Commits
Create multi-file commits and browse commit history via the API.
Create Commit
This is the core endpoint — create a commit with multiple file changes in a single call.
POST /v1/repos/:slug/commits
POST /v1/repos/:namespace/:slug/commits{
"branch": "main",
"message": "Add homepage and config",
"parent_sha": "abc123...",
"author": { "name": "Agent", "email": "agent@example.com" },
"changes": [
{
"path": "index.html",
"content": "<h1>Hello</h1>"
},
{
"path": "config.json",
"content": "{\"version\": 2}"
},
{
"path": "old-file.txt",
"action": "delete"
}
]
}Changes
Each entry in changes describes a file operation.
| Field | Required | Description |
|---|---|---|
path | Yes | File path (no traversal) |
content | No | Full file content (for create/modify) |
encoding | No | utf-8 (default) or base64 |
action | No | "create" (default), "edit", "delete", "rename", or "lazy_edit" |
edits | No | Array of surgical edits (required when action: "edit") |
new_path | No | New file path (required when action: "rename") |
edit_snippet | No | Lazy edit snippet (required when action: "lazy_edit") |
instruction | No | Single-line hint that disambiguates a lazy edit (optional) |
Surgical Edits
When action: "edit", you can make precise changes without sending the entire file. Two modes are supported:
String replacement (like search-and-replace):
{
"path": "src/config.ts",
"action": "edit",
"edits": [
{
"old_string": "const API_URL = \"http://localhost:3000\"",
"new_string": "const API_URL = \"https://api.coregit.dev\""
}
]
}old_string must match exactly one location in the file. Include enough surrounding context to ensure uniqueness. Omit new_string to delete the matched text.
Line range replacement:
{
"path": "src/auth.ts",
"action": "edit",
"edits": [
{
"range": [15, 20],
"content": " const token = verifyJWT(req.headers.authorization);\n if (!token) throw new UnauthorizedError();"
}
]
}range is [startLine, endLine] (1-based, inclusive). Lines in the range are replaced with content.
Both modes in one commit:
{
"changes": [
{ "path": "README.md", "content": "# My App", "action": "create" },
{
"path": "src/config.ts",
"action": "edit",
"edits": [
{ "old_string": "localhost:3000", "new_string": "api.coregit.dev" }
]
},
{ "path": "src/old.ts", "action": "delete" },
{ "path": "src/utils.ts", "action": "rename", "new_path": "src/lib/utils.ts" }
]
}String edits are applied first, then range edits (bottom-to-top to preserve line numbers). Returns 422 if old_string is not found or matches multiple locations.
Lazy Edits
Lazy edits require a paid plan. Free-tier orgs get 402 Payment Required. Billed per output token at $1.32 / 1M tokens — roughly 10% above upstream LLM cost.
action: "lazy_edit" accepts an abbreviated snippet with // ... existing code ... markers and lets Coregit's Fast Apply pipeline merge it into the current file server-side. Your agent produces ~200 tokens instead of rewriting the whole 5 000-token file; Coregit commits the merged full content as a regular blob. One round-trip, atomic with the rest of the commit.
{
"path": "src/auth.ts",
"action": "lazy_edit",
"instruction": "Add user null check before session creation",
"edit_snippet": "// ... existing code ...\n const user = db.find(email);\n if (!user) throw new Error(\"User not found\");\n const session = createSession(user);\n// ... existing code ..."
}Snippet conventions:
- Use language-appropriate comment syntax for markers:
// ... existing code ...(C-family, JS/TS),# ... existing code ...(Python/Ruby),<!-- ... existing code ... -->(HTML/XML). - Keep unchanged spans behind markers — only write the bytes you changed.
- Preserve indentation exactly as it should appear in the final file.
instruction(optional, single line) disambiguates when the snippet could match multiple places (e.g. "Replace the retry logic in the outer loop, not the inner one").
Limits:
edit_snippet≤ 200 KB (~50k tokens input, well under upstream context window)- Max 50
lazy_editchanges per commit (soft cap) - Per-edit timeout 15 s
Error modes:
| Status | Meaning |
|---|---|
402 | Free-tier org — upgrade to use lazy_edit |
404 | File doesn't exist at parent_sha |
502 | Upstream merge failed (retry, no billing on failure) |
503 | lazy_edit not configured on this deployment |
Billing: counted only after the commit succeeds. Failed merges and CAS conflicts cost nothing. Usage appears in /v1/usage as event type lazy_edit_tokens and against the coregit.v2.lazy_edit_tokens meter in billing.
Fields
branch— Target branch namemessage— Commit message (max 50 KB)author—{ name, email }for the commit authorparent_sha— (optional) Expected head SHA for CAS conflict detectionchanges[].encoding—utf-8(default) orbase64for binary files
Limits
- Max 1,000 files per commit
- Max 10 MB per file
List Commits
GET /v1/repos/:slug/commits?ref=main&limit=20
GET /v1/repos/:namespace/:slug/commits?ref=main&limit=20ref(orbranch) — Branch name, tag, or SHA (default: repo's default branch)limit— Max results (default: 20, max: 100)cursor— Commit SHA to resume after (for keyset pagination)
Response 200:
{
"commits": [
{
"sha": "7f3b...",
"message": "Add login page",
"author_name": "Agent",
"author_email": "agent@example.com",
"timestamp": 1704067200,
"parents": ["abc1..."]
}
],
"ref": "main",
"has_more": false,
"next_cursor": null
}Get Commit
GET /v1/repos/:slug/commits/:sha
GET /v1/repos/:namespace/:slug/commits/:shaResponse 200:
{
"sha": "7f3b...",
"message": "Add login page",
"tree": "a1c2...",
"author_name": "Agent",
"author_email": "agent@example.com",
"timestamp": 1704067200,
"parents": ["abc1..."]
}