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 (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, image/webp, image/heic, image/heif, image/svg+xml, application/pdf, text/markdown, text/plain, text/csv, application/json. Office formats are 400. The worker converts exotic images and PDFs to PNG (and inlines text docs) before the design agent runs. Brand colors and fonts may also go 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 }