ChatGPT scraper API
The answer ChatGPT shows its users, with every cited source in order, sentence-level citations, the brands, products and places it names, and its pictures.
Price
$1.50 per 1,000 requests at Starter, down to $1.00 at Max, deducted from your prepaid USD balance.
Endpoint
POST /v1/monitor/chatgpt
Countries
213 countries, plus US states.
Request
curl -X POST "https://api.answerline.dev/v1/monitor/chatgpt" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"What are the best running shoes for flat feet?","country":"US","include":{"markdown":true}}'
import { Client } from "@answerline/sdk";
const client = new Client({ apiKey: process.env.API_KEY! });
const answer = await client.monitor.chatgpt({
"prompt": "What are the best running shoes for flat feet?",
"country": "US",
"include": {
"markdown": true
}
});
import os
from answerline import Client
with Client(os.environ["API_KEY"]) as client:
answer = client.monitor.chatgpt(
prompt="What are the best running shoes for flat feet?",
country="US",
include={
"markdown": True
},
)
What you get back
Field in result | Type | Description |
|---|---|---|
text | string | Text of ChatGPT's reply |
markdown | string | ChatGPT's reply as Markdown; returned only if include.markdown is true |
links | object[] | The links in the answer's text, in the order a reader meets them: one entry per web (http or https) link the answer shows, images and code aside, with the words it shows (text), where it goes (url), its domain and its 1-based position. Sources cited by pills are in citationPills; links to the same page appear in both when the answer does both. Empty when the text links nowhere. |
sources | object[] | Sources the response cites; an empty array if there are none. |
searchResults | object[] | Every page ChatGPT searched for the answer (its "Searched N websites"), cited or not, in the order it lists them. Absent when the answer did not search or ChatGPT does not list them. |
searchQueries | string[] | The fan-out queries ChatGPT issued while producing the response (present when include.searchQueries is true) |
shoppingCards | object[] | Shopping/product cards parsed from the response. When include.shopping is false or not set, result does not contain this field at all, so treat it as optional instead of relying on an empty array. |
inlineProducts | object[] | Products shown inline, with their prices and offers. When include.shopping is false or not set, result does not contain this field at all, so treat it as optional instead of relying on an empty array. |
entities | object[] | Entities parsed from the response (if any). With include.shopping, an entity ChatGPT links to a product also carries product. |
map | object[] | Map entries for businesses or places parsed from the response (if any). Entries originate from the enrichment providers ChatGPT uses (Yelp, Google Business), with field names in camelCase. Only the fields filled in most often appear here; see the API reference for every field. |
images | object[] | The pictures ChatGPT shows in its answer, beside the places and things it names, in answer order: medium image, the page each comes from (url), its title and the picture shown (thumbnail). Absent when the answer shows none. |
citationPills | object[] | Inline citation pills parsed from the response (if any), i.e. citations shown in the body of the text. Every entry represents a single (pill, source) pair; grouping on citationPillId rebuilds each pill. |
ads | object[] | Ads delivered with the ChatGPT response (present when include.ads is true). Several candidate ads are sent by OpenAI, yet the interface displays one at most; check rendered to see which ones were really displayed. |
model | string | ChatGPT model that produced the answer. Empty when ChatGPT names no model. |
Answers from inside any US state
Send state with a two-letter code and ChatGPT and Gemini answer from inside that state, as a person there sees it. All 50 states and DC are covered; GET /v1/states?country=US lists the codes.
{ "prompt": "best pizza near me", "state": "TX" }
A state implies country "US"; with any other country the request is refused with a 400. The price is the same with or without a state. result.provenance.requestedState echoes the state. On 2026-11-09, “best pizza near me” with TX was answered for San Antonio; without a state, for New York. Every other engine accepts state and answers for the whole US (coverage).
ChatGPT state targeting covers who uses it and a 51-state batch in Python and TypeScript.
The app answer versus OpenAI’s developer API
This endpoint returns the answer a ChatGPT user sees. OpenAI’s developer API returns a completion you generate yourself, and the two answer different questions.
The developer API has a web search tool. Its guide (checked 2026-09-17, developers.openai.com) says the response carries url_citation annotations with the URL, title and location of each cited source, a separate sources list of every URL retrieved, the search actions the model took, and an optional user location (country, city, region, timezone). The guide does not describe shopping cards or ads. You also choose the model, system prompt and tool settings, so the output reflects your configuration.
When a brand manager asks whether ChatGPT recommends them, they mean the app. A completion with your own settings is a proxy you would have to validate against the app anyway.
The app also shows products from its shopping search, which the developer API does not describe. They are returned here as inlineProducts. For e-commerce brands those products decide visibility.
Citation fields here describe presentation. citationPills records which sources were grouped into each inline chip. sources[].footnote would mark a source listed but cited by no chip; it is false on every answer served today, since every listed source is cited by a chip. That is closer to what a reader clicks than a list of retrieved URLs. Provider model APIs vs the answers users see compares the two side by side.
An annotated response
The excerpt follows the result schema for POST /v1/monitor/chatgpt. Values are illustrative; the request set include.markdown, include.searchQueries and include.shopping to true.
{
"success": true,
"result": {
// Plain answer text; markdown is present because include.markdown was true.
"text": "For flat feet, look for stability shoes with a firm midsole...",
"markdown": "For **flat feet**, look for stability shoes with a firm midsole...",
// Every cited page, in order. datePublished is omitted when unknown, never null.
"sources": [
{
"position": 1,
"url": "https://www.example-running.com/guides/flat-feet",
"label": "Best Running Shoes for Flat Feet",
"description": "We tested stability models on...",
"footnote": false,
"datePublished": "2026-08-02"
}
],
// One entry per (chip, source) pair. ChatGPT's citationPillId starts at 0.
// position points into result.sources (1-based).
"citationPills": [
{
"url": "https://www.example-running.com/guides/flat-feet",
"label": "Best Running Shoes for Flat Feet",
"domain": "example-running.com",
"citationPillId": 0,
"type": "searchResult",
"position": 1
}
],
// Products from ChatGPT's shopping search, each once. Present only when include.shopping is true.
"inlineProducts": [
{
"render_as": "inline",
"product": {
"title": "Example Stability Runner 5",
"position": 1,
"id": "1234567890",
"url": "https://www.example-store.com/p/stability-runner-5",
"price": "$139.95",
"image_urls": ["https://images.example-store.com/runner-5.jpg"],
"offers": [
{
"merchant_name": "Example Store",
"product_name": "Example Stability Runner 5",
"url": "https://www.example-store.com/p/stability-runner-5",
"price": "$139.95",
"available": true
}
]
}
}
],
// Every brand and product the answer names: ChatGPT's full name for it and its category.
"entities": [{ "type": "product", "name": "Example Stability Runner 5" }],
// Nullable.
"model": null
}
}
result.provenance says how an answer was obtained (all fields). interface is the surface that answered and loginState is signed_out. Each request is a new conversation with your prompt unchanged. model is absent when ChatGPT names none. complete is always true: if ChatGPT never finishes an answer, the request fails, uncharged. wireCaptured says whether rawWire could be filled.
Notes for this engine
Fields in your client
shoppingCardsandinlineProductsare absent wheninclude.shoppingis off. A requested list (searchQueries,ads,shoppingCards,inlineProducts) is an empty array when it has nothing.searchQueries,adsandshoppingCardsare empty on the ChatGPT answers served today.inlineProductsholds the products from ChatGPT’s shopping search.entitieslists every brand and product the answer names, those products too. Itsnameis ChatGPT’s full name for it, which can differ from the words intext; itstypeis its category (product,software, …). Withinclude.shopping, an entity ChatGPT links to a product also carriesproduct: its price, URL and merchant offers, in the shape of an inline product.entitiesis absent andcitationPillsempty when there are none.mapholds the local businesses the answer names as cards (restaurants, shops), each once in answer order:name,address,latitude,longitude,categories,rating,reviewCount,description,phone,websiteUrl, ChatGPT’s ownidandproviderfor it, andposition. The same businesses are inentitieswithtypelocal_business.imagesholds the pictures the answer shows beside what it names:thumbnail(the picture),url(the page it comes from),titleand sizes.mapandimagesare absent when the answer has none.modelis nullable.- No merchant field is filled on a product: read
offers[0].merchant_name. product.positionininlineProductsis its own 1-based sequence. InshoppingCardsit is a flat rank across all cards, not reset per card.
Answers vary between runs
The same prompt, market and hour can produce different text, sources and products, so one run per prompt tells you little. Run each prompt several times per period, store every sample, and report rates (“cited in 7 of 10 runs”) with the sample size. Put the sample number in the idempotency key (...-s3-2026-09-17) so samples are distinct tasks. Answer volatility and sampling vs census cover how many samples to take.
Prompt wording is a variable
Small wording changes shift answers. Freeze the prompt set, version it, and change it deliberately; see prompt set design.
Domains and pages are different metrics
Count citation share on citationPills[].domain for domains and on sources[].url for pages. Mixing them in one metric makes the numbers meaningless.
Markets and search
The finest market is a US state; there is no city-level option. For multi-market studies, keep the prompt text identical and vary only the market, so differences are attributable to it. How to see ChatGPT answers by US state runs one prompt in all 51, and the state-level answers post walks through a larger design.
ChatGPT decides for itself whether to search the web on every answer served today, so disableWebSearch is accepted and changes nothing (provenance.searchMode is engine-default). legacy is accepted and does not change the answer.
Related: ChatGPT state targeting, AI visibility tracking, measuring brand mentions in ChatGPT, competitor analysis, keyword research, ChatGPT shopping cards.
Questions
What does one ChatGPT request return and cost?
The answer text, every cited source with its position, the inline citation chips and the entities (the brands and products the answer names), without any flag. Flags add markdown, searchQueries, ads, shopping products and the raw response at no cost. On the ChatGPT answers served today, searchQueries, ads and shoppingCards come back empty; products from ChatGPT's shopping search come back in inlineProducts. At the Starter tier a request costs $0.0015.
Can I use it for competitive analysis?
Yes. Run the prompts buyers ask about your category and compare brands across the answers: entities lists the brands and products each answer names, sources and citationPills show which domains it cites, and inlineProducts show whose products appear at what price and merchant. The ads list comes back empty on the ChatGPT answers served today.
How is this different from the OpenAI API?
This endpoint returns the answer the ChatGPT app shows its users, with its citations and shopping-search products as fields. OpenAI's developer API returns a completion from a model, system prompt and tools you configure yourself, so it does not tell you what ChatGPT users see.
Can I target a US state with ChatGPT?
Yes, in all 50 states and DC. Send state as a two-letter code, for example CA; it implies country US, and with another country it is refused with a 400. See /docs/coverage#states.
Am I charged when a ChatGPT request fails?
No. A failed request is charged nothing and its reservation is released. A completed request is charged its base price, even if, for example, no products were shown.
From the blog
Best ChatGPT scraper APIs for 2027: answers and citations
How to see ChatGPT answers by US state
ChatGPT visibility tracker: platforms, costs and a pipeline you can run
Docs
- Quickstart
- API reference
- Engine features
- Async tasks and batches
- Webhooks
- Coverage
- Pricing and failures
- Rate limits