🎯 A customizable, anti-detection cloud browser powered by self-developed Chromium designed for web crawlers and AI Agents.πŸ‘‰Try Now
Back to Blog

ChatGPT vs Gemini vs Perplexity: Response Structure Compared

Daniel Kim
Daniel Kim

Lead Scraping Automation Engineer

29-Jun-2026

TL;DR:

  • Three actors, one transport, three answer shapes. scraper.chatgpt, scraper.gemini, and scraper.perplexity all POST to the same endpoint and return the same { status, task_id, task_result } envelope β€” but the fields inside task_result differ by actor.
  • The "sources" field has a different name on each. ChatGPT returns content_references and search_result; Gemini returns citations; Perplexity returns web_results β€” the same idea, three keys, three per-item shapes. The field you read to get the sources is not portable across the three.
  • Only ChatGPT returns products. With shopping enabled, scraper.chatgpt adds a products array with per-merchant offers; Gemini and Perplexity return no shopping surface.
  • Perplexity carries the richest envelope. On top of the answer and web_results, it returns a media_items array and a related_prompt list; Gemini is the leanest β€” answer text plus a citations array and nothing else.
  • Input flags differ by actor. All take prompt and country inside input; ChatGPT adds an optional shopping flag, Perplexity adds web_search. Parameters always go inside input, never at the top level.
  • Every field is nullable and per-session. An array can come back empty on a given run, so the actor you pick decides which fields you can rely on β€” store task_id and a capture timestamp and read the series, not one call.
  • Free to start. New Scrapeless accounts include free trial credits β€” sign up at app.scrapeless.com.

Introduction: one prompt, three response shapes

Send the same question to ChatGPT, Gemini, and Perplexity through Scrapeless and three answers come back β€” in three different JSON shapes. The transport is identical: one POST, one x-api-token header, one { status, task_id, task_result } envelope. What changes is the inside of task_result β€” the key that holds the answer's sources, whether products come back, whether media and follow-up prompts are included. A client that reads one of these actors does not automatically read the other two.

This is a developer comparison of the returned schemas, not a verdict on which model answers better. It maps, field by field, what scraper.chatgpt, scraper.gemini, and scraper.perplexity actually return for the same prompt, where the schemas diverge, and which actor to capture for which job. For the best LLM scrapers view of the tool category itself, that guide ranks the surfaces; this one lays their response shapes side by side.


What each actor captures

All three are Universal Scraping API LLM actors, captured the same way:

  • scraper.chatgpt β€” ChatGPT's synthesized answer, the sources it cited, and (with shopping on) a product carousel with per-merchant offers.
  • scraper.gemini β€” Gemini's answer plus a citations array. The leanest of the three.
  • scraper.perplexity β€” Perplexity's answer, its web-result sources, inline media, and the follow-up prompts it suggests.

The shared contract: same endpoint, same envelope, same auth

All three actors POST to https://api.scrapeless.com/api/v2/scraper/execute with an x-api-token header and a body of { actor, input: { prompt, country, … } }, and all three return { status, task_id, task_result }. Swapping actors is a one-line change.

bash Copy
curl -sS -X POST https://api.scrapeless.com/api/v2/scraper/execute \
  -H "Content-Type: application/json" \
  -H "x-api-token: ${SCRAPELESS_API_KEY}" \
  -d '{ "actor": "scraper.gemini", "input": { "prompt": "best running shoes 2026", "country": "US" } }'
# actor: scraper.chatgpt | scraper.gemini | scraper.perplexity

The transport is portable; the parsing is per-actor β€” task_result is where they diverge.


The answer body, compared

Every actor returns the synthesized answer as result_text (markdown-flavored prose). That field name is the one thing the answer body shares across all three. None of the three returns separate markdown and HTML variants of the answer β€” result_text is the single answer format here. (The scraper.aimode actor, a different surface, is the one that splits the answer into text/markdown/HTML; these three do not.)


Where the schemas diverge: citations and sources

"What did the model cite" is the same question for all three actors and a different field on each:

  • ChatGPT splits it in two: content_references[] (the cited sources, each with title, url, attribution) and search_result[] (the web results it consulted, with title, url, snippet, attribution), gated by a web_search boolean.
  • Gemini returns a single citations[] array, and it is the most detailed per item: title, url, website_name, snippet, favicon, and highlights.
  • Perplexity returns web_results[], the leanest source item: name, url, snippet.

Same concept, three keys, three shapes. A share-of-citation parser written against Gemini's citations[].website_name does not run against Perplexity's web_results[].name without remapping.


Platform-unique fields

Each actor returns something the other two do not:

  • ChatGPT β€” products. Set input.shopping: true and scraper.chatgpt adds a products[] array, each product carrying a price, rating, review count, and an offers[] list with one entry per merchant. It also returns a model id and a links[] array. Gemini and Perplexity have no shopping surface.
  • Perplexity β€” media and follow-ups. scraper.perplexity returns a media_items[] array (image, thumbnail, url, source, medium) and a related_prompt[] list of suggested follow-up questions β€” neither of which the other two return.
  • Gemini β€” nothing extra. Gemini's value is the opposite: a clean two-field answer (result_text + citations[]) with no platform-specific surface to handle.

The field matrix: all three side by side

Conceptual field scraper.chatgpt scraper.gemini scraper.perplexity
Answer text result_text result_text result_text
Cited sources content_references[] (title, url, attribution) citations[] (title, url, website_name, snippet, favicon, highlights) web_results[] (name, url, snippet)
Web-search results search_result[] + web_search flag β€” web_results[]
Products / offers products[] + offers[] (with shopping: true) β€” β€”
Media β€” β€” media_items[]
Related prompts β€” β€” related_prompt[]
Model id model β€” β€”
Links links[] β€” β€”
Echoed prompt prompt prompt prompt
Optional input flag shopping β€” web_search

Read down a column to know which fields an actor gives you; read across a row to see why one parser cannot serve all three.

Get your API key on the free plan: app.scrapeless.com


Input parameters, compared

The input object is where the request-side asymmetry lives. All three require prompt and country; the optional flags differ.

input field scraper.chatgpt scraper.gemini scraper.perplexity
prompt required required required
country required required required
shopping optional (β†’ products[]) β€” β€”
web_search optional β€” optional

Every field sits inside input; sending prompt or country at the top level of the body is rejected.


Volatility and nullability across the three

The answer is generated per session, so the same prompt returns different text and different array lengths from one run to the next, on every actor. Treat each field as nullable: products[] can be empty even with shopping on, citations[] and web_results[] vary in count, and a persistently empty array means there was no answer for that query β€” not something to send again. Store task_id and a capture timestamp on every call so the time series is the signal, not a single response.


Decision guide: which response shape to capture for which job

If the job is… Capture Read
Cross-merchant price / product monitoring scraper.chatgpt with shopping: true products[] β†’ offers[]
Share-of-citation with rich source metadata scraper.gemini citations[] (website_name, highlights)
Source tracking plus media and follow-up intent scraper.perplexity web_results[], media_items[], related_prompt[]
Leanest answer-only capture scraper.gemini result_text

Pin the actor to the question. Because the transport is shared, running two or three of them on the same prompt and country is the same client with a different actor string β€” and gives you the answer from each platform's surface in one pass.


Conclusion: three shapes, one client

The transport is shared and the parsing is not: scraper.chatgpt, scraper.gemini, and scraper.perplexity answer to the same endpoint and envelope, but task_result diverges β€” different source keys, ChatGPT-only products, Perplexity-only media and follow-ups, Gemini's lean two-field shape. Pick the actor by the field you need, map task_result per actor, and treat every field as nullable. Run a fixed prompt set on a schedule with Universal Scraping API credits, and one client captures all three platforms' answers. The field names here are confirmed against live runs of each actor in the LLM Chat Scraper reference.


Ready to Build Your AI-Answer Data Pipeline?

Join our community to claim a free plan and connect with developers building AI-answer data pipelines: Discord Β· Telegram.

Sign up at app.scrapeless.com for free trial credits and point one client at ChatGPT, Gemini, and Perplexity to capture all three answer shapes on the queries your program tracks.


FAQ

Q: Do all three actors take the same input?
All three take prompt and country inside the input object. scraper.chatgpt adds an optional shopping flag and scraper.perplexity adds web_search; parameters always go inside input, never at the top level.

Q: Why are the citation fields named differently across the three?
Each actor parses its own platform's rendered answer, so the source data is shaped per platform β€” ChatGPT's content_references, Gemini's citations, and Perplexity's web_results carry different keys and different per-item fields. Read the field that actor returns rather than assuming a shared key.

Q: Can one client read all three without a rewrite?
For transport, yes β€” the same endpoint, x-api-token header, and { status, task_id, task_result } envelope. You swap the actor name and map the task_result keys per actor, because the inner field set differs.

Q: Which actor returns shopping or product data?
scraper.chatgpt with input.shopping: true populates a products[] array with per-merchant offers[]. Gemini and Perplexity do not return a shopping surface.

Q: Why does the same prompt return different fields on different runs?
Answers are generated per session and vary run to run; every field is nullable and an array can come back empty. Treat a persistently empty result as no answer for that query, and store task_id plus a capture timestamp so the series is the signal.

At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.

Most Popular Articles

Catalogue