TED Contract Expiry Radar - Recompete Leads
Find EU public contracts approaching expiry from TED award notices: incumbent, buyer, value, end date and renewal options.
datagrit › Data › Google AI Overview Citation & Brand Tracker
DataTrack which sources and domains Google AI Overview cites for each search query, with brand mentions and organic rank in one row.
Google AI Overview Citation & Brand Tracker checks a list of Google search queries and tells you, for each one, whether Google shows an AI Overview, which sources it cites and in what order, whether your brand is named in the answer, and where your domain ranks in the organic results. Every query becomes one flat row you can export as JSON, CSV or Excel, call through the Apify API, or feed into n8n, Make and AI agents through MCP.
It is built for SEO and content teams, agencies and brand owners who want to measure visibility inside AI answers (often called AEO or GEO) instead of only in the ten blue links.
Each row contains the query, market, aiOverviewPresent, aiOverviewText, citationCount, citedDomains, citations, the tracked domain fields (trackedDomainCited, trackedDomainsCited, bestCitationPosition, trackedDomainOrganicRank), the brand fields (brandMentioned, brandsMentioned, brandMentionCount), organicResults, sourceUrl and scrapedAt. Tracking fields are null when you did not set domains or brands.
A status row has found: false, a reason (noResults or fetchFailed) and a message; it is not charged.
aiOverviewPresent: false means the results page Google returned for that request had no AI Overview; the row still carries the organic results. Google decides per request whether to show an AI Overview, so a query can flip between checks, which is why the Actor is meant to run on a schedule. An unreadable page is requested up to three times before it becomes a free fetchFailed row. The run message counts how many AI Overviews were found, how many had parsed citations and how many queries had organic results. If Google changes its page layout, the run fails with a message instead of delivering wrong rows: a page that carries citation records or the AI Overview disclaimer ("AI responses may include mistakes") but no AI Overview container is treated as unreadable, and a run that parses no organic results from any page stops with an error. Queries without an AI Overview (local, navigational and result queries often have none) and AI Overviews without source links are normal and never fail a run.
The Actor reads publicly visible search result pages without logging in and without bypassing access controls. You are responsible for using the data in line with applicable laws and the terms of the service. If you find an issue, open it in the Issues tab.
Every result is one flat record, so it drops straight into a spreadsheet, a database or a CRM.
| Field | Type | Description | Example |
|---|---|---|---|
query | string | The search query this row belongs to. | what is kubernetes |
gl | string | Country code of the Google market the query was checked in. | us |
hl | string | Interface language of the Google results page. | en |
found | boolean | False only on a status row, which is free and carries the reason in the reason and message fields. | true |
aiOverviewPresent | boolean | True when Google showed an AI Overview for the query, false when it did not. | true |
aiOverviewText | string | Plain text of the AI Overview with line breaks between paragraphs and list items. Null when there is no AI Overview. | Kubernetes is an open-source system for automating deployment, scaling and manag |
citationCount | integer | Number of distinct source pages cited by the AI Overview. | 7 |
citedDomains | array | Distinct domains cited by the AI Overview, in order of first appearance. | ["kubernetes.io","redhat.com"] |
citations | array | Cited source pages in the order Google lists them: position, URL, domain and site name. | [{"position":1,"url":"https://kubernetes.io/docs/concep |
trackedDomainCited | boolean | True when at least one of your tracked domains is cited in the AI Overview. Null when no domains were tracked. | true |
trackedDomainsCited | array | Which of your tracked domains are cited in the AI Overview. Null when no domains were tracked. | ["kubernetes.io"] |
bestCitationPosition | integer | Position of the first citation that belongs to a tracked domain. Null when none is cited or no domains were tracked. | 1 |
brandMentioned | boolean | True when at least one tracked brand name appears in the AI Overview text. Null when no brand names were tracked. | true |
brandsMentioned | array | Which tracked brand names appear in the AI Overview text. Null when no brand names were tracked. | ["Kubernetes"] |
brandMentionCount | integer | Total number of times tracked brand names appear in the AI Overview text. Null when no brand names were tracked. | 4 |
organicResultCount | integer | Number of organic results parsed from the first results page. | 9 |
trackedDomainOrganicRank | integer | Position of the first organic result that belongs to a tracked domain. Null when none ranks on the first page or no domains were tracked. | 2 |
organicResults | array | Organic results of the first page: position, title, domain and displayed URL. | [{"position":1,"title":"Kubernetes","domain&q |
reason | string | Only on a status row: noResults or fetchFailed. | fetchFailed |
message | string | Only on a status row: plain-language explanation of why the query produced no result row. | Google did not return a readable results page for this query after several attem |
sourceUrl | string | Google search URL the row was read from. | https://www.google.com/search?q=what+is+kubernetes&hl=en&gl=us |
scrapedAt | string | ISO 8601 timestamp of the run that produced the row. | 2026-10-08T08:00:00.000Z |
{
"query": "what is kubernetes",
"gl": "us",
"hl": "en",
"found": true,
"aiOverviewPresent": true,
"aiOverviewText": "Kubernetes is an open-source system for automating deployment, scaling and management of containerized applications.",
"citationCount": 7,
"citedDomains": [
"kubernetes.io",
"redhat.com"
],
"citations": [
{
"position": 1,
"url": "https://kubernetes.io/docs/concepts/overview/",
"domain": "kubernetes.io",
"site": "Kubernetes"
}
],
"trackedDomainCited": true,
"trackedDomainsCited": [
"kubernetes.io"
],
"bestCitationPosition": 1,
"brandMentioned": true,
"brandsMentioned": [
"Kubernetes"
],
"brandMentionCount": 4,
"organicResultCount": 9,
"trackedDomainOrganicRank": 2,
"organicResults": [
{
"position": 1,
"title": "Kubernetes",
"domain": "kubernetes.io",
"displayedUrl": "https://kubernetes.io"
}
],
"reason": "fetchFailed",
"message": "Google did not return a readable results page for this query after several attempts.",
"sourceUrl": "https://www.google.com/search?q=what+is+kubernetes&hl=en&gl=us",
"scrapedAt": "2026-10-08T08:00:00.000Z"
}
| Field | Name | Type | What it does |
|---|---|---|---|
queries required | Search queries | array | Google search queries to check. Each query is one Google results page and produces one row. Duplicates are removed. |
gl | Country (gl) | string | Two-letter country code of the Google market, for example us, gb, de or pl. Controls which results and which AI Overview Google serves. |
hl | Interface language (hl) | string | Language code of the Google results page, for example en, de, pl or pt-BR. The AI Overview is written in this language. |
trackedDomains | Domains to track | array | Your own domains or competitor domains, for example example.com. Subdomains match too. Rows then show whether the domain is cited in the AI Overview, at which citation position, and its organic rank. Leave empty to only list all citations. |
brandNames | Brand names to track | array | Brand or product names to look for in the AI Overview text, case-insensitive. Rows show whether each name is mentioned and how many times. |
maxItems | Maximum rows | integer | Stop after this many result rows in total across all queries. You are charged per result row, so this caps the cost of a run. |
Run the Actor and get the results in one request. Replace YOUR_APIFY_TOKEN with the token from your Apify account settings.
curl -X POST "https://api.apify.com/v2/acts/datagrit~google-ai-overview-citation-tracker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries":["how to lower blood pressure","what is kubernetes","best running shoes for flat feet","how does a heat pump work","is intermittent fasting safe","what causes inflation","how to learn python fast","symptoms of vitamin d deficiency","how to start a vegetable garden","what is a roth ira","how to remove a stripped screw","what is a good credit score"],"trackedDomains":["kubernetes.io","mayoclinic.org"],"brandNames":["Kubernetes"],"maxItems":14}'import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('datagrit/google-ai-overview-citation-tracker').call({
"queries": [
"how to lower blood pressure",
"what is kubernetes",
"best running shoes for flat feet",
"how does a heat pump work",
"is intermittent fasting safe",
"what causes inflation",
"how to learn python fast",
"symptoms of vitamin d deficiency",
"how to start a vegetable garden",
"what is a roth ira",
"how to remove a stripped screw",
"what is a good credit score"
],
"trackedDomains": [
"kubernetes.io",
"mayoclinic.org"
],
"brandNames": [
"Kubernetes"
],
"maxItems": 14
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length, items[0]);Install with npm i apify-client.
from apify_client import ApifyClient
import os
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("datagrit/google-ai-overview-citation-tracker").call(run_input={
"queries": [
"how to lower blood pressure",
"what is kubernetes",
"best running shoes for flat feet",
"how does a heat pump work",
"is intermittent fasting safe",
"what causes inflation",
"how to learn python fast",
"symptoms of vitamin d deficiency",
"how to start a vegetable garden",
"what is a roth ira",
"how to remove a stripped screw",
"what is a good credit score"
],
"trackedDomains": [
"kubernetes.io",
"mayoclinic.org"
],
"brandNames": [
"Kubernetes"
],
"maxItems": 14
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(len(items), items[0] if items else None)Install with pip install apify-client.
No. It reads the AI Overview shown on the regular results page.
Google personalises and varies AI Overviews, so a single check is a sample. Run the same list on a schedule and compare over time.
Up to 10,000 queries; runs read several queries in parallel.
Yes, use Apify schedules or call the Actor from your own workflow.
How to track which sources Google AI Overview cites for your queries — Check a list of Google queries for AI Overview citations, brand mentions and organic rank, per country, in Python or cURL and without a browser.
Find EU public contracts approaching expiry from TED award notices: incumbent, buyer, value, end date and renewal options.
UK public contracts ending soon with incumbent supplier, buyer, value and contact - recompete leads from Contracts Finder award notices.
French company lead lists from Sirene screened by net result and revenue, with net margin, size, matching establishment and optional directors.
Named officers, directors and key employees with pay, hours and titles from IRS e-filed 990, 990-EZ and 990-PF returns.