Rate limiting
The API limits how many requests a company can make. The limits apply per company and are shared across all API keys of that company.
Limits
Section titled “Limits”These limits apply to every endpoint:
| Limit | Value | rate_limit_error_code |
|---|---|---|
| Burst | 20 requests per 10 seconds | COMPANY_BURST |
| Per minute | 100 requests per minute | COMPANY_MINUTE |
| Per day | 50,000 requests per day | COMPANY_DAILY |
| Concurrent requests | 10 requests at a time | COMPANY_CONCURRENCY |
GET /layerFeatures and GET /propertyChanges act on very large data sets and have tighter limits on top of the ones above. Each of the two endpoints has its own budget:
| Limit | Value | rate_limit_error_code |
|---|---|---|
| Burst | 10 requests per 10 seconds | ENDPOINT_BURST |
| Per minute | 50 requests per minute | ENDPOINT_MINUTE |
| Concurrent requests | 5 requests at a time | ENDPOINT_CONCURRENCY |
Limits may be adjusted without notice if required for the stability of the platform.
What counts
Section titled “What counts”- Every authenticated request counts, including requests that fail, for example with a
400. - A request rejected with
429does not count towards any limit. - A request to
GET /layerFeaturesorGET /propertyChangescounts towards both the limits of that endpoint and the company limits.
The time windows are fixed: a window starts at the first request that counts and resets when it ends. The daily limit is a fixed 24-hour window, not a calendar day.
The 429 response
Section titled “The 429 response”When a request exceeds a limit, the API responds with 429 Too Many Requests. The body names the limit that was hit:
{ "rate_limit_error_code": "COMPANY_BURST", "message": "Company rate limit of 20 requests per 10 seconds exceeded"}The body also has other fields. Only rely on rate_limit_error_code and message.
The response has these headers:
| Header | Description |
|---|---|
Retry-After |
Number of seconds to wait before retrying |
RateLimit-Limit |
The number of requests the exceeded time window allows |
RateLimit-Remaining |
Requests left in that window: always 0 on a 429 |
RateLimit-Reset |
Number of seconds until that window resets |
Retry-After is the header to rely on. The RateLimit-* headers follow an IETF draft and their names may change. They are only sent when a time window is exceeded: a 429 for too many concurrent requests only carries Retry-After: 1.
Handling 429
Section titled “Handling 429”- Wait at least
Retry-Afterseconds before retrying, and add some random jitter. - Don’t retry in a tight loop.
- On a
*_CONCURRENCYcode, also reduce the number of requests you run in parallel. - When paging through large results, use the largest page size the endpoint allows. See Pagination.