Rate limits
Rate limits are enforced per API key.
- Default: 30 requests per minute.
- Per-key override: a key can be issued with a higher (or lower) limit. Read a key’s
effective limit from
rate_limitinGET /v1/me. - One limit covers all
/v1/*endpoints. A bulk import is a single request that kicks off an async job, so it counts as one — not one per row. - The window is a fixed one-minute bucket per key, shared consistently across all ZeeMaps servers.
Response headers
Every response includes the current limit state:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed per minute for this key. |
X-RateLimit-Remaining |
Requests left in the current window. |
X-RateLimit-Reset |
Unix timestamp (seconds) when the window resets. |
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1782403260
When you exceed the limit
The API returns 429 RATE_LIMITED with a Retry-After header (seconds until the window
resets):
HTTP/1.1 429 Too Many Requests
Retry-After: 24
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1782403260
{ "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded. Retry after 24s." } }
Backoff guidance
- Honor
Retry-After. On a429, wait at least that many seconds before retrying. - Watch
X-RateLimit-Remainingand slow down as it approaches0instead of sprinting into a429. - Use exponential backoff with jitter for repeated
429s (e.g. 1s, 2s, 4s, 8s, each with a small random offset) so concurrent clients don’t retry in lockstep. - Serialize or pace bursts. For large jobs, prefer a single bulk import over thousands of single-marker calls — it’s one request against your limit and far faster.
Related
- Errors for the full status-code table.
- Pagination — paging large result sets without burning your quota.