API reference
Rate limits
Per-key token buckets, the headers returned on 429 and how to stay under the limit.
Rate limiting in the control-plane API is opt-in and per API key. A key created with rate_limit_per_minute gets a token bucket of that size; keys without it are unlimited. Session users are not rate limited by the API (the portals are protected by login throttling instead).
When the bucket is empty the request is rejected before any work is done:
HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-RateLimit-Limit: 600
Content-Type: application/json
{"error":{"code":"rate_limited","message":"rate limit exceeded","request_id":"01J..."}}
| Header | Meaning |
|---|---|
Retry-After | Whole seconds to wait before the next attempt. |
X-RateLimit-Limit | The key's configured requests per minute. |
The API does not send remaining-quota headers on successful responses. The contract mentions RateLimit-* headers; today only the two above are emitted, on 429.
Shared buckets across replicas
Run several API replicas with DT_REDIS_URL set and the buckets live in Redis, so the limit holds across all of them. Without it each replica keeps its own in-process bucket and the effective limit is multiplied by the replica count.
Staying under the limit
- Page with
page_size=500instead of many small requests. - Use
POST /conversions/bulkstyle endpoints and report exports instead of looping over single items. - Back off exponentially on
429,502and503, starting fromRetry-After. - Tracking traffic (clicks, postbacks) is not subject to this limit; it is bounded by capacity and by the caps you configure. See caps.