Run lifecycle
A run executes a Kit against one conversation input. The default behavior is async: POST /v1/runs returns 202 with a run_id, then your client polls GET /v1/runs/{runId} until the run reaches a terminal state.
| Status | Meaning | Client action |
|---|---|---|
| queued | Accepted and waiting for execution. | Poll again after the advised delay. |
| running | Execution has started. | Keep polling with backoff. |
| succeeded | Output is ready under output.bricks. | Read, validate, and persist the structured output. |
| failed | Execution ended with an error. | Read error_code, error_message, and error_user_message when present. |
| cancelled | Execution did not continue. | Treat as terminal and decide whether a new run is appropriate. |
Create an async run
Send conversation input plus a Kit identifier. Use kit_code for stable published Kit calls or kit_version_id when the integration must target a specific Kit version.
curl -X POST https://api.semarize.com/v1/runs \
-H "Authorization: Bearer smz_live_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: call-123-kit-A1B2C3D4" \
-d '{
"kit_code": "A1B2C3D4",
"mode": "async",
"input": {
"transcript": "Rep: What drove the urgency? Prospect: ..."
}
}'Polling pattern
Poll conservatively. Start with the Retry-After header when present, then use bounded exponential backoff. Avoid tight loops because run execution depends on model, Kit, and input size.
async function waitForRun(runId, apiKey) {
let delayMs = 1000;
while (true) {
const response = await fetch(`https://api.semarize.com/v1/runs/${runId}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (response.status === 429) {
const retryAfter = Number(response.headers.get("Retry-After") || "5");
await sleep(retryAfter * 1000);
continue;
}
const run = await response.json();
if (run.status === "succeeded") return run.output;
if (run.status === "failed" || run.status === "cancelled") throw new Error(run.error_message || run.status);
await sleep(delayMs);
delayMs = Math.min(delayMs * 2, 10000);
}
}Sync mode fallback
mode: sync asks Semarize to wait for completion within the request cycle. A 200 response means the request cycle completed and the run detail is returned. Inspect the run status in the body to decide whether the run succeeded.
If the run does not complete in time, Semarize can return 202 with sync_fallback: true and waited_ms. Continue with the normal async polling flow using the returned run_id.
Webhooks
For push delivery, configure a workspace webhook. Semarize sends terminal events such as run.succeeded, run.failed, and run.cancelled. Webhook payload data uses the same public run detail boundary as GET /v1/runs/{runId}.
- Verify Semarize-Signature before trusting a webhook payload.
- Dedupe on Semarize-Delivery-Id or Semarize-Event-Id.
- If a thin event omits output, fetch GET /v1/runs/{runId} before updating downstream systems.
Related guides
Idempotency
Use Idempotency-Key so retrying run creation does not create duplicate work.
Errors
Map HTTP status codes, flat error envelopes, and terminal run failure fields.
Rate limits
Respect Retry-After, slow polling loops, and build controlled batch workers.
Versioning
Understand /v1 stability, additive changes, and Kit version pinning.
Status
Use status signals, incident retry behavior, and escalation details in production.