Codecommits
POST/repositories/{repo_id}/commits
Commit file changes to a branch
create_commit
commit:create
A token needs thecommit:createscope: Write commits from file changes, and resolve merge-request conflictsGranted bywrite_api,write_repository.Every operation this scope unlocksAudited · mutation
x-gitmoap-audit: {"kind":"audited","arg":"mutation"}
Quota · namespace storage
x-gitmoap-quota: {"kind":"enforced","arg":"namespace_storage"}
Dry run
Takesdry_run.
One commit from a list of file changes — create, update, delete, move, change the mode — landed
through the same branch rules and push rules as a git push. Every change to an existing file
names the blob it was made against, so a file changed by someone else meanwhile is refused
rather than overwritten. dry_run=true answers what the commit would do and writes nothing.
Parameters
Path
- repo_idRepositoryId (string · uuid)Repository ID
Query
- dry_runbooleanoptionalSay what the commit would do — every refusal, the files that changed since they were read, the pipelines it would start — and write nothing
Request body
application/json- branchBranchName (string)The branch the commit lands on.
- messageCommitMessage (string)The commit message, taken as written — trailers such as
Signed-off-byincluded. - expected_head_shaCommitHash (string) or nulloptionalThe head the commit must land on. Omitted, the commit lands on the branch's current head as long as every file it changes is still the one the caller edited.
- start_branchBranchName (string) or nulloptionalCreate
branchfrom this branch's head and land the commit on it, in one step.branchmust not exist yet.
Request body exampleSynthesized example
{
"actions": [
{
"action": "create",
"content": "content-c7e2",
"path": "path-f5d1"
}
],
"branch": "feat/run-header-stream",
"message": "Inline scalar newtypes but keep their brand"
}
Responses
200A preview: what the commit would do. Nothing was writtenapplication/json
- allowedbooleanWhether the commit, sent as it is, would land.
authorCommitAuthor
- The CommitAuthor schema
- emailEmail (string)
- namestring
- branch_existsbooleanWhether
branchexists. Withstart_branch,falsemeans it will be created. pipelinesarray of PredictedPipelineThe pipelines this commit would start, as the branch's push triggers stand now.
- The PredictedPipeline schema
- namestring
- pipeline_idPipelineId (string · uuid) or nulloptionalThe pipeline, when it is one stored in the platform. A pipeline declared in a file under
.gitmoap/pipelines/has no id and is named by its file.
refusalsarray of RefusalEvery reason the commit would be refused, each on the field it is about.
- The Refusal schema
- codeRefusalCodePERMISSION_REQUIREDBRANCH_PROTECTEDAGENT_REFFOREIGN_AUTHORPRIVILEGED_PATHBRANCH_NOT_FOUNDSTART_BRANCH_NOT_FOUNDFILE_NOT_FOUNDREPOSITORY_EMPTYMR_NOT_OPENNOT_CONFLICTEDHEAD_MOVEDBRANCH_EXISTSFILE_CHANGEDFILE_EXISTSPATH_CONFLICTUNSUPPORTED_ENTRYNOTHING_TO_COMMITUNRESOLVEDNOT_IN_CONFLICTUNSUPPORTED_CONFLICTPUSH_RULE_VIOLATIONWhat kind of refusal this is. Closed: a client branches on it. The wire spelling is the
SCREAMING_SNAKEdomain code that leads an error's message, so a refusal returned as data and the same refusal returned as an error read the same. - messagestringWhat is wrong, in a sentence a person can act on.
- fieldstring or nulloptionalThe part of the request the refusal is about:
message,branch, oractions[i]for the i-th file change. - rulestring or nulloptionalThe push rule that refused, by its setting's name (
require_issue_reference), whencodeisPUSH_RULE_VIOLATION.
stalearray of StaleFileThe files that changed since the caller read them.
- The StaleFile schema
- pathstring
- current_blob_shaObjectId (string) or nulloptionalThe blob at the branch's head now. Absent when the file has been deleted.
last_commitCommitSummary or nulloptionalThe commit that last changed the file, when it was found in time.
- 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.
- head_shaCommitHash (string) or nulloptionalThe head the commit would land on; absent for a repository's first commit.
200 exampleSynthesized example
{
"allowed": false,
"author": {
"email": "tomas@acme.example",
"name": "payments-api"
},
"branch_exists": false,
"pipelines": [
{
"name": "payments-api"
},
{
"name": "payments-api"
}
],
"refusals": [
{
"code": "PERMISSION_REQUIRED",
"message": "Label every synthesized example"
},
{
"code": "PERMISSION_REQUIRED",
"message": "Pin a page's payload to the build that rendered it"
}
],
"stale": [
{
"path": "path-d878"
}
],
"head_sha": "937a776bb9c236ba847bdf0cd91b8799374fd488"
}
201The commit landedapplication/json
branchRepositoryBranch
- The RepositoryBranch schema
- aheadinteger · int320–∞
- behindinteger · int320–∞
- branch_nameBranchName (string)
commitCommit
- The Commit schema
- author_emailEmail (string)
- author_namestring
- authored_atstring
- commit_shaCommitHash (string)
- committed_atstring
- committer_emailEmail (string)
- committer_namestring
- repository_idRepositoryId (string · uuid)
- short_shaShortCommitHash (string)
- titlestring
- author_avatar_urlstring or nulloptional
- committer_avatar_urlstring or nulloptional
- messagestring or nulloptional
- parent_shasarray of CommitHash (string)optional
- tagsarray of TagName (string)optional
open_merge_requestsarray of BranchMergeRequestRefThe open merge requests proposing this branch — one per target branch at most. A commit to the branch updates each of them.
- The BranchMergeRequestRef schema
- iidMergeRequestId (integer · int64)The merge request's number in its repository.
- target_branchBranchName (string)Where it proposes to merge the branch.
- protectedbooleanA branch rule protects this branch.
- repository_idRepositoryId (string · uuid)
- viewer_can_pushbooleanWhether the caller may push to this branch — the same verdict a
git pushor a commit written in the browser gets.falsefor someone not signed in. - push_refusalstring or nulloptionalWhy the caller may not push here, in a sentence to show them. Absent when they may.
- branch_createdbooleanThe commit created
branch(fromstart_branch, or as a repository's first commit). commitCommit
- The Commit schema
- author_emailEmail (string)
- author_namestring
- authored_atstring
- commit_shaCommitHash (string)
- committed_atstring
- committer_emailEmail (string)
- committer_namestring
- repository_idRepositoryId (string · uuid)
- short_shaShortCommitHash (string)
- titlestring
- author_avatar_urlstring or nulloptional
- committer_avatar_urlstring or nulloptional
- messagestring or nulloptional
- parent_shasarray of CommitHash (string)optional
- tagsarray of TagName (string)optional
201 exampleSynthesized example
{
"branch": {
"ahead": 5,
"behind": 6,
"branch_name": "refactor/brand-inline",
"commit": {
"author_email": "tomas@acme.example",
"author_name": "Tomás Reyes",
"authored_at": "2026-10-15T15:39:00Z",
"commit_sha": "94f4bacc0c6f0b99d779324910036817bc42d2f5",
"committed_at": "2026-10-13T17:30:12Z",
"committer_email": "tomas@acme.example",
"committer_name": "payments-api",
"repository_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"short_sha": "340876a61e3410af1cbccbcb14c1b4a64d7a827d",
"title": "Pin a page's payload to the build that rendered it",
"author_avatar_url": "https://gitmoap.example/acme/1443d9eb",
"committer_avatar_url": "https://gitmoap.example/acme/22da5cf2",
"message": "Stream pipeline status into the run header",
"parent_shas": [
"beec518cbb2238afcbc15c751ce053d981ab2b9b",
"b1cfdb61a0f3d31b93ca3159da63199430641fa4"
],
"tags": [
"tags-0e81",
"tags-a2b3"
]
},
"open_merge_requests": [
{
"iid": 42,
"target_branch": "main"
}
],
"protected": false,
"repository_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"viewer_can_push": false,
"push_refusal": "push-refusal-7011"
},
"branch_created": false,
"commit": {
"author_email": "mara@acme.example",
"author_name": "Tomás Reyes",
"authored_at": "2026-10-11T19:59:21Z",
"commit_sha": "23ff0453958a83b8695591c8dfa32f7d657c1351",
"committed_at": "2026-10-11T18:27:10Z",
"committer_email": "lin@acme.example",
"committer_name": "payments-api",
"repository_id": "5b0e7c2a-9d14-4e8b-a6f1-2c3d4e5f6a70",
"short_sha": "c49cc49e571f1b247ed9a6d69d73e9fb21923257",
"title": "Stream pipeline status into the run header",
"author_avatar_url": "https://gitmoap.example/acme/3c668683",
"committer_avatar_url": "https://gitmoap.example/acme/ba9cdba6",
"message": "Inline scalar newtypes but keep their brand",
"parent_shas": [
"64e80150bf3454cd202cee3fd4bf1ea34014702a",
"663591f99ab56bb32f587a08f924eef7f2cb159f"
],
"tags": [
"tags-9fdd"
]
}
}
400Malformed request: an invalid path, a path changed twice, more than 100 changes, content that is not valid base64application/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-4ca7",
"message": "Draw the region map from operation density"
}
}
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-960e",
"message": "Inline scalar newtypes but keep their brand"
}
}
403The caller may not push to this repository, or a branch rule protects the branchapplication/json
Error codes
- BRANCH_PROTECTEDA branch rule keeps you from changing this branch this way
- 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-f94d",
"message": "Pin a page's payload to the build that rendered it"
}
}
404Repository not found, or the branch, the start branch or a file the commit changes does not existapplication/json
Error codes
- BRANCH_NOT_FOUNDThe branch does not exist, and nothing asked for it to be created
- FILE_NOT_FOUNDA file the change updates, moves or deletes is not there
- 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
- START_BRANCH_NOT_FOUNDThe branch a new branch was to start from does not exist
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-c20e",
"message": "Label every synthesized example"
}
}
409A file changed since it was read, already exists or collides with a directory; the branch moved or already exists; or the repository is empty and the branch is not its defaultapplication/json
Error codes
- BRANCH_EXISTSA branch with that name already exists
- CONFLICTThe request conflicts with the resource's current state;
reasonsays how - FILE_CHANGEDA file the change edits is no longer the version you read
- FILE_EXISTSA file the change creates already exists
- HEAD_MOVEDThe branch moved since you read it; read it again and retry
- LEGAL_ACCEPTANCE_REQUIREDAccept the current Terms of Service before changing anything; reading stays open
- PATH_CONFLICTA path collides with the tree: a file where a directory is, or beneath a file
- 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-24a6",
"message": "Stream pipeline status into the run header"
}
}
413The request is larger than 16 MiBapplication/json
Error codes
- PAYLOAD_TOO_LARGEThe request body is larger than this operation accepts
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.
413 exampleSynthesized example
{
"error": {
"code": "code-235f",
"message": "Inline scalar newtypes but keep their brand"
}
}
422A push rule refuses the commit, a change targets a symbolic link, a submodule or a directory, or nothing would changeapplication/json
Error codes
- NOTHING_TO_COMMITThe change leaves every file as it was
- PUSH_RULE_VIOLATIONA push rule refuses the change;
rulenames it - UNPROCESSABLE_ENTITYThe request is well-formed but asks for something the resource's rules do not allow;
reasonsays which - UNSUPPORTED_ENTRYThe entry is a symbolic link, a submodule or a directory, which a commit written in the browser does not change
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.
422 exampleSynthesized example
{
"error": {
"code": "code-9f2f",
"message": "Inline scalar newtypes but keep their brand"
}
}
429The commit would take the namespace over its storage limit, or exceeds the per-push sizeapplication/json
Error codes
- TOO_MANY_REQUESTSRetryableA quota, a rate limit or a transfer budget is spent. When the response carries
Retry-After, retry after that many seconds
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.
429 exampleSynthesized example
{
"error": {
"code": "code-7a94",
"message": "Label every synthesized example"
}
}
CLI
gitmoap commits create
- --repo-ididRepository ID (id or owner/repo path)
- --dry-runflagoptionalSay what the commit would do — every refusal, the files that changed since they were read, the pipelines it would start — and write nothing
- --actionsjsonThe file changes, at most 100, each path touched once.
- --branchstringThe branch the commit lands on.
- --expected-head-shastringoptional
- --messagestringThe commit message, taken as written — trailers such as `Signed-off-by` included.
- --start-branchstringoptional