curl --request POST \
--url https://api.seomator.com/v1/projects/{id}/reports/brands \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"startDate": "2023-12-25",
"endDate": "2023-12-25",
"filters": {
"branded": "non_branded"
},
"dimensions": [],
"compare": true
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
startDate: '2023-12-25',
endDate: '2023-12-25',
filters: {branded: 'non_branded'},
dimensions: [],
compare: true
})
};
fetch('https://api.seomator.com/v1/projects/{id}/reports/brands', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.seomator.com/v1/projects/{id}/reports/brands"
payload = {
"startDate": "2023-12-25",
"endDate": "2023-12-25",
"filters": { "branded": "non_branded" },
"dimensions": [],
"compare": True
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"period": {
"start": "<string>",
"end": "<string>"
},
"previous": {
"start": "<string>",
"end": "<string>"
},
"coverage": {
"current": {
"planned": 123,
"collected": 123,
"analyzed": 123
},
"previous": {
"planned": 123,
"collected": 123,
"analyzed": 123
}
},
"rows": [
{
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123,
"period": "current",
"brandId": "<string>",
"brandName": "<string>",
"brandRole": "own",
"date": "<string>",
"week": "<string>",
"assistant": "<string>",
"topicId": "<string>",
"promptId": "<string>"
}
],
"comparison": {
"status": "comparable",
"matchedPairs": 123,
"excludedAssistants": [
"<string>"
],
"brands": [
{
"brandId": "<string>",
"current": {
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123
},
"previous": {
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123
}
}
]
}
}{
"error": {
"code": "bad_request",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "bad_request",
"message": "<string>",
"requestId": "<string>"
}
}Brand visibility in AI answers, with counts and the previous period
Every row returns numerators and their denominator (answers), so you can re-aggregate.
Visibility = named / answers. Named first = first / answers. Average position = positionSum / positionCount. Retrieved = retrieved / answers. Cited = cited / citable. Linked = linked / answers. Share of voice = mentions / the sum of mentions of every tracked brand in the same group (same period and dimensions); mentions counts every time the brand is named.
answers is per brand: an answer whose mention of that brand is pending (an ambiguous name waiting for verification) or unverified (verification failed) is not counted for that brand, in answers or named, so brands can have different denominators. recounting counts answers not yet re-scanned after a brand change; they are not in answers either.
Retrieved: one of the brand’s pages is in the assistant’s source list (it read the page). Cited: the answer cites one of the brand’s pages inline. Linked: the answer text links to one of the brand’s pages. One answer can count in all three.
Gemini shows no inline citations, so cited never counts a Gemini answer and its denominator is citable: the answers from assistants that show inline citations (ChatGPT, Google AI Mode).
Dates are UTC days, inclusive. The default is the last 7 complete UTC days, ending yesterday; pass endDate for today, which is still being collected (see coverage). Non-branded prompts only, unless filters.branded says otherwise.
comparison compares only prompt × assistant pairs answered in both periods. Show a change only when its status is comparable.
Breaking down by prompt together with date or week needs filters.promptIds with 1 to 20 prompts.
curl --request POST \
--url https://api.seomator.com/v1/projects/{id}/reports/brands \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"startDate": "2023-12-25",
"endDate": "2023-12-25",
"filters": {
"branded": "non_branded"
},
"dimensions": [],
"compare": true
}
'const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
startDate: '2023-12-25',
endDate: '2023-12-25',
filters: {branded: 'non_branded'},
dimensions: [],
compare: true
})
};
fetch('https://api.seomator.com/v1/projects/{id}/reports/brands', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.seomator.com/v1/projects/{id}/reports/brands"
payload = {
"startDate": "2023-12-25",
"endDate": "2023-12-25",
"filters": { "branded": "non_branded" },
"dimensions": [],
"compare": True
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"period": {
"start": "<string>",
"end": "<string>"
},
"previous": {
"start": "<string>",
"end": "<string>"
},
"coverage": {
"current": {
"planned": 123,
"collected": 123,
"analyzed": 123
},
"previous": {
"planned": 123,
"collected": 123,
"analyzed": 123
}
},
"rows": [
{
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123,
"period": "current",
"brandId": "<string>",
"brandName": "<string>",
"brandRole": "own",
"date": "<string>",
"week": "<string>",
"assistant": "<string>",
"topicId": "<string>",
"promptId": "<string>"
}
],
"comparison": {
"status": "comparable",
"matchedPairs": 123,
"excludedAssistants": [
"<string>"
],
"brands": [
{
"brandId": "<string>",
"current": {
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123
},
"previous": {
"answers": 123,
"named": 123,
"first": 123,
"mentions": 123,
"positionSum": 123,
"positionCount": 123,
"retrieved": 123,
"cited": 123,
"linked": 123,
"citable": 123,
"pending": 123,
"unverified": 123,
"recounting": 123
}
}
]
}
}{
"error": {
"code": "bad_request",
"message": "<string>",
"requestId": "<string>"
}
}{
"error": {
"code": "bad_request",
"message": "<string>",
"requestId": "<string>"
}
}Authorizations
Path Parameters
Project id (proj_…) or slug (the domain with dots as dashes).