Runs API
Start, poll, notify, cancel, and delete generative runs on a NexDoc Design job, including viewer URLs.
Scopes: runs:rw / runs:read
A run is one generation on a job. The first run creates the design; later runs on the same job_id are edits. Persist job_id and run_id as soon as this endpoint returns — before polling or requesting email. Never start a second job for the same design.
Typical wait: 1–5 minutes for a simple card or short landing page; 10–20 minutes (sometimes longer) for decks, reports, and image-heavy work. A long wait is not a hang.
POST/v1/jobs/{job_id}/runs
Accepts JSON or multipart. Returns 202.
JSON body
| Field | Type | Notes |
|---|---|---|
format | string | Format slug. Always send it. |
instructions | string | Design brief (create) or edit diff (update) |
content | string | Source copy, markdown. "" on updates that keep copy |
files | string[] | file_… ids to place in the workspace |
assets | [{name, file_id}] | Map a filename under assets/ to a file id |
webhook_url | string | Accepted and stored; completion delivery is not guaranteed — prefer notify_email or poll |
notify_email | bool | Email the account owner when the run finishes (completed / failed / cancelled) |
{
"format": "landing-page",
"instructions": "Dark editorial landing page",
"content": "# Acme\n...",
"files": ["file_..."],
"assets": [{"name": "logo.png", "file_id": "file_..."}],
"notify_email": false,
"webhook_url": null
}Multipart fields
format, instructions, content (text or file part), repeated files (png/jpg/gif/pdf, stored immediately), optional file_ids (JSON array text), assets (JSON array text), webhook_url, notify_email.
Allowed files types: image/png, image/jpeg, image/gif, application/pdf. Anything else (svg, webp, json, brand-kit.json) is 400. Put brand colors and fonts in instructions.
Markdown image references whose basename matches an uploaded filename are rewritten to assets/<filename>.
Response
{
"job_id": "job_...",
"run_id": "run_...",
"status": "queued",
"notify_email": false,
"created_at": "..."
}402 cannot start (no balance / past due) · 404 job or file · 503 enqueue failed (retry once after 10 seconds).
Wait for completion
Polling — GET the run every few seconds until completed, failed, or cancelled.
Email — set notify_email: true on create, or call POST …/notify-email after the run has started. NexDoc emails the account address on the API key. Do not block on webhook_url.
GET/v1/jobs/{job_id}/runs
Oldest first.
{
"job_id": "job_...",
"data": [
{
"run_id": "run_...",
"status": "completed",
"commit_hash": "...",
"charge_usd": 0.16,
"created_at": "...",
"completed_at": "..."
}
]
}GET/v1/jobs/{job_id}/runs/{run_id}
status, charge_usd, commit_hash, summary_diff, created_at, completed_at, notify_email. On completed: viewer_url, viewer_expires_at. On failed: error, log_tail.
Status values: queued, preparing, running, validating, uploading_outputs, completed, failed, cancelled, cancelling.
POST/v1/jobs/{job_id}/runs/{run_id}/notify-email
Request an email when an in-progress run finishes.
- In progress →
{ "notify_email": true } - Already terminal → 200 plus
warning; no email is sent. Fetch the run and reportstatus/viewer_url/error.
POST/v1/jobs/{job_id}/runs/{run_id}/cancel
{ "status": "cancelling" }409 if already terminal.
DELETE/v1/jobs/{job_id}/runs/{run_id}
Soft-delete.
{ "job_id": "job_...", "run_id": "run_...", "deleted": true }