Brand ids
{id} in a path accepts either form returned by /brands/search:
- the platform id — a numeric string like
1234567890 - the brand UUID —
a1b2c3d4-...
id, so passing that straight through is the
normal path. An id that matches no brand returns 404 brand_not_found.
Nothing is paginated
There is no cursor, nopage, and no total. Each endpoint returns up to its
cap in one response, and count is the number of rows in that response —
not how many exist.
If count equals the limit you asked for, assume there is more data you
didn’t get, and raise the limit.
Ordering
Because results are ranked, truncating with
limit keeps the strongest rows —
you lose the tail, not an arbitrary subset.
Modes take different fields
/brands/search validates a different shape per mode, and these rules can’t be
expressed in JSON Schema, so a generated client won’t catch them:
mode: "ids"requiresbrandIds.countis ignored — you get one row per id.mode: "brand_name"requiresbrandNamesandtype.mode: "smart"requiresqueryandtype, and rejectssortBy, because results are ordered by relevance.
400 invalid_request with the offending field in details.
Rate limits
Three limits apply at once, and the lowest wins:- 60 requests/minute per IP address
- 120 requests/minute per key
- a per-endpoint limit: 60/min for
/brands/search, 30/min for the other three
429 rate_limited with a Retry-After header.
Wait that many seconds rather than retrying immediately.
Note the per-IP limit is lower than the per-key limit and is checked first, so a
single server making concurrent calls will hit 60/min before it hits 120/min.
Requests and responses
- Server-to-server only. There’s no CORS, so browser calls will fail. Keep the key on your backend.
- POST bodies are capped at 100 KB. Larger returns
413 payload_too_large. - Responses are never cached — every response carries
Cache-Control: no-store. HEADis not supported on/insightsand/landing-pages. It returns405 method_not_allowed, because it would run the query and bill for it without returning a body.