Consent Docs

Rate limits

The request budgets for each key and each address, the headers that report them and what the API returns when a limit is reached.

Reference3 min readFor developers calling the REST API

The API counts requests in one-minute windows and answers 429 when a budget is used up.

Budgets#

Budget Default Counts
For each key 600 a minute for a test key, 6,000 once it is live Every request made with the key
Calls on a person, for each key 60 a minute POST /subjects/find, /export, /withdraw, /erase, /link, POST /requests/link, the notice campaign links and both processor-task calls, on top of the key's budget
Consent checks, for each key 600 identifiers a minute Each identifier in POST /consent/check, the subject and every alsoKnownAs entry, and each identifier in a write with collectedAt from a key that holds consent:check, on top of the key's budget
Audit log reads, for each key 60 a minute GET /audit-log, on top of the key's budget
Hosted notice page, for each address 300 requests and 20 unknown links in 10 minutes Requests to /n/{token} from one IP address
Browser and app writes, for each key and address 60 a minute Requests other than GET made with a publishable key from one IP address
For each address 3,000 a minute Every request to /sdk from one IP address, whatever the key
Hosted rights request form 5 an hour for each address Requests submitted through the form
  • Whoever runs your deployment can change these defaults.
  • You can set a key's own budget, from 60 to 600,000 a minute, under Rate limit when you create the key.
  • Set a key's own number of identifiers to check, from 60 to 6,000 a minute, under Checks per minute on the key. Whoever runs the deployment can raise the 6,000 with SDK_CHECK_MAX_PER_MINUTE.
  • Each consent check also counts once against the key's budget and the budget for each address.
  • A key that kept the default of 600 moves to 6,000 when it goes live. A budget you set yourself stays as it is.
  • Calls made with a secret key are not held to the write budget for each address, since one server acts for many people.

A project's monthly record limit is separate from these budgets; see Usage and limits.

Response headers#

Header Sent on Value
RateLimit-Limit Every keyed response The key's budget for the window
RateLimit-Remaining Every keyed response Requests left in the window
RateLimit-Reset Every keyed response Seconds until the window starts again
Retry-After A 429 response Seconds to wait before the next request
RateLimit-Limit: 600
RateLimit-Remaining: 587
RateLimit-Reset: 42

When a limit is reached#

The answer is 429 with a Retry-After header. Wait that many seconds, then continue. A consent check, or a write with collectedAt from a key that holds consent:check, over the key's identifier budget answers 429 with the code CHECK_BUDGET_EXCEEDED.

JSON
{
  "statusCode": 429,
  "message": ["Too many requests"],
  "error": "TOO_MANY_REQUESTS",
  "timestamp": "2026-09-24T10:12:03.000Z",
  "path": "/sdk/v1/subjects/find",
  "requestId": "0d8a3c1e-5a52-4f0b-9c0e-2f1b7a9d4e63"
}
Caller What it does on a 429
Your server Wait for Retry-After, then send the request again
Node.js SDK Throws ConsentApiError with retryAfter. It does not retry.
Python SDK Raises RateLimitError with retry_after. It does not retry.
Browser runtime Applies the visitor's choice locally at once and sends the write again on a later page load

For a large import, use Import CSV in Records, or pace your writes below the key's budget from the start: under ten a second for a test key.

The other error bodies are in Errors.

↑↓ to move, Enter to open