Async Jobs
The sync endpoint (POST /v1/chat) waits for the AI to finish before responding. For long operations or background processing, use the async endpoint instead.
When to use async
Async flow
1. Start the job
job_id is an opaque UUID — treat it as a string, don’t parse it. Chat jobs and attachment-processing jobs share the same id space and the same GET /v1/jobs/{job_id} path.
2. Poll for status
3. Get the result
Whenstatus is "completed", the result field contains the AI response and document changes:
Job statuses
Revert vs. in-flight jobs. Revert returns
409 while a chat job on the same session is in pending, in_progress, or awaiting_approval. Wait for the job to land in completed/failed/cancelled, or cancel it explicitly via POST /v1/jobs/{job_id}/cancel, before retrying revert.Continuing a large edit
A very large edit can be too big to finish in a single turn. When that happens the AI applies as much as it can, keeps that work, and pauses withstatus: "awaiting_approval" and metadata.awaiting_kind: "continue_prompt" — asking whether to continue with the rest. This is distinct from HITL change review (which instead sets metadata.pending_changes) and can occur in either approval mode.
The pause carries a metadata.continue_prompt object:
/continue:
continue: true— resume; the job returns toin_progressand finishes the rest.continue: false— stop here; everything applied so far is kept.
continue_prompt in your polling loop just like repeated HITL rounds — keep going until status is completed. If you never respond, the job is cleaned up after 1 hour, like any other awaiting_approval job.
Latency expectations and timeout strategy
Knowing how long an operation should take helps you decide when to surface a “still processing” hint and when to treat a job as broken.Typical latency by operation type
These are medians for typical documents (5–20 sections). Larger documents, embedded images, or operations using
model_tier: "max" with thinking_depth: "deep" may exceed these ranges. The model_tier and thinking_depth you choose materially affect latency — see Model Selection. The server enforces a hard 30-minute wall-clock cap on every chat turn (sync and async); requests that exceed it return a graceful 504 with a suggestion to split the work across smaller turns.
Polling strategy that surfaces progress
intermediate event to the user — see Streaming → Rendering intermediate events.
Job retention
All jobs — pending, in-progress, awaiting-approval, or terminal — are automatically removed 1 hour after creation. For user-facing workflows that may run longer (or where the user steps away), keepMAX_WAIT well under 1 hour and persist the job_id so you can resume polling later.
Job types
Thejob_type field on every job row tells you which lifecycle to expect.
large_export jobs are fire-and-forget — the recipient receives an email when the render finishes, so polling is optional. Use it when you want to surface progress in your UI rather than letting the user check their inbox.
Cancel a job
Onlypending and in_progress jobs can be cancelled:
List all jobs
Polling example
Jobs are automatically cleaned up 1 hour after completion, failure, or cancellation. Jobs in
awaiting_approval status are also cleaned up after 1 hour — approve or deny changes within this window.
