Skip to main content

Limits by tier

The per-minute figure is a burst ceiling for your key, not a reserved throughput guarantee. Each tier’s limit is fully reachable on its own, but authenticated traffic across all keys shares a platform-wide budget, so sustained parallel bursts at the top of the range can return 503 before you reach your own limit. If you need sustained high throughput rather than headroom for spikes, get in touch before you build against it — see Handling 503 below.

Response headers

Metered /v1 responses include rate-limit and quota headers. The public /v1/health endpoint is outside this middleware chain.
X-Quota-Overage-Limit is only present for paid tiers. When X-Quota-Used exceeds X-Quota-Limit, you are in the overage zone: requests continue but incur per-request charges. Requests are blocked at the hard limit. See Pricing for overage rates. Free anonymous quotas reset on the 1st of each calendar month. Paid customer quotas and overage counters follow the active Polar subscription billing period, so usage aligns with the billing invoice rather than a calendar-month boundary.

Handling 429 responses

When you exceed the rate limit, the API returns a 429 status with a Retry-After header:
The wait time (in seconds) is exposed both in the Retry-After response header and as error.retryAfter in the JSON body. The SDK reads it automatically. Best practices:
  1. Read the Retry-After header and wait before retrying
  2. Implement exponential backoff for repeated 429s
  3. Use the SDK, which handles retries automatically

Handling 503

A 503 with code UPSTREAM_ERROR means Borough could not verify your key against its billing provider — usually because the shared verification budget is momentarily saturated, occasionally because the provider is degraded. It is explicitly retryable and says nothing about your key being invalid, which is why it is a 503 and not a 401.
Retry with exponential backoff and jitter. Do not re-issue or rotate your key in response to a 503 — the key is fine. The SDK retries this automatically. If you see it steadily rather than in bursts, tell us: that is a capacity signal on our side, not a bug in yours.

Quota exceeded

Paid tiers have overage headroom: requests continue past the base quota and are billed at your tier’s overage rate, up to the overage cap. Once the hard limit is reached:
Free-tier users are blocked at 100 requests with no overage. The response also carries a quotaContext block (and X-Quota-Tier / X-Quota-Upgrade-URL headers) so you can prompt an upgrade at the moment you hit the limit:
nextTier and upgradeUrl are null once you are on the top tier (Business).

Checking your usage

Read the X-Quota-* response headers on any API response, or call GET /v1/usage for a full breakdown without spending a request:
GET /v1/usage is authenticated and rate-limited but does not count against your monthly quota. The full machine-readable API spec is served at GET /v1/openapi.json for import into Postman, Bruno, or code generators.