
Upsert an Origin Check Run via the API
Report CI status on a commit by upserting a check suite and check run together with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/check-runs. Official reference: Origin API → Checks / Post Check Run.
Origin is in Early Beta and subject to change. Authenticate with an installation access token (oit_…) that carries repository:checks:write. The write is attributed to the app that owns the authenticated installation. Availability: Early Beta per the API overview.
The first run upsert creates its suite automatically. A repeated call with the same (repo, head_sha, suite.key, check.key) updates the existing check run in place rather than creating a duplicate. externalUpdatedAt orders updates so a stale retry cannot overwrite newer state.
Keep key values stable and readable: required checks match the installing app plus the suite key, and optionally a run key. name is display-only and is not used for matching. Reuse externalId to update an attempt (which discards that attempt's previous result); use a new externalId for a retry so the earlier attempt stays as history.
Cost: 5 points against the principal budget (ordinary write).
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 |
|---|---|---|
headSha |
yes | Head commit SHA (40- or 64-char hex) |
checkSuite |
yes | Suite upserted alongside the run |
checkSuite.key |
yes | Stable app-chosen suite identity across attempts |
checkSuite.name |
yes | Human-facing suite name |
checkSuite.externalId |
yes | Provider-assigned immutable identity for this suite attempt |
checkSuite.detailsUrl |
no | Optional link to suite-level detail |
checkRun |
yes | Check run to upsert |
checkRun.key |
yes | Stable app-chosen run identity across attempts |
checkRun.name |
yes | Human-facing run name |
checkRun.status |
yes | queued, in_progress, or completed (do not send rerequested; Origin sets that on re-request) |
checkRun.conclusion |
when completed | success, failure, neutral, cancelled, skipped, timed_out, action_required, or stale |
checkRun.externalUpdatedAt |
yes | External last-update time (RFC 3339); orders concurrent updates |
checkRun.externalId |
yes | Provider-assigned immutable identity for this run attempt |
checkRun.startedAt / completedAt |
no | Provider-reported start and end times |
checkRun.detailsUrl |
no | Link to the provider's job or build page |
checkRun.output.title |
no | Short headline (max 255 characters) |
checkRun.output.summary |
no | Markdown summary (max 65,535 UTF-8 bytes) |
checkRun.output.text |
no | Extended Markdown details (max 65,535 UTF-8 bytes) |
checkRun.deadlineAt |
no | Optional deadline (RFC 3339). More than 24 hours ahead returns InvalidArgument (HTTP 400). When an in_progress run passes its deadline, Origin completes it with timed_out. |
checkRun.isRerequestable |
no | When true, commit to answering repository.check_run.rerequested by posting a fresh run for the same head SHA and key. |
curl --request POST \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
"checkSuite": {
"key": "ci-8842",
"name": "CI",
"detailsUrl": "https://ci.acme.dev/runs/8842",
"externalId": "build-8842"
},
"checkRun": {
"key": "ci-8842-unit-tests",
"name": "unit-tests",
"status": "completed",
"conclusion": "success",
"externalUpdatedAt": "2026-08-02T14:44:30Z",
"startedAt": "2026-08-02T14:40:00Z",
"completedAt": "2026-08-02T14:44:30Z",
"detailsUrl": "https://ci.acme.dev/runs/8842",
"externalId": "run-8842",
"output": {
"title": "Unit tests",
"summary": "128 tests passed.",
"text": "All suites green."
}
}
}'
Response
The body returns the upserted checkSuite and checkRun, including server-assigned ids (crg_… for suites, cr_… for runs), repository references, SHA, keys, status, conclusion, timestamps, actor, and output when supplied.
Mirrored repositories reject check writes until the mirror is a stable outbound mirror. Use an installation token, not an app JWT, for this endpoint.
Base URL: https://api.cursor.com/v1/origin.