API / batch-upsert-origin-check-runs-via-api

API

Batch Upsert Origin Check Runs via the API

Atomically upsert several check runs that share one suite with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/check-runs:batchUpsert. Official reference: Origin API → Checks / Batch Upsert Check Runs (OpenAPI OriginService_BatchUpsertCheckRuns).

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 request accepts 1–10 runs under one checkSuite and rejects duplicate (externalId, key) identities. Every run commits or the entire request rolls back. Keep suite and run key values stable and readable (required checks match on app + suite key, optionally run key; name is display-only). Reuse externalId to update an attempt; use a new externalId for a retry so the earlier attempt stays as history. externalUpdatedAt orders updates so stale retries cannot overwrite newer state. Do not send status: rerequested — only Origin sets that; a request carrying it returns InvalidArgument (HTTP 400).

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 Shared suite input (key, name, externalId; optional detailsUrl)
checkRuns yes Array of 1–10 CheckRunInput entries with unique (externalId, key)

Each run needs key, name, status (queued / in_progress / completed), externalUpdatedAt, and externalId. When status is completed, supply conclusion. Optional fields match single-run upsert: startedAt, completedAt, detailsUrl, output, deadlineAt, isRerequestable.

curl --request POST \
  --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs:batchUpsert' \
  --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"
  },
  "checkRuns": [
    {
      "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 checkRuns in request order, including server-assigned crg_… / cr_… ids, repository references, timestamps, and actors.

Example shape from the OpenAPI:

{
  "checkSuite": {
    "id": "crg_01k2ja2000e0080000000000h8",
    "repository": {
      "id": "repo_01k2ja2000e0080000000000q4",
      "name": "rocket",
      "owner": {
        "slug": "acme",
        "id": "ns_01k2ja2000e0080000000000p3",
        "type": "team"
      }
    },
    "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
    "key": "ci-8842",
    "name": "CI",
    "detailsUrl": "https://ci.acme.dev/runs/8842",
    "createdAt": "2026-08-01T09:30:00Z",
    "updatedAt": "2026-08-02T14:45:00Z",
    "externalId": "build-8842",
    "actor": {
      "user": {
        "id": "user_01k2ja2000e0080000000000c3",
        "email": "jane@acme.dev"
      }
    }
  },
  "checkRuns": [
    {
      "id": "cr_01k2ja2000e0080000000000g7",
      "checkSuite": {
        "id": "crg_01k2ja2000e0080000000000h8"
      },
      "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4",
      "key": "ci-8842-unit-tests",
      "name": "unit-tests",
      "status": "completed",
      "conclusion": "success",
      "externalId": "run-8842"
    }
  ]
}

Prefer batch upsert when one CI job finishes several checks together; use single-run upsert when jobs complete on different schedules.

Base URL: https://api.cursor.com/v1/origin.