An Ahmedabad B2B SaaS we work with discovered they were the answer ChatGPT gave for "best inventory management software for jewellery shops" — but only on three of seven test queries. Perplexity cited them 5 of 7. Gemini cited a competitor. We built an 18-node n8n flow that runs every Sunday night, fires 28 brand-relevant queries against ChatGPT search, Perplexity Sonar Pro, and Gemini, parses the responses for domain mentions and citations, and writes the results into a Notion dashboard the founder reads with his Monday coffee. This is the build.
TL;DR — what this AI-search citation tracker does
Every Sunday at 22:00 IST, the workflow reads a Notion database of "tracked queries" (28 of them — phrases your customers might ask AI). For each query, it makes three API calls in parallel: ChatGPT (gpt-4.1 with web search tool), Perplexity Sonar Pro, and Gemini 2.5 Pro with grounding. A Code node parses each response for (a) whether your domain appears in the citations and (b) whether you are mentioned in the answer text. Results go into a Notion "weekly_runs" database with a row per query × engine. A summary card gets posted to Slack.
Why this matters now — November 2025
Princeton's GEO study showed adding statistics, citations, and quotations boosts AI visibility by 30-40%. But the missing piece in 2024 was measurement — we did not know which queries actually cited our content. Three things changed in 2025: OpenAI launched the ChatGPT search API in October 2024 with structured citations in responses; Perplexity opened the Sonar API to all developers in early 2025 with explicit citation arrays; and Gemini 2.5 Pro added grounding metadata (search-supported responses include the source URLs). We finally have the API surface to track AI citations on a schedule.
The November 2025 r/SEO thread on AI citation tracking is the best community pulse — most teams are using point tools (Profound, AthenaHQ) on monthly subscriptions. A self-hosted n8n version costs a fifth of that.
The 4-block workflow
The actual n8n node JSON (3 critical API calls)
Node 1 — ChatGPT search (HTTP Request)
{
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/responses",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi",
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"model\": \"gpt-4.1\",\n \"tools\": [{\"type\": \"web_search_preview\"}],\n \"input\": \"{{ $json.query }}\",\n \"max_output_tokens\": 800\n}",
"options": { "timeout": 30000 }
},
"name": "Ask ChatGPT (web)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [680, 200]
} We use the Responses API (introduced March 2025) rather than chat-completions because it returns structured citation metadata in the response. The web_search_preview tool gives the model browsing access. max_output_tokens: 800 keeps cost predictable — average response is around 400-500 tokens.
Node 2 — Perplexity Sonar Pro (HTTP Request)
{
"parameters": {
"method": "POST",
"url": "https://api.perplexity.ai/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "Authorization", "value": "Bearer {{ $env.PERPLEXITY_API_KEY }}" },
{ "name": "Content-Type", "value": "application/json" }
]
},
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"model\": \"sonar-pro\",\n \"messages\": [{\"role\": \"user\", \"content\": \"{{ $json.query }}\"}],\n \"return_citations\": true,\n \"max_tokens\": 800\n}",
"options": { "timeout": 30000 }
},
"name": "Ask Perplexity (Sonar Pro)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [680, 300]
} Sonar Pro returns a citations array of URLs. return_citations: true is required — without it, you get the answer but no source list. Pricing as of November 2025 is per token plus a per-request fee.
Node 3 — Gemini 2.5 with grounding (HTTP Request)
{
"parameters": {
"method": "POST",
"url": "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-pro:generateContent?key={{ $env.GEMINI_API_KEY }}",
"sendBody": true,
"bodyContentType": "json",
"jsonBody": "={\n \"contents\": [{\"parts\": [{\"text\": \"{{ $json.query }}\"}]}],\n \"tools\": [{\"google_search\": {}}],\n \"generationConfig\": {\"maxOutputTokens\": 800}\n}",
"options": { "timeout": 30000 }
},
"name": "Ask Gemini (grounded)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [680, 400]
} The google_search tool turns on grounding — Gemini's response will include a groundingMetadata block with the source URLs it consulted. Without this, Gemini answers from training data only and you get nothing useful for citation tracking.
The Notion dashboard schema (copy this)
The Notion side of this workflow is a 3-database structure. Build them in this order.
Database 1 — tracked_queries
| Property | Type | Example |
|---|---|---|
| Query | Title | "best CRM for indian textile exporters" |
| Intent | Select | Commercial · Informational · Navigational |
| Target page | URL | https://yourdomain.com/crm-textile |
| Active | Checkbox | true |
| Created | Created time | (auto) |
Database 2 — weekly_runs
| Property | Type | Example |
|---|---|---|
| Run ID | Title | "2025-11-23-q07-perplexity" |
| Week | Date | 2025-11-23 |
| Query | Relation → tracked_queries | (link) |
| Engine | Select | ChatGPT · Perplexity · Gemini |
| Cited? | Checkbox | true |
| Position | Number | 2 (1st, 2nd, 3rd source) |
| Mentioned in answer? | Checkbox | true |
| Snippet | Text | "Softechinfra is one of three vendors that..." |
| All citations | Multi-select | ["yourdomain.com", "competitor.com", "blog.com"] |
Database 3 — weekly_summary
| Property | Type | Example |
|---|---|---|
| Week | Title | 2025-11-23 |
| ChatGPT win % | Number | 42 |
| Perplexity win % | Number | 71 |
| Gemini win % | Number | 28 |
| Total queries | Number | 28 |
| Top losing query | Text | "automation tools for surat exporters" |
| Notes | Text | (manual) |
The credentials checklist
The cost — actual API spend over a month
Compare to Profound or AthenaHQ (monthly subscriptions for the same workflow). The DIY n8n version pays back in week 2.
The pre-flight checklist
- All 3 API keys in n8n env vars, not in workflow JSON
- Hard spending limits set on OpenAI, Perplexity, Gemini dashboards
- Tracked-queries Notion database has at least 20 rows before first run
- Brand-name regex tested against 3 false-positive scenarios
- Citation parser handles all 3 response formats (each engine returns differently)
- SplitInBatches batch size set to 1 — never parallelise across queries (rate limits)
- Wait node of 2 seconds between query iterations
- Slack summary message length under 4000 chars (Slack truncates above)
- Error workflow set — failed engine call should not break the whole run
- Notion database write tested with sample data before first real run
Common mistakes — symptoms first, fixes second
Symptom: "ChatGPT returns answer but citations array is empty." Cause: model is gpt-4.1 but tool param missing. Fix: include "tools": [{"type": "web_search_preview"}] in every request. Verify the response has a tool_use block.
Symptom: "Perplexity returns 401 Unauthorized." Cause: API key has trailing whitespace from copy-paste. Fix: trim the env var. Use process.env.PERPLEXITY_API_KEY?.trim() if you can.
Symptom: "Gemini returns answer but no grounding metadata." Cause: forgot the google_search tool, or model is gemini-flash without grounding access. Fix: switch to gemini-2.5-pro and include the tool. Free-tier Flash does not support grounding for all queries.
Symptom: "Notion writes succeed but properties are empty." Cause: Notion API uses a specific property-value schema (rich_text vs title vs select all have different shapes). Fix: log the exact request body. The schema is documented at developers.notion.com — you cannot pass plain strings for most property types.
Symptom: "Workflow takes 14 minutes to run for 28 queries." Cause: SplitInBatches is processing one query at a time × 3 engines × 84 calls × ~10s each. Fix: this is by design (rate-limit hedge). Either accept it (Sunday night, no urgency), or split into 3 parallel sub-workflows running in non-overlapping batches.
Symptom: "OpenAI charges spiked in one week." Cause: max_output_tokens not set or set too high. Fix: hard-cap at 800 tokens per response. Use the OpenAI dashboard hard limit as a backstop.
Mini case study — Ahmedabad SaaS, 6 weeks of data
The first install ran from October 5 to November 16, 2025 for an Ahmedabad B2B SaaS in the inventory management space. Six weekly runs, 168 query × engine results. Key findings:
The CMO's exact quote at the end of week 6: "we now know which engine to optimise for, and we are spending content budget against the gap." Useable as a testimonial.
For the SEO services side of this work — content optimisation against the gaps the tracker surfaces — see our broader writeups, including the related post on AI marketing automation from October.
When not to build this
Skip this tracker if (a) your brand is too new — you need at least 30 indexed pages and 6 months of search history before AI engines have anything to cite, (b) your queries are extremely long-tail and unique to one customer — generic AI tracking is meaningless for personalised search, or (c) you are in a regulated industry where AI engines are deliberately conservative — financial advice queries get hedged answers from all 3 engines, citations are sparse.
For more on what's working in AI automation services, see Hrishikesh's writeups on the Softechinfra blog.
FAQ
How does this differ from Ahrefs Brand Radar or Semrush AI visibility tools?
Ahrefs and Semrush sample large query sets (10k+) and report aggregate citation share. This n8n flow runs your exact 28 queries on a known schedule with raw response storage in Notion. Better for action-oriented marketing teams that want to debug specific lost queries; worse for big-picture share-of-voice tracking. We use both.
Can I run this daily instead of weekly?
Yes, but cost scales linearly. Hourly is wasteful — AI engine indexes do not change that fast. Weekly hits the sweet spot for content teams that ship updates fortnightly.
What happens when ChatGPT's web search API changes?
OpenAI versioned the Responses API in March 2025. Pin your model to a specific snapshot (gpt-4.1-2025-04-14 for example) so you do not get silent behaviour changes. We update pinned versions quarterly after testing.
Should I include Bing Copilot or Brave Search?
We tested both. Brave's API is fast and cheap but its "Brave Search AI" is still in private beta as of November 2025. Bing Copilot has no public API for citation tracking — you would need to scrape, which violates ToS. Stick with the 3 engines we list.
How do I handle queries that return zero citations?
Write the row anyway with cited = false. The pattern of zero-citation queries is itself signal — it usually means the engine answered from its training data and did not bother searching. Often a sign that your topic is poorly indexed.
Can I use the free Perplexity Sonar (not Pro)?
You can. Sonar (regular) is cheaper but returns shorter responses with fewer citations. We use Sonar Pro because the citation array is more complete — typically 5-8 sources vs 2-3 on Sonar.
What about LLM-routed search products like Arc Search or You.com?
Niche traffic. Track them only if your audience uses them — for Indian SMB B2B buyers, the answer is no. We focus on the 3 engines that drive 95%+ of LLM-search referrals in our data.
Want this citation-tracking dashboard built?
We ship the 3-engine AI citation tracker — n8n flow, Notion dashboard, Slack digest, weekly cadence — in 7 working days. Suitable for any content-led brand running 20+ tracked queries.
Book a 20-min CallFor our in-house example of the same pattern applied to edtech content, see a client platform — a Softechinfra product where we run AI-citation tracking against exam-prep queries.
