Use case Answer-engine research

How to capture ChatGPT
fan-out queries

When ChatGPT searches the web, it rewrites your question into a handful of narrower queries and searches for those. Here is how to see them, with code and with Moose.

Watch Moose do it Show me the code
Chat Workflows
Hi, Moosehttps://himoose.com
New chat
Home Inbox Context Visibility Workflows Audio Chats Artifact Library Connections
Recents
Sam SamPremium
Capture ChatGPT fan-out qu… New chat Share
Capture ChatGPT fan-out queries
What prompt do you want ChatGPT fan-out queries for?
best AI security platforms for SMB
Capturing ChatGPT fan-out queries…
ChatGPT fan-out queries

OpenAI exposed 12 distinct ChatGPT fan-out queries for this prompt.

Prompt

best AI security platforms for SMB

Fan-out queries
  • best AI security platforms SMB 2026 endpoint email cloud managed detection small business
  • Gartner market guide SMB cybersecurity platforms AI 2026
  • small business cybersecurity platform AI features official pricing MDR email security official
  • site:microsoft.com Defender for Business official SMB endpoint protection
  • site:huntress.com managed EDR small business official
  • site:sentinelone.com Singularity Core small business official
  • site:sophos.com Intercept X small business official
  • site:crowdstrike.com Falcon Go small business official pricing
  • site:bitdefender.com GravityZone Small Business Security official pricing
  • site:todyl.com managed security platform SMB official
  • best MDR for small business 2026 independent comparison review
  • SMB email security AI phishing protection official pricing 2026
Share a URL, a draft document, or run an AEO audit…
GPT-5.6 Luna Send
Hi, Moose 0.3.281 Beta Need help?
A recreation of a real run. One question, twelve queries, about eleven seconds.
The definition

What is a ChatGPT fan-out query?

A fan-out query is one of the several search queries ChatGPT writes for itself when it decides to search the web. You type one question. Before it answers, the model rewrites your question into a set of narrower, more specific searches, runs all of them, reads what comes back, and synthesises a single answer.

The searches it wrote are the fan-out queries. They are not what you typed and they do not appear in the answer. They are the queries your pages need to show up for.

What the user typed
best AI security platforms for SMB
1 prompt
What ChatGPT searched for
best AI security platforms SMB 2026 endpoint email cloud managed detection small business
Gartner market guide SMB cybersecurity platforms AI 2026
small business cybersecurity platform AI features official pricing MDR email security official
site:microsoft.com Defender for Business official SMB endpoint protection
site:huntress.com managed EDR small business official
site:sentinelone.com Singularity Core small business official
12 queries, 6 shown
Without Moose

How to capture fan-out queries with code

There is no public API for this. The only way to see the queries yourself is to drive a logged-in browser and read the search tool calls out of the response stream. Here is a working starting point, and the list of what will break.

playwright
# fanout.py · read ChatGPT's own search calls off the wire
import asyncio, json
from playwright.async_api import async_playwright

PROMPT = "best AI security platforms for SMB"
found  = set()

def harvest(evt):
    msg = evt.get("message") or {}
    # the fan-out queries ride inside the search tool call
    if msg.get("author", {}).get("name") != "web":
        return
    for part in msg.get("content", {}).get("parts", []):
        if isinstance(part, str) and part.startswith('search("'):
            found.add(part[8:-2])

async def main():
    async with async_playwright() as pw:
        # a real logged-in profile. clean headless gets challenged.
        ctx  = await pw.chromium.launch_persistent_context(
            "~/.chatgpt-profile", headless=False)
        page = await ctx.new_page()

        async def on_response(res):
            if "/backend-api/conversation" not in res.url:
                return
            body = await res.text()          # SSE, not JSON
            for line in body.splitlines():
                if line.startswith("data: "):
                    try: harvest(json.loads(line[6:]))
                    except ValueError: pass

        page.on("response", on_response)
        await page.goto("https://chatgpt.com/?search=1")
        await page.fill("#prompt-textarea", PROMPT)
        await page.keyboard.press("Enter")
        await page.wait_for_timeout(45_000)  # no "done" signal
        print(json.dumps(sorted(found), indent=2))

asyncio.run(main())
// fanout.mjs · same idea, node + playwright
import { chromium } from 'playwright';

const PROMPT = 'best AI security platforms for SMB';
const found  = new Set();

// headless gets challenged, so this opens a real window
const ctx  = await chromium.launchPersistentContext(
  './chatgpt-profile', { headless: false });
const page = await ctx.newPage();

page.on('response', async (res) => {
  if (!res.url().includes('/backend-api/conversation')) return;
  const body = await res.text().catch(() => '');  // SSE
  for (const line of body.split('\n')) {
    if (!line.startsWith('data: ')) continue;
    let evt;
    try { evt = JSON.parse(line.slice(6)); } catch { continue; }
    const msg = evt?.message;
    if (msg?.author?.name !== 'web') continue;
    for (const p of msg?.content?.parts ?? []) {
      if (typeof p === 'string' && p.startsWith('search("'))
        found.add(p.slice(8, -2));
    }
  }
});

await page.goto('https://chatgpt.com/?search=1');
await page.fill('#prompt-textarea', PROMPT);
await page.keyboard.press('Enter');
await page.waitForTimeout(45_000);   // no "done" signal
console.log([...found].sort());
What breaks
It needs a logged-in window

A clean headless context gets challenged, so you end up running a visible Chromium with your own session in it.

The payload is undocumented

The author name, the parts array, the search("...") wrapper: none of it is a contract. It has changed before and will change again.

Search does not always fire

If the model answers from memory there is no fan-out at all, and nothing tells you that is what happened. You get an empty set.

One prompt, one moment

No schedule, no deduplication across runs, no comparison with last week. Capturing once is easy. Capturing repeatedly and noticing what moved is the work.

Read the terms first

Automating a logged-in ChatGPT session is a decision about your own account. Read the terms before you do it.

With Moose

With Moose, you ask in chat

Same capture, same source, without the browser work. Moose keeps every run, so you can compare this week's query set against last week's.

01
Open a chat and ask

Type "capture ChatGPT fan-out queries". No workflow to configure.

02
Give it the prompt

Any question a buyer would type. Moose runs it and captures the search calls that come back.

03
Keep the list

The queries land in your library, exportable, and ready to feed a brief or a coverage check.

Fan-out capture is on the managed plan only

This one is not available on BYOK plans. The capture has to come straight from OpenAI, and routed access through OpenRouter does not expose ChatGPT's internal search queries. On a key-based plan, everything else in Moose still works, including the instant visibility check across five AI search engines. This one feature does not.

What to do with them

What to do with the queries

The real query set
Twelve searches behind one question

Those twelve searches decide which pages get pulled and read, so they matter more than the exact phrasing your buyer typed.

The trust list
A site: query names a brand the model trusts

When ChatGPT wants an official answer it goes to specific domains. If yours is not among them for your own category, that is the gap.

The brief
One page that answers all twelve

Pricing, comparison, official spec, independent review: the fan-out tells you which of those the engine went looking for, so you know what one page has to cover.

The trend
Track it over time

The query set changes as the model and the index change. New queries appearing is an early read on where the category is moving.

Questions people ask

Are fan-out queries the same as the citations ChatGPT shows?

No. Citations are the pages the engine used. Fan-out queries are the searches that found them.

Do the queries change if I run the same prompt again?

Usually yes, a little. The core queries are stable and the long tail moves. Run the same prompt weekly and watch which queries appear and disappear.

Will optimising for fan-out queries get me cited?

No one can promise that. The queries show what the model went looking for. If none of your pages answer those searches, they will not be read. If they do, they can be.

Do other answer engines fan out too?

Most of them do. Perplexity, Google AI Mode and Gemini all break a question into searches before answering. What differs is how much of it they show you. Google is the other one worth capturing, and it works differently enough to have its own page.

More things to ask Moose

All use cases
Managed plan feature

See the searches behind
the answer.

Download Hi, Moose, open a chat, and ask. Fan-out capture needs the managed plan. The app is free to install and the visibility checks are free to run.