Codetree
GET/repositories/{repo_id}/tree/last-commits
The last commit that touched each file and folder in a directory
list_tree_last_commits
tree:read
A token needs thetree:readscope: Browse repository trees and blobsGranted bymcp_agent,mcp_agent_write,read_api,read_repository,write_api,write_repository.Every operation this scope unlocksCacheable · ref addressed
x-gitmoap-cache: {"kind":"ref_addressed"}
Single-resource
x-gitmoap-isolation: {"kind":"single_or_self_scoped"}
Conditional · 304
Declares304 Not Modified.Redirects · 302
Declares302 Found.
For one page of a directory listing, the newest commit that changed each entry, plus the
directory's own latest commit. Ask with the same ref, path, limit and page as the tree
listing and the two line up entry for entry. History is searched only so far back: an entry it
does not reach has no commit, and truncated says so. An answer cut short by time is never
cached, so asking again can fill it in.
Parameters
Path
- repo_idRepositoryId (string · uuid)Repository ID
Query
- refstringoptionalGit ref (branch, tag, or commit SHA). Default: HEAD
- pathstringoptionalDirectory path within the repo. Default: root
- redirectbooleanoptional
falseanswers with the pinned URL and commit SHA in the body instead of a 302, for clients that cannot follow a redirect. Default: true - limitintegeroptionalEntries per page (max 100). Default: 100. Pass the same value as the tree listing so the two pages line up
- pageintegeroptionalPage number (0-based). Default: 0
Responses
200The last commit for each entry on this page of the directory, in the same order as the tree listing for the same ref, path, limit and pageapplication/json
- has_moreboolean
itemsarray of TreeEntryCommit
- The TreeEntryCommit schema
- namestringThe entry's name within the directory being listed.
- pathstringThe entry's full path from the repository root — the key to join against a tree listing.
- typeTreeEntryTypeblobtree
commitCommitSummary or nulloptionalThe newest commit that changed this file, or anything inside this directory. Absent when the search reached its limit before finding one;
truncatedon the response says so.- The CommitSummary schema
- author_namestringThe author's name as recorded in the commit — a git identity, not a gitmoap account.
- authored_atstringWhen the change was written, ISO 8601.
- committed_atstringWhen the commit was created, ISO 8601. Later than
authored_atafter a rebase or a cherry-pick; this is the time a "last updated" column should show. - shaCommitHash (string)The full commit SHA.
- short_shaShortCommitHash (string)The abbreviated SHA, as git chose to abbreviate it in this repository.
- titlestringThe commit message's first line.
- author_avatar_urlstring or nulloptionalThe author's avatar, when this instance serves avatars.
- author_emailEmail (string) or nulloptionalThe author's email as recorded in the commit. Absent when the commit records something that is not an email address; the commit still has its name and message, only no avatar.
- pageinteger0–∞
- total_countinteger0–∞
- truncatedbooleanThe search reached its limit before every entry had an answer. The entries it did not reach carry no
commit; they have one, it was simply too far back to find in time. A search that ran out of time is answered withCache-Control: no-storeand noETag, so asking again searches again; one that reached its limit on commits read gives the same answer every time. commitCommitSummary or nulloptionalThe newest commit that changed anything in this directory.
- The CommitSummary schema
- author_namestringThe author's name as recorded in the commit — a git identity, not a gitmoap account.
- authored_atstringWhen the change was written, ISO 8601.
- committed_atstringWhen the commit was created, ISO 8601. Later than
authored_atafter a rebase or a cherry-pick; this is the time a "last updated" column should show. - shaCommitHash (string)The full commit SHA.
- short_shaShortCommitHash (string)The abbreviated SHA, as git chose to abbreviate it in this repository.
- titlestringThe commit message's first line.
- author_avatar_urlstring or nulloptionalThe author's avatar, when this instance serves avatars.
- author_emailEmail (string) or nulloptionalThe author's email as recorded in the commit. Absent when the commit records something that is not an email address; the commit still has its name and message, only no avatar.
200 exampleSynthesized example
{
"has_more": false,
"items": [
{
"name": "payments-api",
"path": "path-cdc8",
"type": "blob"
}
],
"page": 29,
"total_count": 2,
"truncated": false,
"commit": {
"author_name": "Lin Park",
"authored_at": "2026-10-13T15:30:28Z",
"committed_at": "2026-10-14T00:22:19Z",
"sha": "f92bf92dbe564a1c1c5ccc719129876aa01f05ad",
"short_sha": "7e138c3726d50241c232f617dda3a8af7f360eca",
"title": "Stream pipeline status into the run header",
"author_avatar_url": "https://gitmoap.example/acme/e669eab7",
"author_email": "mara@acme.example"
}
}
302`ref` names a branch, tag or HEAD: redirect to the same request with `ref` pinned to the commit SHA it resolves to
No body.
304The ref has not moved since the caller's `If-None-Match`
No body.
400Invalid requestapplication/json
Error codes
- BAD_REQUESTThe request is malformed: a parameter or a body field is not a well-formed value of its type
errorErrorBody
- The ErrorBody schema
- codestringThe coarse category, tied to the status:
NOT_FOUND,CONFLICT,INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all. - messagestringWhat went wrong, for a person. Written to be read, not parsed: match on
reasonorcode. - fieldstring or nulloptionalOn a
400that refused one field's value, the field, as its JSON path:email,items[0].name. Put the message under that input. Absent on every other error. - reasonstring or nulloptionalThe specific code, when the error has one:
LAST_ORGANIZATION_OWNER,BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and oncodeotherwise. - required_scopestring or nulloptionalThe scope the access token was missing, on
INSUFFICIENT_SCOPE. - violationsanyoptionalPresent on the structured-validation errors (
PROVIDER_VALIDATION_FAILEDper-node,PIPELINE_VALIDATION_FAILEDDAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
400 exampleSynthesized example
{
"error": {
"code": "code-5634",
"message": "Stream pipeline status into the run header"
}
}
401Unauthenticated — no credential, or an invalid oneapplication/json
Error codes
- UNAUTHORIZEDNo credential was sent, or the one sent is invalid, expired or revoked
errorErrorBody
- The ErrorBody schema
- codestringThe coarse category, tied to the status:
NOT_FOUND,CONFLICT,INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all. - messagestringWhat went wrong, for a person. Written to be read, not parsed: match on
reasonorcode. - fieldstring or nulloptionalOn a
400that refused one field's value, the field, as its JSON path:email,items[0].name. Put the message under that input. Absent on every other error. - reasonstring or nulloptionalThe specific code, when the error has one:
LAST_ORGANIZATION_OWNER,BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and oncodeotherwise. - required_scopestring or nulloptionalThe scope the access token was missing, on
INSUFFICIENT_SCOPE. - violationsanyoptionalPresent on the structured-validation errors (
PROVIDER_VALIDATION_FAILEDper-node,PIPELINE_VALIDATION_FAILEDDAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
401 exampleSynthesized example
{
"error": {
"code": "code-2472",
"message": "Stream pipeline status into the run header"
}
}
403Forbidden — the caller's access level or token scope is insufficientapplication/json
Error codes
- FORBIDDENYou are signed in but may not do this here;
reasonnames the permission or the rule that refused it - INSUFFICIENT_SCOPEThe access token lacks the scope this operation needs;
required_scopenames it - PERMISSION_REQUIREDYou need a permission you do not hold here; the message names it
errorErrorBody
- The ErrorBody schema
- codestringThe coarse category, tied to the status:
NOT_FOUND,CONFLICT,INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all. - messagestringWhat went wrong, for a person. Written to be read, not parsed: match on
reasonorcode. - fieldstring or nulloptionalOn a
400that refused one field's value, the field, as its JSON path:email,items[0].name. Put the message under that input. Absent on every other error. - reasonstring or nulloptionalThe specific code, when the error has one:
LAST_ORGANIZATION_OWNER,BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and oncodeotherwise. - required_scopestring or nulloptionalThe scope the access token was missing, on
INSUFFICIENT_SCOPE. - violationsanyoptionalPresent on the structured-validation errors (
PROVIDER_VALIDATION_FAILEDper-node,PIPELINE_VALIDATION_FAILEDDAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
403 exampleSynthesized example
{
"error": {
"code": "code-0d8f",
"message": "Pin a page's payload to the build that rendered it"
}
}
404Repository or directory not foundapplication/json
Error codes
- NOT_FOUNDThe resource does not exist — or exists and you cannot see it: a private resource you have no access to answers exactly as an absent one does
errorErrorBody
- The ErrorBody schema
- codestringThe coarse category, tied to the status:
NOT_FOUND,CONFLICT,INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all. - messagestringWhat went wrong, for a person. Written to be read, not parsed: match on
reasonorcode. - fieldstring or nulloptionalOn a
400that refused one field's value, the field, as its JSON path:email,items[0].name. Put the message under that input. Absent on every other error. - reasonstring or nulloptionalThe specific code, when the error has one:
LAST_ORGANIZATION_OWNER,BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and oncodeotherwise. - required_scopestring or nulloptionalThe scope the access token was missing, on
INSUFFICIENT_SCOPE. - violationsanyoptionalPresent on the structured-validation errors (
PROVIDER_VALIDATION_FAILEDper-node,PIPELINE_VALIDATION_FAILEDDAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
404 exampleSynthesized example
{
"error": {
"code": "code-d660",
"message": "Inline scalar newtypes but keep their brand"
}
}
409The repository is empty: nothing has been pushed to it, so there is no history to searchapplication/json
Error codes
- CONFLICTThe request conflicts with the resource's current state;
reasonsays how - REPOSITORY_EMPTYThe repository has no branches or tags yet; there is nothing to read until something is pushed to it
errorErrorBody
- The ErrorBody schema
- codestringThe coarse category, tied to the status:
NOT_FOUND,CONFLICT,INSUFFICIENT_SCOPE. Every error has one; the API reference's error catalogue lists them all. - messagestringWhat went wrong, for a person. Written to be read, not parsed: match on
reasonorcode. - fieldstring or nulloptionalOn a
400that refused one field's value, the field, as its JSON path:email,items[0].name. Put the message under that input. Absent on every other error. - reasonstring or nulloptionalThe specific code, when the error has one:
LAST_ORGANIZATION_OWNER,BRANCH_PROTECTED. The message starts with it too. Match on this when it is present, and oncodeotherwise. - required_scopestring or nulloptionalThe scope the access token was missing, on
INSUFFICIENT_SCOPE. - violationsanyoptionalPresent on the structured-validation errors (
PROVIDER_VALIDATION_FAILEDper-node,PIPELINE_VALIDATION_FAILEDDAG): a JSON array of the offending elements, so a caller can fix every one in a single round-trip. Absent (omitted) on every other error.
409 exampleSynthesized example
{
"error": {
"code": "code-a780",
"message": "Inline scalar newtypes but keep their brand"
}
}
CLI
gitmoap tree list-tree-last-commits
- --repo-ididRepository ID (id or owner/repo path)
- --limitnumberoptionalEntries per page (max 100). Default: 100. Pass the same value as the tree listing so the two pages line up
- --pagenumberoptionalPage number (0-based). Default: 0
- --pathstringoptionalDirectory path within the repo. Default: root
- --redirectflagoptional`false` answers with the pinned URL and commit SHA in the body instead of a 302, for clients that cannot follow a redirect. Default: true
- --refstringoptionalGit ref (branch, tag, or commit SHA). Default: HEAD