- One surface, no webhook (the hello-world case) runs synchronously by default: the call returns the terminal Envelope in one
200. - Multiple surfaces, a
webhook, or?mode=asyncuse the durable path:202immediately with a parent job and one child per surface × region. PollGET /v1/jobs/:idor register a webhook.
Authorization: Bearer <API_KEY> and Content-Type: application/json.
Query parameters
sync forces the bounded inline path; async forces the durable 202 + poll
path. Omitted: a single-surface no-webhook request runs sync, everything else
async. The header Prefer: wait=30 is equivalent to ?mode=sync.flat projects each Envelope of a sync response to the compact flat shape (surface, status, text, markdown, sources). One child returns the flat object directly; several children return { "results": [...] }.Body
The prompt to run. This is the exact text sent to each surface.
prompt is
accepted as an alias. Non-empty, up to 2000 characters — a longer value is
rejected with 422 QUERY_TOO_LONG.One or more surfaces to capture. Each surface produces one child job per region.Allowed values:
chatgpt, claude, perplexity, gemini, copilot, google_ai_overview, google_ai_mode, google_search, google_news.Where to run each surface — at most 10 per request. One child is created per surface × region. Omitted: one untargeted (
GLOBAL) child per surface. A bare string like "US" is accepted as sugar for { "country": "US" }.Receive a signed POST on each child’s terminal state instead of polling. Setting a webhook forces the async path. Recommended for fan-out.
Safe-retry key. This is a body field, not a header. Reusing the same key
with the same body replays the original job (
202 + Idempotent-Replayed: true); reusing it with a different body returns 409 IDEMPOTENCY_CONFLICT.Opt in to Auto Extract.
true is identical to {}:
extract brands the answer mentions without pinning targets. false, or
omitting the field, disables extraction and leaves evidence.mentions as
null. Auto Extract is BETA and adds 0 credits today; pricing will
change at GA.Request
Response 202 Accepted (async)
The parent job id has no dots. Each entry in children is a dotted 3-segment child id — <jobId>.<surface>.<regionKey> — where the region key is the lowercased country[:city][:language] (or GLOBAL when untargeted).
The parent job id (dotless). Read it with
GET /v1/jobs/job_8t2q to see the
roll-up status and per-child state.Always
processing on submit. Terminal states are completed, partial,
failed, canceled, expired.Response 200 OK (sync)
A sync call returns the parent id, its rollup status, and the full Envelope per child:
evidence.mentions populates only when the request sets extract. See Auto
Extract for the full shape, pinned-target absence
behavior, and examples.?view=flat the same call returns just { surface, status, text, markdown, sources }.
If a surface returns nothing, the job still completes:
provenance.surfacePresent is false, job.warnings carries a
surface_absent warning, and answer is empty. An empty capture costs no
credits.Per-surface alias
POST /v1/search/:surface targets one surface — sync by default like any single-surface call. It accepts two convenience fields:
prompt— alias ofquery.country— flat sugar forregions: [{ "country": "..." }].
Idempotency
IncludeidempotencyKey in the body to make retries safe.
Errors
Every error uses the flat shape{ "code", "error", "request_id", "docs_url", "details"? }. Validation messages name the offending field and the allowed values.
400
429 responses carry
Retry-After alongside X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. See Errors for the full catalog.
Response headers
Read a job
Poll a parent or fetch a single child’s Envelope.
The Envelope
Every field in the canonical per-surface result.
Auto Extract
Extract brand mentions and pin targets for present-or-absent reporting.