Docs
AIMentionTracker API errors and rate limits
Ten error codes, each one saying something a client can act on, and one rate limit that is the same on every plan.
Card required, nothing charged for 7 days
The error envelope
An error replaces data with an error object. There is no partial success: you get the data or you get one of these.
{
"error": {
"code": "brand_required",
"message": "This organisation has 3 brands. Pass ?brand=<id>; GET /v1/brands lists them."
}
}Branch on code. Four separate conditions return 404 and two return 402, so the status alone does not tell you what went wrong. The message is written for a human reading a log and its wording may change; the code will not.
Every error code
Ten codes. The middle column is what happened; the rest is what to do about it.
| Code | Status | What it means, and what to do |
|---|---|---|
| unauthorized | 401 | No key, or a key that is malformed, revoked or expired. Create a key at /api-keys. Send it as X-API-Key or Authorization: Bearer. |
| no_subscription | 402 | This organisation has never had a plan. Choose a plan. A lapsed plan is not refused: if you have subscribed before, you keep read access to the answers you already own. |
| api_not_on_plan | 402 | This plan does not include API access. Every plan includes the API, so this should not occur in practice. If you see it, contact support. |
| insufficient_scope | 403 | The key was not granted the scope this endpoint needs. Mint a key with the required scope. Every current endpoint needs `read`. |
| brand_required | 400 | The organisation has several brands and the request did not say which. Pass ?brand=<id>. GET /brands lists them. Deliberately not defaulted: a silent default files one customer's numbers under another's. |
| no_such_brand | 404 | No brand with that id that this key may read. 404 rather than 403 on purpose — a 403 would confirm the brand exists in somebody else's organisation. |
| no_brand | 404 | This organisation has no brand at all, or the brand a pinned key is bound to has been deleted. Finish setup in the dashboard. For a pinned key whose brand is gone, mint a new key. |
| brand_not_configured | 404 | The brand exists but setup was never finished, so there is nothing to report. 404 rather than a page of zeroes, which would read as measured absence. |
| bad_cursor | 400 | The pagination cursor does not belong to this brand. Start again without a cursor. Not a silent restart from the top, which would produce undetectable duplicates. |
| rate_limited | 429 | Either the per-key quota of 300 requests a minute, or the per-address limit of 200 failed authentications an hour, which is applied before the key is checked. Retry-After says how long to wait. Back off using Retry-After. If you are seeing this with a key you believe is valid, it is the second cause: the key is being rejected. |
AI visibility API rate limits
300 requests a minute, per key, on every plan. The cheapest plan gets the same ceiling as the most expensive one, because a rate limit that scales with price is a way of selling the same data twice.
The headers are on every response, not only the 429. A client should learn it is near the limit from a request that worked — finding out on the failure is finding out too late.
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 41 # seconds until the window rolls
# and on a 429 only
Retry-After: 41The window is fixed rather than sliding, so X-RateLimit-Reset counts down the seconds left in the current minute and the allowance returns in full when it hits zero.
The other 429
Failed authentications are throttled separately, by IP address, at 200 an hour, before the key is looked up at all. This exists because verification is the expensive part: without it, an unauthenticated caller could force an indexed database read per request, unbounded and metered by nothing.
Only failures are counted. Metering successful requests by address too would give one office behind a single NAT a second, lower ceiling that nothing in the product documents. If you are being refused with rate_limited and your key is new, check the key before you check your request rate.
Handling errors well
- Read
error.code, never the message. The message is prose for a log line. The code is the contract. - Retry only on 429 and 5xx, and only after
Retry-After. Retrying a 401 in a loop trips the IP throttle and makes the problem harder to see. - Treat
brand_requiredas a setup step, not an error to surface. Call/brandsonce, cache the id, and pass it from then on. See working with multiple brands. - Do not paper over
brand_not_configuredwith zeroes. A page of zeroes is a claim that we looked and found nothing. Say the brand has not finished setup. - Pass
meta.next_cursorback verbatim. Constructing one yourself earnsbad_cursor, which is better than the alternative — silently restarting at page one and reporting the first fifty answers twice.
Checking your key
Most integration failures are one of three things: the wrong header, a revoked key, or a scope that was never granted. GET /me distinguishes all three in one request.
curl -i -H "X-API-Key: $AMT_API_KEY" https://app.aimentiontracker.ai/api/v1/meA 200 returns key.scopes alongside key.available_scopes, so a client can tell “this key was not granted that scope” from “that scope does not exist”. A 401 means the key itself is the problem; keys are stored as a SHA-256 hash, so we cannot tell you which one you sent, only that it is not one of ours.
What a client does with this
An alert email is what the API's data looks like once a client has read it correctly: both counts present, the gap stated, and no percentage quoted off a sample that cannot carry one.

Questions about API errors
Answered from the implementation.
What is the rate limit on the AIMentionTracker API?
Why did I get a 429 before my key was even checked?
Should I branch on the status code or the error code?
Why does an unknown brand return the same error as a forbidden one?
Why does an unconfigured brand return 404 rather than empty data?
Does a lapsed subscription lose API access?
7-day trial
Measure it before you automate it
The API reads what AIMentionTracker has already collected. Add your brand and the prompts your buyers type, and the first answers land within minutes.
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.