ChatGPT Retrieval Dissector
Paste the SSE stream of a ChatGPT conversation request and see every web.run retrieval call in order, the queries it disclosed, the results it forwarded, the sources panel, the citations and the model's thoughts. Every item links back to its line in the stream.
Open the browser's developer tools (Network tab) while ChatGPT answers, find the POST …/backend-api/f/conversation
request and copy its response body — the event: delta / data: {...} stream. Paste it below.
Nothing leaves the browser. The text is parsed in a Web Worker on this page. There is no upload, no server and no external request. Session tokens and your custom instructions are masked before anything is shown.
Disclaimer. I made an effort to keep this tool private: it runs entirely in your browser, nothing is sent to or stored on a server, and I don't want your data.
Still, pasting your browser's session data into any website is generally a bad idea. I built this tool for myself. If you use it, you do so at your own risk.
Checked against the wire queries: exact, near (case, quotes, spaces) or unverified; unverified ones are attributed to the calls that disclosed nothing.
Report
Raw stream
read-only, masked, verbatim otherwise · click any L-number above to jump hereHow it reads the stream
- Each
data:line is a full message ({"v":{"message":…}}) or a patch. Patches are applied to the message whose channel numbercmatches; patches withoutcgo to the most recently added message. A bare{"v":"text"}repeats the previous text append on that message (the answer streams this way), so answer text and the citations inside it are complete. - A retrieval call is an assistant message with recipient
web.run. Calls are ordered by theparent_idchain, not by file position orcreate_time. - A call whose message carries
inline_cot_expandable_contentran inside the chain of thought (the "Searched N websites" box); its queries are hidden by design. A call without it is a visible call, and the UI shows its queries. The report labels every call and every citation with its block. - Disclosed queries come from the
web.runtool message that carriesmetadata.search_model_queries.queriesand points at the call throughparent_id. A visible call without one is flagged. - Results are
metadata.search_result_groups[].entries[]. Groups accumulate, so a call owns the entries whoseturn_indexfirst appears under it. - The content of
inline_cot_expandable_contentis the accumulating "Searched N websites" panel. It is kept as its own layer and never counted as tool results, so the report can show which forwarded entries the panel never surfaced, and which panel entries no tool message forwarded. Each call also lists the metadata keys of its call, query and result messages (reasoning titles, tool icons, group counts, thread ids), with boilerplate request keys hidden. - The sources panel is the set of groups with small
turn_index(0, 1, …) on the final messages. Panel turn k is the k-th search call in chain order (view-only calls skipped; a search call that forwarded nothing still takes a slot), verified by URL overlap with what the tool message forwarded, with a fallback match by overlap when the ordinal fails. Merging both byref_indexgives a lower bound on the pool the model received: which slots only the tool message had, which only the panel had, which are still missing, and the pool size (max ref_index + 1). Neither slice is complete; the tool message tends to keep news hits and drop the tail, the panel drops news and keeps more of the tail, and wholesite:sub-queries can vanish from one of them. A disclosed query with asite:operator is flagged when no merged entry is on that site. - What the reader never saw. ChatGPT shows retrieved sources in two places: the thinking panel ("Searched N websites", from
inline_cot_expandable_content) and the Sources footnote under the answer (from the small-turn_index panel groups); inline citations are a third, narrower path. The tool message is not a surface. Every reconstructed pool slot is classified by which of these showed it. Slots in none of them, and index gaps that no copy carries, are retrieval the model had and the reader never could see. The section at the top of the report lists them with URLs where the stream has one, and offers a CSV. - Citations are
<Cite refs={["turn{T}{type}{N}"]}/>tags in the answer text pluscontent_references[].refs, resolved by (turn_index, ref_type, ref_index). Message fragments that were merged into a final message are not double-counted. - Bad JSON lines, a truncated last line and missing fields become parse warnings; the report is still produced.