Performance & limits
Service limits at a glance — query timeout, page size, concurrency, caching — and how to scope queries so they stay fast.
Service limits at a glance
| Limit | Value |
|---|---|
| Authentication | Required on every request (bearer token) |
| API keys per account | 5 |
| Per-query time limit | 30 seconds — longer queries fail with HTTP 500 |
| Max page size | limit clamped at 10,000 features |
| Concurrent requests | Shared cap across all callers — excess gets 503 + Retry-After |
| Response cache | 60 seconds, private to your client |
| Total counts | No numberMatched in responses — page until a short page (paging) |
| Server-side sorting | None — sortby is accepted but ignored; sort client-side |
| Writes | None — the API is read-only |
| CORS | Open (Access-Control-Allow-Origin: *) |
Scope your queries
The service is backed by a large database (full detection history since January 2025). Well-scoped queries are fast — sub-second to a few seconds; broad unscoped ones can be slow or time out.
- Combine a reasonable
bbox, anobserved_attime window, and/oractive = true. A broad-areabboxwith a largelimitand no other filter is the main query shape that can exceed the 30-second limit and return HTTP 500. active = trueandobserved_atranges are fast (indexed). Filtering by non-indexed attributes over large sets is slower.- Prefer time windows over deep paging for bulk pulls — see Paging & bulk export.
Concurrency
The API admits a fixed number of requests at a time, shared across all callers, so one heavy
consumer cannot starve everyone else. Past that ceiling you get an immediate 503 with
Retry-After and a {"code":"ogc-busy"} body — the request never reached the database, so
retrying after the suggested delay is safe and cheap.
Practically: run a handful of parallel requests, not dozens. A serial loop over narrow time windows finishes a bulk export faster than a wide fan-out that spends its time being refused.
Retries
Treat an HTTP 500 with a timeout message as retryable: narrow the query (smaller
bbox, shorter time window, add active = true) and retry with backoff.
A 503 is retryable too — see Concurrency above, and honor Retry-After. A 401 is not:
re-run the token exchange rather than retrying the same request.
Caching & freshness
Responses carry Cache-Control: private, max-age=60. Because they are authenticated they are
never held in a shared cache, but your own HTTP client may reuse one for up to a minute. Freshly
ingested detections can therefore lag by up to a minute on top of ingestion itself.
