Status
succeeded is the important difference from v2. A v2 run could report
completed while cells were still filling in. A v3 Job stays running through
enrichment, so when it succeeds the numbers are final and you can act on them
immediately.
Polling
PollGET /jobs/{job_id} while status is queued
or running. Every running response carries next_poll_at and a Retry-After
header. Honor them: polling faster does not finish the Job sooner, because those
reads are served from a short-lived cache. See the
quickstart for a poll loop you can copy.
Lost a Job id? List them:
metadata when you admit the Job so you can correlate the list (and the
webhook) back to your own run id.
Webhooks
Subscribe to thejob.* group instead of polling:
Payloads carry a compact summary (counts and resource ids), your
metadata,
and credits. They never include row-level data or row_ids — fetch those
with GET /jobs/{job_id}. See the
Job event reference.
sequence on the payload is a monotonic generation. At-least-once retries can
arrive out of order — ignore any event whose sequence is not greater than the
last one you processed for that job_id.
Credits
credits.spent is this Job’s spend alone. settled: false on a
quality: "accurate" run means the number can still adjust down after
delivered-lead settlement. Reconcile billing after settled: true.
credits is null on operations that spend nothing.
needs_input
Whenstatus is needs_input, needs_input is one of:
questions— answer withPOST /jobs/{job_id}/input{ "answers": ["..."] }. The same Job id resumes.handoff— a human step (for example Stripe SCA). Send the user the URL. Origami resumes the Job itself after the in-app step completes.
Cancel
POST /jobs/{job_id}/cancel is cooperative. A
successful call sets cancel_requested: true and returns the current snapshot.
Repeating cancel on an already-flagged Job is an idempotent 200. A Job that
cannot be cancelled returns 409 JOB_NOT_CANCELLABLE.
Partial work is kept. Credits already spent are not refunded.
Retryable agent failures
Failed AGENT Jobs keep a retry signal onerror.code:
Retryable means re-running the same call on the same resources is reasonable.
Don’t create a fresh list and pay for the lookups twice.
Where Jobs come from
Everything else in v3 is synchronous — it either succeeds or errors on the spot.