What it returns
The AI Overview capture normalizes into the same canonical Envelope:answer.text/answer.markdown— the Overview summary.markdownis always populated.answer.blocks[]— structured blocks, each typed withtextandreferenceIds.provenance.model— the observed model label and confidence.provenance.surfacePresent— whether the Overview returned an answer.provenance.region— requested vs. effective region.evidence.sources[]— the cited/retrieved sourcesanswer.blocks[].referenceIdspoint to. This is an own-fleet surface, soevidence.fanOutis{ "provenance": "none", "queries": [] }.
Every surface normalizes to the same Envelope. Whether you capture Google
AI Overview, ChatGPT, or Perplexity, you parse one shape, so the code below
works unchanged across surfaces. See Output formats.
Request
Addgoogle_ai_overview to surfaces on a standard POST /v1/search. A single-surface request with no webhook runs synchronously by default (a 200 with the Envelope inline); add ?mode=async for the durable fan-out path — one child per surface × region, returning 202 with a parent job.
202 carries the parent job and one dotted child id — read it with GET /v1/jobs/:id or receive it on a webhook.
Per-surface alias
POST /v1/search/google_ai_overview targets this one surface — sync by default like any single-surface call. It holds the connection open and returns the result inline with 200 (the Envelope in children[0]), no polling. It accepts two convenience fields: prompt (alias of query) and country (flat sugar for regions: [{ "country": "..." }]).
Envelope
A trimmed capture, the same four sections (job, provenance, answer, evidence) you get from every surface.
If Google shows no Overview for the query, the child still completes:
provenance.surfacePresent is false, job.warnings carries a
surface_absent warning, and answer is empty. An empty capture costs no
credits.All surfaces
The full enum and how fan-out works.
The Envelope
Every field in the canonical per-surface result.