Docs
Multiple brands in the AIMentionTracker API
One key can cover many brands, so the API makes you say which one you mean. Here is why that is a refusal rather than a default, and how to give a client a key that cannot wander.
Card required, nothing charged for 7 days
Find the brand id first
Everything on this page starts with one request. The id it returns is what every other endpoint wants in ?brand= — on every endpoint in the API reference, and as --brand in the CLI.
curl -H "X-API-Key: $AMT_API_KEY" https://app.aimentiontracker.ai/api/v1/brands| Field | Type | Meaning |
|---|---|---|
| id● | string | The workspace public id. Pass as ?brand=. |
| name● | string | Brand name. |
| domain | string | null | The brand's own domain, null before setup finishes. |
| configured● | boolean | False means setup was never finished. Data endpoints return 404 brand_not_configured for one of these rather than a page of zeroes, which would read as measured absence. |
| active_prompts● | integer | Prompts currently running for this brand. |
| market | object | — |
| market.location_code | integer | null | DataForSEO location code. |
| market.language_code | string | null | ISO language code. |
| last_collected_at | string | null | ISO timestamp of the most recent stored answer. |
{
"data": [
{
"id": "wsp_zD6cssxGlJyF",
"name": "Acme",
"domain": "acme.com",
"configured": true,
"active_prompts": 5,
"market": {
"location_code": 2840,
"language_code": "en"
},
"last_collected_at": "2026-09-30T04:12:00.000Z"
},
{
"id": "wsp_094oxa5e",
"name": "Acme Labs",
"domain": null,
"configured": false,
"active_prompts": 0,
"market": {
"location_code": 2840,
"language_code": "en"
},
"last_collected_at": null
}
],
"meta": {
"generated_at": "2026-09-30T09:00:00.000Z",
"pinned": false,
"note": "Pass one of these ids as ?brand= on every other endpoint."
}
}Why omitting ?brand= is an error
When your organisation has one brand, leave ?brand= off and the API uses it. When it has two or more, omitting it returns 400 brand_required with a message naming how many there are.
We could have defaulted to the first brand, or the oldest, or the one most recently collected. Every one of those produces the same failure: a dashboard, a weekly email or a client report carrying one brand's numbers under another brand's name, with nothing anywhere in the response saying which one it actually described.
That error is invisible after the fact. Nobody finds it by reading the output, because the output looks exactly like a correct one. The cost of refusing is one extra request while you build. The cost of guessing is a wrong number nobody catches, in your customer's name, which is the specific thing this product exists to not do.
# 400 brand_required
curl -H "X-API-Key: $AMT_API_KEY" "https://app.aimentiontracker.ai/api/v1/visibility?days=30"
# 200
curl -H "X-API-Key: $AMT_API_KEY" "https://app.aimentiontracker.ai/api/v1/visibility?days=30&brand=wsp_zD6cssxGlJyF"{"error":{"code":"brand_required","message":"This organisation has 2 brands. Pass ?brand=<id>; GET /v1/brands lists them. Run `amt brands` for the ids, then pass --brand.","status":400}}Treat it as a setup step rather than an error to surface: call /brands once, keep the id, pass it from then on. Every response also carries meta.brand, so a client can label output with the brand the API says it described rather than the one it believes it asked for.
Pinned keys, for agencies
A key bound to one brand at the moment it is minted.
An organisation key can read every brand in the organisation. That is right for your own automation and wrong for anything you hand to a client or run per-client in CI, because the only thing separating one client's data from another's is a query parameter.
Pin the key instead, at API keys in the app. A pinned key:
- Reads only its brand. Any other
?brand=is refused. - Cannot enumerate siblings.
GET /brandsreturns a list of one. It does not learn that the organisation has others, so probing ids tells it nothing. - Says so.
meta.pinnedistrue, andGET /mereturnskey.pinned_to_brand: true, so a client can display the constraint instead of inferring it. - Needs no
?brand=. The parameter is ignored rather than required, so the same code works pinned or not.
The practical shape for an agency: one pinned key per client, stored with that client's job. A misconfigured job then fails loudly with no_such_brand instead of quietly reporting on the wrong company. The same constraint is worth applying to a key you hand to an AI assistant through the MCP server.
Multi-brand AI visibility tracking in four steps
- 1
List once, cache the ids
GET /brandsat startup. Storeidagainst your own customer record, not the name — names change, ids do not. - 2
Skip what is not configured
Rows with
configured: falsehave no data. Show “setup unfinished”, never a zero. - 3
Pass ?brand= on every request
Even when there is one brand today. The day a second is added, nothing breaks.
- 4
Label from meta.brand
Take the name on the output from the response, not from your own variable.
Knowing when a brand has data
last_collected_at is the timestamp of the most recent stored answer, and active_prompts is how many prompts are currently running. Together they answer the question a client actually has when a number looks low: is this brand quiet, or is it not collecting?
A brand with active_prompts: 0 is not being measured. A brand whose last_collected_atis three days old on a schedule that runs daily is worth flagging in your own interface before anyone reads a rate off it. Neither of those is an error from the API's point of view, which is exactly why a client should look.
Questions about brands and API keys
Answered from the implementation.
Can one AIMentionTracker API key read several brands?
Why does the API return 400 brand_required instead of picking a brand?
How do pinned API keys work for agencies?
How do I find a brand id?
What happens if a brand has not finished setup?
Can I compare two brands I track in one request?
7-day trial
Track every brand you are responsible for
One organisation, as many brands as you manage, and a key per client that cannot be pointed at the wrong one.
Card required, nothing charged for 7 days.
On every plan
- Every answer stored in full, with its citations.
- Every rate shown with the number of checks behind it.
- Cited-but-not-named reported as its own state.