The Envelope is the canonical result for one surface. Every surface returns the exact same shape, so you write your parsing logic once and it works for ChatGPT, Claude, Perplexity, Gemini, Copilot, Google AI Overview, and Google AI Mode alike. You read an Envelope by fetching a child job — a dotted id like job_8t2q.chatgpt.us:
curl https://api.aisearchapi.dev/v1/jobs/job_8t2q.chatgpt.us \
  -H "Authorization: Bearer $AISEARCH_API_KEY"
A parent id has no dots (job_8t2q) and returns the list of children. A child id is dotted (job_8t2q.chatgpt.us) and returns the Envelope shown here. See Jobs & polling for how the two relate.

The four sections

An Envelope always has these four top-level sections:
SectionWhat it holds
jobIdentity and status of this capture — the query, surface, region, timestamps, and any warnings.
provenanceWhat actually produced the answer — which model, whether web search ran, and the effective region.
answerThe answer the user saw — as plain text, as markdown, and as structured blocks.
evidenceThe structured proof behind the answer — cited sources, follow-up queries, mentions, shopping, and ads.

Full example

{
  "job": {
    "id": "job_8t2q.chatgpt.us",
    "query": "best crm for startups",
    "surface": "chatgpt",
    "region": "US",
    "status": "completed",
    "warnings": [],
    "requestedAt": "2026-06-30T17:02:11Z",
    "completedAt": "2026-06-30T17:02:23Z"
  },
  "provenance": {
    "model": {
      "providerId": "openai",
      "observedLabel": "GPT-5",
      "inferred": false,
      "confidence": 0.98
    },
    "webSearch": { "enabled": true, "known": true },
    "region": { "requested": "US", "effective": "US" },
    "surfacePresent": true
  },
  "answer": {
    "text": "For startups, the top CRMs are HubSpot, Attio and Pipedrive...",
    "markdown": "For startups, the top CRMs are **HubSpot**, **Attio** and **Pipedrive**...",
    "blocks": [
      { "type": "paragraph", "text": "...", "referenceIds": [1] }
    ]
  },
  "evidence": {
    "sources": [
      {
        "id": 1,
        "url": "https://...",
        "title": "Best CRMs for startups",
        "role": "cited",
        "cited": true,
        "charRanges": [[0, 58]],
        "quote": "..."
      }
    ],
    "fanOut": { "queries": ["best crm for startups 2026", "hubspot vs attio"] },
    "mentions": ["HubSpot", "Attio", "Pipedrive"],
    "shopping": [],
    "ads": []
  }
}

job

job.id
string
The child id for this capture — job_<id>.<surface>.<region>.
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).
job.region
string
The requested region for this capture (ISO-3166 alpha-2).
job.status
string
Lifecycle state. Active: queued, processing. Terminal: completed, partial, failed, canceled, expired. A child Envelope is only meaningful once status is terminal — a poll loop must stop on any terminal state. See Job lifecycle.
job.warnings
string[]
Non-fatal notes about this capture. For example, a surface_absent warning accompanies provenance.surfacePresent: false when the surface returned nothing.
job.requestedAt
string
ISO-8601 timestamp when the capture was requested.
job.completedAt
string
ISO-8601 timestamp when the capture reached a terminal state.

provenance

provenance.model
object
Which model produced the answer.
Whether the surface ran a web search for this answer. enabled is the observed value; known is true when that value is certain.
provenance.region
object
requested is the region you asked for; effective is the region the surface actually served.
provenance.surfacePresent
boolean
true when the surface returned an answer. false means the surface returned nothing — see When a surface returns nothing.

answer

answer.text
string
The answer as plain text — the words the user saw, stripped of formatting.
answer.markdown
string
The same answer as markdown, preserving bold, lists, and other formatting. This field is always populated for a present answer, so you can render it directly.
answer.blocks
object[]
The answer broken into structured blocks.

evidence

evidence.sources
object[]
The sources behind the answer.
evidence.fanOut.queries
string[]
The follow-up queries the surface ran on its own to answer the prompt.
evidence.mentions
string[]
Brands and entities named in the answer.
evidence.shopping
object[]
Shopping results the surface returned, when present.
evidence.ads
object[]
Ads the surface returned, when present.

When a surface returns nothing

Sometimes a surface produces no answer for a query. When that happens the job still reaches completed — it does not fail. The Envelope reports the absence plainly:
  • provenance.surfacePresent is false.
  • job.warnings includes a surface_absent warning.
  • answer is empty.
An empty capture like this costs nothing — you are only charged on a successful capture. See Credits & pricing.

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.