read-only retest, August 2026AI Search · Methodology

Raw-stream hidden signals:what ChatGPT and Perplexity actually send

TL;DR: Behind the ChatGPT and Perplexity answer you see is a raw server-sent-event stream carrying dozens of undocumented fields our AI Hotel Landscape pipeline already stores but had never parsed. We walked that stream, by key presence rather than a hardcoded path, against our own captures — not a third party's — and re-tested six claimed hidden signals. Two held up (a 17-head Perplexity intent classifier, confirmed 69/69; a ChatGPT citation-competitor field, real but weaker than advertised), and three came back as clean, structural zeros: no brand priors in ChatGPT's “thoughts,” no measurable model escalation, and no Perplexity trust tiers anywhere in 519 checked records.

NS
Nicolas Sitter
Published August 2026 · read-only retest, August 2026
141
ChatGPT citation-competitor groups (77% of captures)
0/146
ChatGPT captures with brand priors in "thoughts"
69/69
Perplexity captures with a live 17-head classifier
0/519
Perplexity records with a trust-tier block
Read the Report

Executive Summary

We had our own data. We had never actually parsed it.

Bright Data's capture pipeline stores the full raw server-sent-event (SSE) stream from ChatGPT and Perplexity on every hotel prompt in the AI Hotel Landscape corpus — but until this retest, nobody had walked that field for anything beyond the parsed answer text. It is dozens of undocumented keys deep: classifier scores, retrieval-tier tags, citation-competition graphs, model routing metadata. The AEO knowledge base had flagged six specific claims about what lives inside that stream, most sourced from a different capture surface (a live-browser Chrome extension) than the one that actually feeds our production data. This retest re-ran all six against our own Bright Data captures — a read-only walk of public.fanout_captures, no third-party dataset involved.

The result is a genuine mixed verdict, not a clean win: one signal (Perplexity's intent classifier) is exactly as documented, one (ChatGPT's citation-competitor field) is real but weaker than the KB entry implied, and three — ChatGPT narrating brand priors, ChatGPT's model escalation, and Perplexity's trust tiers — came back as clean, reproducible zeros in this pipeline and this query set today. We report the zeros as prominently as the hits; that is the point of re-testing.

Read the negative results as scoped, not universal. A zero in our data means the signal did not appear in our specific capture pipeline and query library — a narrow set of single-turn, simple hotel prompts fired through Bright Data's SSE tee. It does not prove the phenomenon can never occur on a different client, a richer multi-turn conversation, or a paid-tier account. Every refuted finding below says exactly what would change that verdict.

Section 1

What held up

Two of six signals survived contact with real data — one confirmed exactly as claimed, one real but weaker than the source implied.

Perplexity's 17-head intent classifier (confirmed, 69/69)

Every parseable Perplexity snapshot carries a populated classifier_results.mhe_predictions_full block — a router scorecard of 17 named intent heads (skip_search, places_search_intent, shopping_intent, nav_intent, comet_nav_widget_combined_target, and 12 others), each carrying a probability and threshold. On a query for “boutique hotel with good coffee,” the panel fired places_search_intent at probability 1.0 (threshold 0.85) and comet_nav_widget_combined_target at 0.97 (threshold 0.5), against a shopping_intent of 0.11 (threshold 0.7) — for a query that never explicitly asked for navigation or shopping. Two heads, skip_search and personal_search, deviate slightly: they carry only a boolean, no probability or threshold, in every example checked.

This is the one signal that arrived exactly as documented, in every single parseable record. The caveat is availability, not correctness: it's only testable in the Dec 2025–Feb 2026 window, because that's the only period where Bright Data's Perplexity captures still carry the inner response_raw field this whole retest depends on (see Section 3). “Confirmed” here means confirmed for the window where it's observable, not confirmed for current, live data.

ChatGPT's winner-vs-runner-up citations (partially confirmed)

A supporting_websites structure appears in 112 of 146 (77%) recent ChatGPT hotel captures, with 141 winner/runner-up groups total — each pairing the citation ChatGPT actually used against one or more competitors it considered. Manually reading 10 of those pairs, roughly 7 in 10 are genuine same-claim competitors — e.g. Bangkok's winner (“The 10 best luxury hotels in Bangkok in 2026 | Latitude”) against a runner-up making the identical claim (“The Best Luxury Hotels in Bangkok for 2026 · La Revue des Hôtels”) — while roughly 3 in 10 are only topically adjacent, like a curated Beijing top-10 list paired against a Reddit thread asking for help choosing between four hotels.

Why “partially,” not “confirmed”: in every single inspected pair — and on spot checks across the wider 141-group set — the snippet field on both winner and runner-up nodes is an empty string. Bright Data's parse never populates it for these citation nodes. That means the “surrounding claim” comparison this signal implies reduces entirely to title-string similarity; there is no snippet text to confirm sentence-level competition. This is itself worth fixing before supporting_websites becomes a metric — title similarity alone is a much weaker signal than a same-sentence claim match.

Perplexity's mode/model fields (partially confirmed — real fields, no escalation observed)

search_mode, user_selected_model and display_model all exist exactly where claimed. But across all 69 parseable records, search_mode was null every time (never STUDY or RESEARCH), and user_selected_model and display_model were identical (“turbo” / “turbo”) with zero divergences — including on hotel prompts phrased conversationally enough that an escalation would be plausible if the account/config ever triggered one. The scraping setup's consistently present _extras.pro_search_mode: “auto” hints this account tier may simply never escalate; a larger or paid-tier sample would be needed to say more.

Section 2

What didn't

Three claimed signals came back as clean, reproducible zeros — not “rare,” genuinely absent given how each is currently defined and how our pipeline captures data. We report them as negative results rather than quietly dropping them.

ChatGPT never narrates brand priors in “thoughts” (refuted, 0/146). thoughts blocks are present in all 146 parseable records, but every one of the 16 distinct thought strings observed is boilerplate — “Searching 10 websites” (28×), “Searching 11 websites” (23×), down to a single “Searching www.cntraveler.com” (a bare domain, not a brand mention). thoughts.content is always an empty string; no capitalized multi-word proper-noun candidate — no hotel brand, chain, or destination-specific reasoning — appears anywhere in the stream, before or after the first search event.

Scope of the refutation: this used our own Bright Data SSE-tee capture on simple, single-turn “best/cheap/luxury hotels in [city]” prompts — not the live-browser capture the original claim was sourced from. It's plausible the tee only surfaces the UI-facing summary type of thoughts block, or that more complex, comparative, multi-turn prompts would surface narrated reasoning these queries never trigger. This refutes the signal as it manifests in our capture pipeline and query set today — it is not a claim that ChatGPT never narrates priors under any circumstances.
ChatGPT's model escalation is structurally unmeasurable right now (refuted, 0/146 qualify). default_model_slug reads “auto” in 100% of records — never a concrete model name to compare against. The resolved model underneath does vary (gpt-5-6 on 130 records / 89%, gpt-5-5-mini on 16 / 11%), but that's normal Auto routing, not escalation — the metric's own definition requires a concrete requested model, so the qualifying denominator is 0/146 by construction. This exactly reconfirms a caveat already written into our own pipeline code: it isn't a new finding, it's a clean re-confirmation that this framing is unmeasurable unless the capture trigger is changed to request a concrete model.
Perplexity exposes no trust-tier block, anywhere (refuted, 0 of 519 checked). No trust:{level,name,description} structure exists in 69 fully-parsed snapshots or in 450 additional records substring-scanned for the literal string "trust" — 300 spread across Dec 2025–Aug 2026, plus 150 from the single most recent capture day. The domain-scope field that does exist in the still-populated window is a bare slug, web_results[].meta_data.citation_domain_name (e.g. “hotelparisbastille”), nothing close to a {level, name, description} trust object. One record inspected in depth (583 KB of inner SSE text, 140 data: lines) had zero trust keys anywhere.

This one comes with the biggest confound of the retest — see Section 3. The most likely explanation isn't that trust tiers were fabricated; it's that they live on a different capture surface entirely.
Section 3

The finding underneath the findings: the substrate is vanishing

The single biggest result of this retest is a data-availability one, not a signal-semantics one — and it dominates every Perplexity verdict above.

Bright Data's Perplexity dataset feeding fanout_captures stopped reliably including a usable inner response_raw SSE string well before this retest's query window: intermittent from around February 2026 (a same-day mix of populated and empty rows), consistently empty by roughly April 2026, and by August 2026 the response_raw key — along with answer_html, answer_text and source_html — is gone from the payload schema entirely, replaced by a new links_attached key. This is a scraper/schema change on Bright Data's side, unrelated to fanout_captures' own 30-day retention purge on ChatGPT raw payloads — a second, separate reason the same field can be missing depending on the engine.

Net effect: every structural (parsed) Perplexity check in this retest is drawn only from the Dec 2025–Feb 2026 window, because that's the only period where the substrate exists in this table at all — even though non-null raw_response rows exist all the way through August 2026 (they are simply missing the useful inner text). We could not structurally test a single post-Feb-2026 Perplexity record for any of these three signals, even with a much larger sample.

Availability of the field this entire Perplexity retest depends on, by capture window.
WindowPerplexity response_rawWhat it means for this retest
Dec 2025 – ~Feb 2026Reliably populatedThe only window where trust_tiers, router_scorecard and mode_escalation could be structurally parsed at all
~Feb 2026IntermittentSame-day mix of populated and empty rows — transition period
~Apr 2026 onwardConsistently emptyNon-null response_raw rows exist, but the inner SSE text is missing
Aug 2026 (current)Key removed entirelyresponse_raw / answer_html / answer_text / source_html gone; replaced by links_attached
The KB entry's own “confirmed” evidence for trust tiers points to a run from a different capture pipeline — a live-browser Chrome extension, not the Bright Data dataset scraper that feeds this table. The two surfaces plausibly expose different internal Perplexity fields for the same product. That fully explains a real-but-elsewhere signal without anyone having fabricated it — and it's a reminder to always name the capture surface, not just the platform, when citing a raw-stream finding.
Section 4

Signal tracker

All six signals, one table. Once public_dashboard.pd_weekly_raw_stream_signals ships, this table re-runs every week from live capture data and the rows below update automatically; until then it renders the frozen counts from this retest — read-only retest, August 2026.

EngineSignalVerdictOccurrencesSample checked
ChatGPT
supporting_websites (winner vs. runner-up citations)
Real and common, but weaker than advertised: every inspected snippet field is empty, so the "same claim" judgment reduces to title-only comparison — about 7 in 10 manually-read pairs genuinely compete, 3 in 10 are only topically adjacent.
Partially confirmed141 groups112/146 records (77%)
ChatGPT
priors (brand names in thoughts before search)
100% of observed thoughts text (16 distinct strings) is boilerplate progress messages ("Searching N websites") — zero brand, chain, or destination-specific reasoning in any record.
Refuted0 occurrences146/146 records
ChatGPT
model_escalation (default_model_slug vs. resolved)
default_model_slug is "auto" on every single record — the escalation metric requires a concrete requested model to compare against, so it cannot fire by construction under the current trigger config.
Refuted0/146 qualify146/146 records
Perplexity
trust_tiers (domain trust:{level,name,description})
Zero trust blocks anywhere — 69 fully-parsed snapshots plus 450 substring-scanned records spanning Dec 2025–Aug 2026. The field that does exist is a bare domain slug, not a trust tier.
Refuted0 occurrences519 records checked
Perplexity
router_scorecard (classifier_results.mhe_predictions_full)
Present and non-empty in every parseable record, exposing the same 17 named intent heads every time — probability/threshold/fired triples exactly as claimed.
Confirmed69/69 records69 parseable snapshots
Perplexity
mode_escalation (search_mode / model swap)
The fields are real, but search_mode was null in 100% of records (never STUDY/RESEARCH) and user_selected_model always matched display_model — no escalation observed in this sample.
Partially confirmed0 escalations69 records

Frozen snapshot (read-only retest, August 2026) — the live weekly view is drafted but not yet deployed; see Methodology.

Methodology

Source. This is a read-only re-test of open questions from our AEO knowledge base, run against ai-scrapers' own public.fanout_captures table — the same corpus behind the AI Hotel Landscape. Every signal in this article was mined from our own hotel-search captures, not a third party's dataset.

Shape. fanout_captures.raw_response is a JSON-deserialized dict whose response_raw field is (when present) a JSON string containing a list of {event, data} server-sent-event frames. data is itself a JSON-patch-shaped tree (p/o/v/c keys at points) whose values are where fields like supporting_websites, thoughts, classifier_results and search_mode actually live.

Extraction, not path-matching. Because the JSON shape drifts release to release, we walk every dict/list depth-first and collect fields by key presence rather than a hardcoded path — a plain dict.values() traversal still reaches values nested inside the patch tree's v field, confirmed with exploratory probes before writing the main extraction script.

Sampling. ChatGPT: 300 recent captures with non-null raw_response, pulled in 40-row chunks (a single large query reliably hit Supabase statement timeouts and Cloudflare 521/522/525 errors on this project — confirmed empirically), deduped to 150 rows across 150 distinct query_ids, 146 of which parsed cleanly. Perplexity: 150 rows across 101 distinct query IDs (100 oldest-first from Dec 25, 2025; 50 newest-first through Aug 10, 2026), pulled with a two-phase query (lightweight columns first to pick diverse IDs, then a small-batch fetch of the heavy raw_response column — 0.5–2 MB per row), of which 69 parsed into a full snapshot.

Live tracker (pending). A permanent extraction module, fanouts-automation/tasks/raw_signals.py, and a weekly aggregate, public_dashboard.pd_weekly_raw_stream_signals (built via public.rebuild_raw_stream_signals), are drafted to keep the Section 4 table live going forward. The migration is not yet applied — it is pending manual review and deploy — so today's table renders the frozen counts from this retest. Once the migration ships, data lands after the next scheduled refresh and the table above starts updating automatically.

Access. Read-only throughout: only SELECT queries against Supabase, no writes, no migrations applied, no backfills executed. All working scripts and fixtures stayed in a scratch directory and were never committed.

FAQ

Undocumented fields inside the raw server-sent-event stream an AI engine sends while assembling an answer — classifier scores, retrieval-tier tags, citation-competition graphs, model-routing metadata — that never appear in the rendered chat UI but are captured by a scraping pipeline that logs the full SSE payload. This article mines six specific claimed signals out of our own ChatGPT and Perplexity captures to see which ones actually exist.

Explore the data behind this page

Every number here comes from a read-only walk of our own AI Hotel Landscape captures — CC-BY-4.0.