Rate Limiting
The Brandsearch API enforces rate limits and quotas to ensure fair usage. This page explains the limits by tier and how to handle them.
Rate limits by tier
Rate limits are applied per API key. Each tier has different limits across multiple time windows.
- Name
Starter- Type
- tier
- Description
3 req/s, 15 req/min, 300 req/hr, 3,000 req/day
- Name
Outscaler- Type
- tier
- Description
10 req/s, 60 req/min, 1,000 req/hr, 10,000 req/day
- Name
Agency- Type
- tier
- Description
30 req/s, 200 req/min, 5,000 req/hr, 50,000 req/day
Rate limit exceeded response
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded.",
"details": {
"retry_after": 12,
"window": "1m"
}
}
}
Quotas
In addition to rate limits, each API key has daily and monthly request quotas.
| Tier | Daily Quota | Monthly Quota |
|---|---|---|
| Starter | 3,000 | 50,000 |
| Outscaler | 10,000 | 200,000 |
| Agency | 50,000 | 1,000,000 |
Quotas reset automatically — daily quotas reset at midnight UTC, and monthly quotas reset on the 1st of each month.
You can fetch live counters at any time with GET /v1/usage, which is unmetered.
Free (unmetered) endpoints
Some endpoints don't count against your quota:
GET /v1/lookup— resolve a name/domain/handle to a brand IDGET /v1/me— your account infoGET /v1/usage— live quota countersGET /v1/facets/*— enumerate valid filter/sort/field values
These responses include X-Quota-Charged: false so you can verify the request was not metered.
Credits (per-row tracking)
In addition to request count, every metered response carries an X-Credits-Used header showing how many rows were charged:
- List endpoints charge 1 credit per returned row (so a
page_size=20response costs up to 20 credits). - Detail endpoints (
GET /v1/meta-ads/{ad_id}, etc.) charge 1 credit. - Free endpoints above charge 0 credits.
Credits are currently informational — there is no daily or monthly limit on credits yet, but counters (credits_used_today, credits_used_this_month) are exposed via GET /v1/usage.
Response headers
Every API response includes headers showing your current quota usage:
- Name
X-Quota-Daily-Remaining- Type
- integer
- Description
Requests remaining for the current day.
- Name
X-Quota-Monthly-Remaining- Type
- integer
- Description
Requests remaining for the current month.
- Name
X-Quota-Daily-Limit- Type
- integer
- Description
Your total daily limit.
- Name
X-Quota-Monthly-Limit- Type
- integer
- Description
Your total monthly limit.
- Name
X-Quota-Overrun- Type
- string
- Description
Present with value
"true"when the response exceeded quota.
- Name
X-Quota-Overrun-Daily- Type
- integer
- Description
Number of daily overage requests (only when overrun).
- Name
X-Quota-Overrun-Monthly- Type
- integer
- Description
Number of monthly overage requests (only when overrun).
- Name
X-RateLimit-Limit- Type
- integer
- Description
Maximum requests allowed in the most-constrained rate-limit window.
- Name
X-RateLimit-Remaining- Type
- integer
- Description
Requests remaining in that window after the current one.
- Name
X-RateLimit-Reset- Type
- integer
- Description
Unix timestamp (seconds) when the most-constrained window expires and the counter resets.
- Name
Retry-After- Type
- integer
- Description
Seconds to wait before retrying (on
429responses).
- Name
X-Credits-Used- Type
- integer
- Description
Credits charged for this request (rows on list, 1 on detail, 0 on free endpoints).
- Name
X-Quota-Charged- Type
- string
- Description
Set to
"false"on unmetered endpoints (/v1/lookup,/v1/me,/v1/usage,/v1/facets/*).
Handling rate limits
When you hit a rate limit, the API returns a 429 status with a Retry-After header. The best practice is to implement exponential backoff:
Handling rate limits
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options)
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('Retry-After') || '1')
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000))
continue
}
return response
}
throw new Error('Max retries exceeded')
}
Monitor your X-Quota-Daily-Remaining and X-Quota-Monthly-Remaining headers to proactively manage your usage and avoid hitting limits.