
Create Origin Commit From Files via the API
Commit inline file changes and advance a branch with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/git/commits:createFromFiles. Official reference: Origin API and changelog (OpenAPI OriginService_CreateCommitFromFiles; added 2026-09-05).
Origin is in Early Beta and subject to change. Authenticate with an installation access token (oit_…) or a user access token that carries repository:contents:write. Availability: Early Beta per the API overview.
targetBranch must currently point at expectedHeadSha, which becomes the new commit's parent. A tip that has moved, a missing branch, an empty diff, a write blocked by a push ruleset, or a write on a repository whose contents are mirrored from another host returns FailedPrecondition. Limits per request: 1,000 file changes, 8 MiB per file, 32 MiB of content in total.
Cost: 10 points against the principal budget (Create Commit From Files).
Path parameters
| Param | Required | Meaning |
|---|---|---|
ownerSlug |
yes | Owning entity's unique slug |
repoName |
yes | Repo name, unique to the owner |
Request body
| Field | Required | Meaning |
|---|---|---|
targetBranch |
yes | Branch as <name>, heads/<name>, or refs/heads/<name>; must already exist |
expectedHeadSha |
yes | Full hex SHA the branch tip must match (becomes the parent) |
message |
yes | Commit message |
author |
yes | { "name", "email" }; timestamps are assigned by the server |
committer |
no | Defaults to author when omitted |
files |
yes | At least one change; paths unique within the request |
Each files[] entry requires path and exactly one of content or delete: true. For content writes: encoding is utf-8 (default) or base64; mode is file (default), executable, or symlink (contents are the link target). delete must be true when set; deleting a missing path fails with FailedPrecondition.
curl --request POST \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/commits:createFromFiles' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"targetBranch": "main",
"expectedHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
"message": "Update changelog and remove stub",
"author": {
"name": "CI Bot",
"email": "ci@acme.dev"
},
"files": [
{
"path": "docs/changelog.md",
"content": "# Changelog\n\n- Ship telemetry\n",
"encoding": "utf-8",
"mode": "file"
},
{
"path": "tmp/stub.txt",
"delete": true
}
]
}'
Response
200 returns sha (new commit, now the branch tip), treeSha (new root tree), and previousHeadSha (prior tip / parent).
{
"sha": "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
"treeSha": "f0e1d2c3b4a5968778695a4b3c2d1e0f9a8b7c6d",
"previousHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"
}
Read the tip first (for example Get Git Commit with the branch name, or List Branches) and send that SHA as expectedHeadSha so concurrent pushes fail cleanly and leave the tip unchanged. Base URL: https://api.cursor.com/v1/origin.