Rate Limits
Understand rate limiting behavior and how to handle throttled requests.
Overview
Rate limiting is applied to specific API endpoints to prevent abuse and ensure service stability. Free workspace API keys use an additional per-key minute limit and workspace daily quota. The limits below generally use token buckets; the Free workspace daily quota uses a fixed 24-hour window.
Inspect Current Quota
Use GET /api/v1/limits to inspect the authenticated key's current quota state. The endpoint authenticates account-scoped and workspace-scoped keys and reports the same authenticated key bucket consumed by identity endpoints such as /api/v1/me/*, but does not consume the quota it reports.
{
"apiVersion": "v1",
"defaultDateVersion": "2026-05-26",
"supportedVersions": ["2026-05-26"],
"rateLimit": {
"limit": 1000,
"remaining": 999,
"reset": 1780000000,
"policy": "\"api\";q=1000;w=60"
}
}Rate-Limited Endpoints
Free workspace REST API60/minFree workspace REST API1,000/dayPOST /api/v1/domains/verify10/minGET /api/v1/domains/check-dns20/minSCIM /scim/v2/*100/minGET /api/v1/audit-logs100/minPOST /api/v1/media50/hourResponse Headers
Rate-limited API endpoints include quota headers on successful responses so clients can throttle proactively. A 429 Too Many Requests response also includes retry timing:
RateLimitCurrent remaining quota and reset delayRateLimit-PolicyAdvertised quota and window policyX-RateLimit-LimitLegacy quota limit valueX-RateLimit-RemainingLegacy remaining quota valueX-RateLimit-ResetLegacy reset time as a Unix timestampRetry-AfterSeconds to wait after a 429 responseHandling 429 Responses
When you exceed the rate limit, the API returns a 429 Too Many Requests response. Implement exponential backoff with the Retry-After header:
async function fetchWithRetry(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter) * 1000
: Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}