The Envelope is the canonical result for one surface × region. Every surface returns the exact same shape, so you write your parsing logic once and it works for ChatGPT, Claude, Perplexity, Copilot, Google AI Overview, Google AI Mode, Google Search, and Google News alike. You read an Envelope by fetching a child job — a dotted, three-segment id like job_8t2q.chatgpt.us:
A parent id has no dots (job_8t2q) and returns the list of children. A child id is dotted (job_<id>.<surface>.<regionKey>) and returns the Envelope shown here. See Jobs & polling for how the two relate. Sync responses carry the same Envelope per child inline; ?view=flat projects each one down to { surface, status, text, markdown, sources } — see The flat projection.

The four sections

An Envelope always has these four top-level sections, plus two optional add-ons: The full structured evidence — cited sources, the query fan-out, and brand mentions — is included at no extra credit cost. There is no per-field charge; a capture bills the flat per-surface price whether it returns a one-line answer or deep evidence.

Full example

job

job.id
string
The child id for this capture — job_<id>.<surface>.<regionKey>.
job.query
string
The prompt that was submitted.
job.surface
string
The surface this Envelope came from (chatgpt, claude, perplexity, gemini, copilot, google_ai_overview, google_ai_mode, google_search, google_news).
job.region
string
The canonical region key this capture ran in — lowercased country[:city][:language], or GLOBAL when untargeted.
job.status
string
Lifecycle state — one of queued, running, completed, partial, failed. Active: queued, running. Terminal: completed, partial, failed. A child Envelope is only meaningful once status is terminal — a poll loop must stop on any terminal state, and also stop if a job is reported canceled or expired. See Job lifecycle.
job.warnings
string[]
Non-fatal notes about the CAPTURE (a property of the answer you received) — the answer is still valid. This is a closed allowlist; the API never exposes internal acquisition-lane or routing detail here. Known values:
  • surface_absent — the surface rendered no answer; accompanies provenance.surfacePresent: false (absence is data, the job still completes).
  • partial_capture — the page was captured but a region or section was cut off; the returned answer may be incomplete.
  • geo_not_applied — the requested region could not be applied to this capture; compare against provenance.region (requested vs effective).
  • location_not_applied — a requested region.location (a Google geotarget canonical name) could not be uule-encoded, so no locality was applied and provenance.region.effectiveLocation was left null. We never apply a wrong uule (it would silently mislocalize) — honest absence instead.
  • extraction_failed — Auto Extract was requested, but the extraction lane failed, was unavailable, or exhausted its time budget; evidence.mentions is null. The capture itself still completes normally.
  • extraction_skipped — Auto Extract was requested, but an empty answer or surface_absent left nothing to extract; evidence.mentions is null. The capture itself still completes normally.
job.requestedAt
string
ISO-8601 timestamp when the capture was requested.
job.completedAt
string | null
ISO-8601 timestamp when the capture reached a terminal state.

provenance

provenance is the lane-free record of how the answer was produced. It tells you which model spoke, whether the surface searched the web, and the exact region and login context the capture ran under — everything you need to judge a result, and nothing about our internal plumbing.
provenance.model
object
Which model produced the answer.
Whether the surface ran a web search for this answer. enabled is the observed value (null when unknown); known is true when that value is certain.
provenance.triggerState
string
How the answer was produced: search when the surface consulted the web, or parametric when it answered from the model’s own weights without searching.
provenance.persona
string
The account context the capture ran under — anonymous_default_model, anonymous_authenticated, or consented_personalized.
provenance.loginState
string
Whether the capture was signed in on the surface: logged_in, logged_out, or unknown.
provenance.surfacePresent
boolean
true when the surface returned an answer. false means the surface returned nothing — see When a surface returns nothing.
provenance.region
object
requested is the region key you asked for; effective is the region the capture actually ran from. Both are strings (or null for an untargeted capture).For Google-surface locality (region.location), two more fields let you verify what was localized: requestedLocation is the geotarget canonical name you asked for (or null), and effectiveLocation is the name a uule was actually applied for (or null). effectiveLocation is null — paired with a location_not_applied warning — whenever the name could not be encoded, so a wrong locality is never claimed.
provenance.capturedAt
string
ISO-8601 timestamp of the capture itself.
provenance.callUuid
string
A stable id for this individual capture run — useful for correlating a result with your own logs.
provenance.schemaVersion
string
The Envelope schema version this result was produced under. Treat unknown provenance fields as additive.
provenance is deliberately lane-free. It does not expose how we acquired the capture — no method, acquisition, fidelity, engine, routing, or driver-version fields. The acquisition lane is internal and never surfaced; what you get is a clean, portable description of the result itself.

answer

answer.text
string
The answer as plain text — the words the user saw, stripped of formatting. Always present.
answer.markdown
string
The same answer as markdown, preserving bold, lists, and other formatting. Present for every answer unless you set include.markdown: false on the request to trim it. When present you can render it directly.
answer.blocks
object[]
The answer broken into structured blocks.

evidence

evidence is the structured extraction for the capture — cloro parity, included at no extra credit cost. It carries the sources behind the answer, the internal search queries the surface fanned out, and a derived brand-visibility layer. Every field is always present; mentions may be null, and shopping / ads are reserved placeholders that are currently always null.
evidence.sources
object[]
The cited and retrieved sources for the answer. answer.blocks[].referenceIds point at these by id.
evidence.fanOut
object
The internal search queries the surface used to answer, when observable.
evidence.mentions
object | null
The derived brand-visibility layer. It is null unless the request set extract, or when extraction failed or was skipped.
evidence.shopping
null
Reserved for structured shopping cards. Currently always null — it exists today so adding it later is not a breaking change.
evidence.ads
null
Reserved for structured ads. Currently always null, for the same reason.

html

The optional html field is a proof-of-page URL — a rendered snapshot of the exact page the answer was captured from, so you can show a receipt of what a real user saw.
html
string (uri)
A URL you resolve with GET /v1/artifacts/{key}, authenticated with your API key. Present only when both are true:
  • You opt in — set include.html: true on the submit body, or add ?include=html when you poll.
  • The capture is a consumer-UI (scrape) surface — the ones where there is a real page to snapshot. Model-API-style captures have no page and omit html even when requested.
When those conditions aren’t met, the field is simply absent.
html is the only capture snapshot published to customers, and it’s strictly opt-in. Fetch it the same way you fetch any artifact — see Fetch an artifact.

credits

On metered (restricted-key) requests each capture reports its cost inline under success-only billing.
credits.creditsToCharge
integer
The reserved/estimated cost — the flat per-surface price for this capture.
credits.creditsCharged
integer
The finalized cost after settlement: the full price on a successful capture, and 0 for an absent or failed capture (which is never charged). It reads 0 while a job is still processing.
A credits object appears on the sync result, on each accepted batch item, on each child-job GET, and in the webhook payload; the parent-job rollup carries creditsToCharge only. Metered submits also return X-Credits-Charged and X-Credits-Remaining headers on the sync 200 and the async 202. See Credits & billing for how costs add up across a fan-out.

The include request field

The submit body accepts an optional include object that shapes the response only — it never changes how a capture is acquired.
include.markdown
boolean
default:"true"
Keep answer.markdown in the response. Set false to trim it and slim the payload — answer.text is always present regardless.
include.html
boolean
default:"false"
Add the proof-of-page html URL. Honored on consumer-UI (scrape) surfaces only.
Unknown include keys are rejected with 400 VALIDATION_FAILED. Send only markdown and html.

The flat projection

Add ?view=flat to a sync request (or a poll) and each Envelope is projected down to the compact fields a simple consumer needs:
?view=flat (one child)
The flat shape is { surface, status, text, markdown, sources } — the answer’s cited/retrieved sources ride along even here. A single child returns the flat object directly; several children return { "results": [...] }. The flat view always returns a markdown field, falling back to text when no distinct markdown exists — include.markdown: false only trims answer.markdown in the rich Envelope, never the flat projection.

When a surface returns nothing

Absence is data. Sometimes a surface produces no answer for a query — that is a real, useful signal, and the capture reports it plainly instead of failing:
  • The child job still reaches completed; it does not fail.
  • provenance.surfacePresent is false.
  • job.warnings includes a surface_absent warning.
  • answer is empty.
An empty capture like this is freecredits.creditsCharged is 0, because you are only charged on a successful capture. See Credits & billing.

Jobs & polling

How parent and child jobs relate, and how to read results.

Job lifecycle

Every state a job can be in, and when to stop polling.

Fetch an artifact

Resolve the opt-in proof-of-page html URL.

Credits & billing

What a capture costs — evidence and all — and when you’re charged.