Every extraction is a job. Creating one returns instantly with the job already in pending; the model runs in a queue behind the scenes. You get the result by receiving a webhook (recommended) or by polling the job. This design means a slow or large document never blocks your request, and nothing is silently dropped — a job always ends in completed or failed.
Lifecycle
POST /jobs/create returns the full job object — the same shape as [GET /jobs/:id](/docs/api-reference) — already in pending, with engine, target, and the precharge hold populated. output and the final token usage fill in once it finishes.
webhook_url and let Veralens push the result the moment the job finishes. It is lower latency, costs you no extra requests, and takes load off both your app and the API. Reach for polling only when you genuinely can't receive a webhook — a local script, a notebook, a one-off.Webhooks (recommended)
Pass a webhook_url when creating the job and Veralens will POST the result to it as soon as the job finishes. Webhooks require API-key auth — they are not available for playground jobs.
Delivery payload — the body is one of:
For success, data is the parsed result (already an object for json targets, a string for markdown/plaintext).
Headers — verify authenticity before trusting a delivery:
Deliveries retry with exponential backoff if your endpoint does not respond with a 2xx. Two rules for a robust handler:
- Acknowledge fast, process after. Return
200immediately, then do the work — a slow handler looks like a failure and triggers retries. - **Be idempotent on
job_id.** A retry can deliver the same event twice; dedupe so you never double-process.
Polling (fallback)
When you can't receive a webhook, fetch the job until status is no longer pending. Poll about once per second with a ceiling — most jobs finish in a few seconds. Don't hammer the endpoint; it's strictly less efficient than a webhook.
Billing per job
Creating a job places an estimated hold on your balance. When the job completes, the hold settles to the actual token cost; if it fails, the hold is refunded in full. The final usage.cost on the job is what you were charged. See Pricing & Funds.
Listing and traceability
Use [GET /jobs/list](/docs/api-reference) to page through past jobs, filter by status or source, or search with q. Every job keeps its target, engine, token usage, and cost, so you can audit exactly what each extraction did and what it cost.