Skip to content

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.

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.

  • Every authenticated request counts, including requests that fail, for example with a 400.
  • A request rejected with 429 does not count towards any limit.
  • A request to GET /layerFeatures or GET /propertyChanges counts 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.

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.

  • Wait at least Retry-After seconds before retrying, and add some random jitter.
  • Don’t retry in a tight loop.
  • On a *_CONCURRENCY code, 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.