# ChatGPT Search Scraper & API - Answers, Sources, Products (`s-r/chatgpt-search`) Actor

Ask ChatGPT any question and get the answer as JSON: plain text and Markdown, the cited sources in order, and the product cards it shows. Built for SEO teams, agencies and brands that track their visibility in ChatGPT search. You pay only for answered questions.

- **URL**: https://apify.com/s-r/chatgpt-search.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** AI, SEO tools, Marketing
- **Stats:** 8 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 chatgpt answers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## ChatGPT Search Scraper: answers, cited sources and product cards

ChatGPT Search Scraper collects answers from anonymous ChatGPT sessions, together with the sources cited in each answer and product cards when they appear. Use it to gather the raw evidence behind AI search visibility research, compare answers to a consistent question set, or build a dataset for your SEO reporting.

The actor returns one dataset row per question. Each row includes plain answer text, a Markdown version, ordered sources and compact product information. Questions are independent: the next question starts a new conversation. No ChatGPT account, OpenAI API credential, brand configuration or competitor list is required as input.

### What the ChatGPT Search Scraper returns

- **The answer** as plain text (`answer_text`) and as Markdown with headings, lists and tables (`answer_markdown`).
- **The cited sources** in the order ChatGPT shows them: URL, page title, domain and position, with tracking parameters removed and duplicates merged.
- **Product cards** when ChatGPT shows them: product name, position, numeric price, currency, merchant and product URL.
- **Context for every row**: the question, its position in your list, the country, a UTC capture time and the conversation identifier.

### ChatGPT Search Scraper use cases

SEO teams can collect the answers their clients care about and examine which websites appear as cited sources. Agencies can keep the same question list across several collection runs and compare the resulting evidence in their own reporting tools. Brands can inspect recommendations and product mentions without having to manually copy every answer into a spreadsheet.

#### ChatGPT rank tracking and AI visibility

Run the same question list on a schedule and count how often a domain appears in `citations`, at which `position`, and whether a product shows up in `products`. That is the raw material of a ChatGPT rank tracker: you keep the method in your own spreadsheet, BI tool or database instead of trusting a black-box visibility score. Because every row carries the question, country and capture time, a change in a domain's citations can be traced back to the exact answer.

#### Content and competitor research

Read which pages ChatGPT cites for the questions in your niche. The `domain` field makes it simple to group sources by publisher, and `answer_markdown` keeps comparison tables intact, so you can see which vendors are named, in what order, and which reviews or pricing pages back up the answer.

#### Product and shopping questions

For buying questions ChatGPT often shows product cards. The actor returns them as structured rows with a numeric price and currency, so merchants and brands can see which products and shops are recommended for a question in a given country.

This is a raw collection tool. It does not calculate brand visibility scores, infer sentiment, identify competitors, or schedule repeat audits. Those calculations depend on your reporting method and the questions you select. Save the question, country and capture time with the answer so that later comparisons keep their context.

### Input

`queries` is required. On Apify, supply one string with one question per line, both in the input form and through the Apify API. Leading and trailing whitespace is removed and blank lines are ignored. Question order is preserved, including duplicate questions. The input accepts at most 10,000 questions per run; completing a large list requires a sufficient run timeout (see the FAQ). Every question must contain at most 4,000 characters. An empty question list returns an input error without producing an answer. The direct API and MCP also accept an array of question strings.

```json
{
  "queries": "what is 17 times 23",
  "country": "US"
}
```

`country` is optional and defaults to `US`. Use an ISO alpha-2 code such as `NL`, `DE` or `GB`; lowercase codes work too. `countryCode` is accepted as an API alias, and an empty alias means `US`. When both names are present, `country` takes precedence. Unsupported countries are rejected before collecting answers. The accepted country list reflects ChatGPT's supported countries and territories.

Country describes where the question is sent from. It does not guarantee local sources, local shops or a particular answer language. Write your question in the language and geographic context you want to research. For example, the recorded Dutch robot vacuum question returned Dutch answer text and EUR product cards, while an English phone plan question sent from Great Britain asked for clarification and showed no cited sources.

### How to use the ChatGPT Search Scraper

1. Enter your questions in the `queries` field, one per line.
2. Optionally pick the `country` the questions are sent from.
3. Start the run and open the **Answers and sources** view, or export the dataset as JSON, CSV or Excel.

#### ChatGPT scraper API: call it from your own code

Every Apify actor is also an API. This call runs the actor for one recorded question and returns the dataset rows in the response. It suits a handful of questions; for long lists, start an asynchronous run and read the dataset when it finishes.

```bash
curl -X POST "https://api.apify.com/v2/acts/s-r~chatgpt-search/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"queries": "best crm software for small business 2026", "country": "US"}'
```

The same input works from the Apify Python and JavaScript clients, from Make, Zapier and n8n, and from scheduled tasks in Apify Console.

### Output

The dataset contains an `ai_answer` row for each processed question. Core fields include `source`, `fetched_at`, `engine`, `query`, `country`, `answer_shown` and `answer_text`. `source` is `chatgpt-search` and `engine` is `chatgpt`. Capture timestamps are UTC. `query_index` keeps the question's position in the normalized input list.

`answer_text` removes citation chip labels while retaining the answer's prose, entity names and inline product names. Inline product references also keep their names in `answer_markdown`, without prices or merchant button labels. `answer_markdown` preserves headings, lists and tables. Each nested `citations` entry includes a URL, title, domain and position. Tracking parameters beginning with `utm_` are removed from clean URLs. Duplicate sources within one answer are combined by clean URL, in order of first appearance.

Product cards are optional. When ChatGPT shows them, `products` contains product names, positions, numeric prices, currencies, first merchants and product URLs when available. Missing price or merchant information remains null. A product mention is evidence that a card appeared in the response; it is not a verified price quotation, inventory check or recommendation from the actor.

This excerpt is taken from an actual recorded response to the arithmetic question above:

```json
{
  "query": "what is 17 times 23",
  "answer_shown": true,
  "answer_text": "17 × 23 = 391.",
  "citations": [],
  "products": []
}
```

For direct API integrations, the same sources and product cards also appear in separate `citations` and `products` lists with their question and capture context. Source rows additionally preserve the original cited URL, attribution and publication timestamp when the answer supplies them. Product rows include ratings, review counts, image URLs and offers when those fields exist on the card.

A shopping question returns sources and product cards together. Excerpt from the recorded US response to a headphones question, with the answer text left out and the lists shortened to two entries (the full row has 5 sources and 5 products):

```json
{
  "query": "best noise cancelling headphones under 200 dollars",
  "country": "US",
  "fetched_at": "2026-10-04T22:26:35.905972Z",
  "answer_shown": true,
  "citation_count": 5,
  "product_count": 5,
  "citations": [
    {
      "url": "https://www.rtings.com/headphones/reviews/best/by-price/under-200",
      "title": "The 5 Best Headphones Under $200 of 2026 - RTINGS.com",
      "domain": "rtings.com",
      "position": 1
    },
    {
      "url": "https://www.rtings.com/headphones/tools/compare/sony-wh-ch720n-wireless-vs-anker-soundcore-space-q45-wireless/38908/34852?usage=19",
      "title": "Sony WH-CH720N vs Anker Soundcore Space Q45 Wireless: Which Headphones Are Better? - RTINGS.com",
      "domain": "rtings.com",
      "position": 2
    }
  ],
  "products": [
    {
      "product_name": "Anker Soundcore Space Q45",
      "position": 1,
      "price": 129.99,
      "currency": "USD",
      "merchant": "Micro Center",
      "url": "https://www.microcenter.com/product/653777/anker-soundcore-space-q45-adaptive-noise-cancelling-wireless-bluetooth-headphones-black"
    },
    {
      "product_name": "Sony WH-CH720N",
      "position": 2,
      "price": 89.99,
      "currency": "USD",
      "merchant": "Target",
      "url": "https://www.target.com/p/sony-whch720n-bluetooth-wireless-noise-canceling-headphones-black/-/A-88533038?TCID=OAG&afid=chatgpt"
    }
  ]
}
```

### How it compares

| | ChatGPT Search Scraper | Typical alternative |
|---|---|---|
| Answer | Plain text without citation labels, plus Markdown with tables | One text field with Markdown and inline image links |
| Sources | Ordered list with URL, title, domain and position; tracking parameters removed, duplicates merged | URL and title with `utm_source` tracking left in, no domain field |
| Product cards | Separate rows: name, position, numeric price, currency, merchant, URL | Names and prices only inside the answer text |
| Questions without an answer | Returned with an English reason and not charged | Varies |
| Search queries ChatGPT used | Not available in the anonymous client (`query_fan_out` is empty) | Offered as a field by some tools, often empty |
| Account needed | No ChatGPT account or OpenAI key | Varies |

### Pricing and free plan

Billing counts completed answers with non-empty answer text: each one is a single `chatgpt-result-scraped` event, the same event name other ChatGPT search actors use, so switching does not change how your usage is counted. Sources and product cards are included with the answer and are not charged separately. A completed answer without citations still counts as an answer. Unanswered questions and invalid input do not generate answer charges. Check the actor's Pricing tab for current event prices and any platform fees.

Users without a paid Apify plan receive at most ten dataset rows per run. The question list is capped before collection begins. Paid users can submit larger lists; processing time grows with the number of questions. Repeated questions remain separate requests and separate completed answers.

### FAQ

#### Does every answer include web sources?

No. ChatGPT decides whether to search and what to cite. Arithmetic, clarification requests and questions without relevant results can produce complete answers with an empty citations list. The actor preserves that distinction instead of inventing sources.

When ChatGPT shows only lightweight source chips (domain names without citation URLs in the page), `citations` stays empty. The actor never invents URLs, so empty citations alongside visible source names is expected behaviour rather than a defect.

#### Can I request ChatGPT's internal search queries?

The anonymous client does not expose query fan-out. `query_fan_out` is therefore always an empty array. It should not be interpreted as proof that ChatGPT did not perform a search.

#### How are long question lists processed?

The actor follows continuation cursors automatically. Allow roughly 3–4 questions per minute (about 15–20 seconds per question), with additional time for retries and waiting during busy periods. The default Apify run timeout is 1,200 seconds (20 minutes), typically enough for roughly 60–70 questions, not the full 10,000-question input limit. Concurrent runs share collection capacity fairly, so each run may need more time during overlap. Increase the run timeout in Apify's run options before submitting a large list; for 500 questions, allow at least three hours and extra time for retries. If the timeout guard is reached, the run returns the completed answers with `partial: true` and a warning. Only completed answers are charged.

Direct API clients keep the same questions and country, pass `next_cursor` as `cursor`, and continue until the cursor is null. Every collection request has a bounded time budget, so larger lists are delivered in several pieces. A retryable busy response should be retried with pauses; the Apify actor handles this automatically within its run timeout.

#### What happens when a question fails?

A failed question can carry `answer_shown: false`, null answer text and an English error reason alongside successful questions. If no answer completes, the request returns a structured source error. Temporary timeouts can be retried. Previously delivered answers remain available when a later question cannot finish.

#### Are results identical across runs?

No. ChatGPT answers and search results can change between runs. Keep the full response, question wording and timestamp when comparing measurements, and use repeated observations before drawing conclusions about visibility.

#### Is this the same as the OpenAI API with web search?

No. The OpenAI API answers through developer models with their own settings and requires an API key that you pay for. The ChatGPT Search Scraper records what an anonymous visitor sees in ChatGPT itself: the answer, the sources it cites and the product cards it shows. Use it when you need to know what ChatGPT users are shown, not what a model returns through the API.

#### Do I need a ChatGPT account or an OpenAI key?

No. Questions are asked in anonymous sessions. You only need an Apify account to run the actor.

#### Which countries are supported?

Any country or territory where ChatGPT is available, set with an ISO alpha-2 code such as `US`, `GB`, `NL` or `DE`. Countries where ChatGPT is not offered are rejected before any answer is collected, so they never cost anything.

# Actor input Schema

## `queries` (type: `string`):

Questions as one string with one question per line, also when calling the Apify API. Blank lines are ignored; each question is at most 4000 characters.

## `country` (type: `string`):

ISO alpha-2 country from which questions are sent. The question language largely determines localization.

## `countryCode` (type: `string`):

Legacy alias of country. Leave country empty to use this value; empty means US.

## Actor input object example

```json
{
  "queries": "best crm software for small business 2026",
  "country": "US"
}
```

# Actor output Schema

## `answers` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": "best crm software for small business 2026",
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/chatgpt-search").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": "best crm software for small business 2026",
    "country": "US",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/chatgpt-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": "best crm software for small business 2026",
  "country": "US"
}' |
apify call s-r/chatgpt-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,s-r/chatgpt-search"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rJsTMbI1EXOaHm4WX/builds/LRmbcecONLCdGS2jV/openapi.json
