Sign in

API reference

Start a run

POST/v1/runs

Scope: runs:write

Starts a run on a tracker issue. The issue picks the project, and the key must be allowed on it. Like a run started by hand in the portal, it starts as soon as there’s a slot, and doesn’t wait for anyone to approve it.

curl --fail-with-body -sS https://<workspace>.nightlab.io/v1/runs \
  -H "Authorization: Bearer $NIGHTLAB_API_KEY" \
  -H "Idempotency-Key: ci-8812-build" \
  -H "Content-Type: application/json" \
  -d '{"issue": "SHOP-1431", "external_ref": "ci-8812"}'

Body

  • issuestringRequired

    The tracker key, like SHOP-1431. It picks the project: there’s no project field.

  • action"build" or "improve", default "build"

    build writes the change and opens a draft pull request once your checks pass. improve only scopes the issue: it reads the issue and the code, and posts what done means back on the issue, writing no code.

  • check_duplicatesboolean, default false

    With build, first check the change isn’t already in the code.

  • dry_runboolean, default false

    Read the git host and the tracker, and write to neither: no branch, pull request or comment. While the workspace’s writes are off, every run is a dry run.

  • external_refstring, up to 200

    Your own id, like the CI job’s. It comes back on the run and on every event about it, and GET /v1/runs?external_ref= finds the run by it.

  • repostring

    Only when the issue’s project has several repositories and you need one: its name, as List projects gives it.

Idempotency

Send an Idempotency-Key header, up to 255 characters. For 24 hours, a retry with the same key and the same body gets the first answer back, marked Idempotent-Replayed: true, and starts nothing. The same key with another body is refused with 422, and while the first request is still being answered, with 409. Keys are per API key: a rotated key starts afresh. A refused start keeps nothing, so retrying it runs anew.

The answer

201 with the run, in state queued. Keep its id to read it, or match its external_ref on the events.

201 Created

{
  "id": "run-42",
  "project": "shop",
  "issue": "SHOP-1431",
  "action": "build",
  "state": "queued",
  "outcome": null,
  "no_pr_reason": null,
  "pr_url": null,
  "pr_state": null,
  "external_ref": "ci-8812",
  "summary": null,
  "created_at": "2026-11-01T10:00:00Z",
  "updated_at": "2026-11-01T10:00:00Z",
  "finished_at": null,
  "links": {
    "api": "/v1/runs/run-42",
    "portal": "https://app.nightlab.io/runs/run-42"
  }
}

Refusals

Each is application/problem+json, with a sentence saying what to change.

StatusWhen
402The budget is used up, until it renews or an admin raises it.
403The key lacks runs:write, the issue’s project isn’t one of the key’s, the call came from outside its allow-list, or the workspace isn’t active.
409Setup isn’t finished, the project has no repository nightlab can reach, the issue’s key is on more than one tracker site, the issue already has a run in progress (the answer names it), or the same Idempotency-Key is still being answered.
422A field is wrong (errors lists each), repo isn’t one of the issue’s project’s, or the Idempotency-Key was used with another body.
429The key’s rate limit, with Retry-After; or no run slot is free, in the workspace or on nightlab.