Visibility scores
Visibility, presence and mentions for one brand’s latest scan, how visibility and presence moved over the days you ask for, and one point for every scan in them. view=time_series adds rank per scan.
What comes back
Leave out view and you get the summary: the brand, its scores from the latest scan, how they changed across the days you asked for, and one point for each scan in those days.
latest_scoresfrom the latest scanvisibility0 to 100. How often AIs name the brand, and how high in the answer. A brand with no finished scan, or a scan where no answers came back, is sent as 0, not null.
49.5presenceShare of requests that named it at all. Failed requests count here, so it can read lower than Presence in the app.
32.1average_rankIts average place when named, 1 is first. The summary sends it as null today; view=time_series carries it per scan.
–mentionsAnswers that named it.
54model_scoresBoth scores for each AI, by its name.
one per AItrendacross the days you asked forvisibility_changePoints gained or lost since the last scan before the days began. This is the raw change; the app colours a change only outside the usual range.
+1.9presence_changeThe same, for presence.
+1.5historicala list[ ]One per scan in the days: its date, visibility and presence. Rank and mentions come back empty here; view=time_series carries them.
7 scansHow each score is worked out:How Visibility is worked out ›
Parameters
Send them in the query string. Only brand_id is needed; the rest change what the numbers cover.
brand_iduuid · requiredThe brand to read. You can send brand instead. Its id is in the /get-brands reply.
days7 to 365How far back the change and the history reach. The latest scores are the same whatever you pick.
default 90viewtextThe shape of the reply: summary, time_series, by_model or by_prompt. See the four views below.
default summaryperiodYYYY-MM or YYYY-QnA calendar month or quarter instead of a rolling window. A closed month comes from the monthly archive, so repeat reads match unless we publish a correction to that month. days is then ignored.
e.g. 2026-09 or 2026-Q3tag_idsuuids, comma-separatedScore only the prompts with these tags. Their answers are scored again as one set, not averaged prompt by prompt. Reports from before Jul 20, 2026 keep a per-prompt average.
summary only · not with periodprompt_iduuidScore one prompt on its own, from its answers on every AI.
summary only · not with periodFour views
The view parameter changes the shape of the reply. Pick the one that fits what you’re building.
summarydefaultThe latest scores, the change and every scan. This page.
time_series7 rowsA row for each scan with every score. For your own charts.
by_modelper AIEach AI's scores from the latest scan, with its change.
by_prompt21 promptsEach prompt's scores from the latest scan, with its text.
The other three views send back only the brand’s id and name, read every market’s scans (summary reads the brand’s main market), and ignore tag_ids and prompt_id.
Errors
Every error has a status and a detail: usually a sentence written to be shown as it is, an object for plan limits, and a list for a bad parameter. The one exception is 429, which sends error instead of detail.
"brand_id is required"Add brand_id, or brand. A view outside the four gets a 400 too, with its own detail.
"Missing API key"Send Authorization: Bearer, then your key. A key that doesn’t start sk_live_ gets a 401 too.
"Invalid API key"The key is mistyped, or was replaced or removed. Make a new one on the API keys page.
"Access denied to this brand"Your account can’t read this brand, or the id is wrong. Check it against /get-brands.
"The REST API requires an eligible paid plan."The REST API comes with Scale. The code is feature_not_entitled. MCP works on Growth too.
"Brand not found or no data available"We couldn’t read the brand’s record. Send it again; if it keeps happening, check the id against /get-brands.
[{ "loc": ["query", "days"], … }]brand_id or prompt_id isn’t a uuid, or days is outside 7 to 365. The list names the field.
"Rate limit exceeded: 60 per 1 minute"In error, not detail. Wait a minute, then try again.
"Authentication service temporarily unavailable"Ours, not yours. Try again in a few seconds.
Rate limits
60 requests a minute to this endpoint, counted for your whole account, so every server you call from shares the one count. No plan raises it.
None. There’s no remaining count and no Retry-After.
Wait a minute, then send again.
Scores change when a scan finishes, so one read after each scan keeps you current.
