Output formats
Two formats
An answer comes back in two forms. Each has its own use:
| Field | What it holds | Use it for |
|---|---|---|
text | The answer as plain text, always present on answer engines. | Search, brand matching, diffs between runs. |
markdown | The same answer with its headings, lists, tables, bold and links. | Showing the answer as the user saw it, reading tables row by row. |
Structured parts of an answer, such as sources, citationPills, links and shoppingCards, are
fields of their own in every format. You don't need to parse them out of the text.
links lists the web links in the answer's text in the order a reader meets them, each with the words it
shows (text), its url, its domain and its 1-based position. Sources cited
by pills are in citationPills. ChatGPT, Gemini, Perplexity, Copilot, Grok, and Google AI Mode return it.
Which engine returns which
| Engine | markdown | html |
|---|---|---|
| ChatGPT | With include.markdown | With include.html: a link to the page |
| Gemini | With include.markdown | With include.html: a link to the page |
| Perplexity | With include.markdown | With include.html: a link to the page |
| Copilot | With include.markdown | — |
| Grok | With include.markdown | With include.html: a link to the page |
| Google AI Mode | With include.markdown | With include.html: a link to the page |
| Google Search | No answer text: results are fields | With include.html: a link to the page |
| Google News | No answer text: results are fields | With include.html: a link to the page |
The full list of flags per engine is in engine features.
Markdown
markdown keeps the answer's structure: headings, bullet and numbered lists, bold text, links and tables as
Markdown tables. text is derived from it with the markup removed, so the two always hold the same words.
It is the engine's own Markdown, so it carries standard backslash escapes (ChatGPT writes \$15 and
1\.): render it with a CommonMark renderer, or read text, which has none. Request it with "include": { "markdown": true }.
Answers, titles and source URLs are third-party content. Render markdown with a renderer that drops raw
HTML, open source links with rel="noopener nofollow", and when an answer goes into a prompt for your own
model, mark it as data to analyze, not instructions to follow.
HTML snapshots
Set "include": { "html": true } to check an answer against the page it came from.
html then links a copy of that page as it was when the answer was captured, stored on our file host:
each Google results page, the AI Mode page, and the Google News feed the results were read from. On ChatGPT, Gemini
and Perplexity it is the answer in the engine's own page: its headings, lists, tables, citation chips,
ChatGPT's product rows and the questions it asks back, Gemini's video cards and the follow-up suggestions as the engine lays them out. A copy opens with its scripts off, so it
shows the page and runs nothing. On Grok it is a copy of the answer's public page on grok.com. That page is
sometimes not available: the answer then comes without html or screenshot and costs the
same.
The copy is free on every engine that takes it. Copilot refuses include.html with a 400 before anything runs, and nothing is billed.
With a state, ChatGPT refuses include.html and include.screenshot with
a 400, uncharged. See US states.
Screenshots
Set "include": { "screenshot": true } to see the page as it looked once the answer finished.
screenshot then links a full-page PNG of it, stored next to the HTML copy on our file host. Google Search
returns a list with one link per results page, in page order, as html does; the other engines return one
link. On Grok it shows the answer's public page, the one html copies; on ChatGPT, Gemini and Perplexity, the page
html links. Images on the page
are not loaded, so they show as empty boxes or broken-image icons.
ChatGPT, Gemini, Perplexity, Grok, Google AI Mode, and Google Search take the flag. A missing screenshot is not an error, and the request costs the same. Screenshots are free.
Provenance
Every answer carries result.provenance: how it was obtained. Nothing is guessed: a field we cannot
know for an answer is left out. Each request runs on its own: answers are never cached or shared between requests.
| Field | What it says |
|---|---|
capturedAt | When the answer was captured (ISO 8601, UTC). |
prompt / query / url | What was asked, as sent. |
requestedCountry | The country the request asked for. |
requestedState | The US state the request asked for. Absent when it named none. |
interface | The surface that answered: desktop-web, mobile-web, web-app (the engine's web app) or rss. Absent when it is not known. |
loginState | signed_out or signed_in. Absent when it is not known. |
attempt | Which attempt produced the answer, from 1. Earlier attempts failed and were not charged. |
complete | always true: a request whose answer the engine never finishes fails and is not charged. |
searchMode | Chat engines: forced when the request made the engine search the web, else engine-default. |
webSearchTriggered | Chat engines: true when the engine was seen searching the web (ChatGPT) or the answer cites sources or reports search queries; absent otherwise, since an answer without them does not prove no search ran. |
answerDepth | Perplexity: quick, the depth of every answer it serves. Absent on the others. See answer depth in engine features. |
model | Chat engines: the model the engine named; absent when it names none. |
wireCaptured | Chat engines: whether the answer request's own response body was captured. |
It is free, and not part of the declared OpenAPI schema, so a strict client should ignore keys it does not know.
Raw engine response
"include": { "rawWire": true } adds result.rawWire: the engine's own response as we
received it, before parsing. Every engine accepts the flag. It is off by default and free. It is a string when the
engine sent text, a JSON value when it sent JSON, and null where the engine's own stream, page or feed was not captured. The
parsed fields of the answer are the same either way.
| Engine | rawWire holds |
|---|---|
| ChatGPT | The finished conversation as one JSON object, or the answer stream as text. |
| Gemini | The answer stream the engine's web app received, when it was captured. |
| Google Search, AI Mode | The results pages as rendered, one HTML string per page, when they were captured. |
| Google News | The RSS feed, when it was read. |
| Perplexity, Copilot, Grok | null. |
We remove the location Gemini detected. ChatGPT's stream keeps its anonymous conversation id; its stop and resume handles are emptied. The MCP tools, the LangChain tools and the published OpenAPI document offer the flag too.
include.rawResponse is different: on ChatGPT, Gemini, Perplexity, Copilot, and Grok, it adds result.rawResponse, our normalized
event stream, kept for compatibility. rawWire is the raw answer.
Cost
include.markdown, include.html, include.rawWire, include.screenshot and provenance are free on every engine that takes them: the
request costs the same with or without them. See balance and pricing.