DOC Reference

Error reference

Every rejection Overspan can return, why it happened, and what to do next. Nothing is silently clamped and nothing bills as overage.

Error shape

Every error is JSON with the same shape, whatever the status code:

response body
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit of 60 requests/minute exceeded."
  }
}

Branch on error.code, which is stable. The message is written for a human reading a log and may be reworded.

All codes

StatusCodeMeansRetry?
401 missing_key No key was supplied. Not until fixed
401 invalid_key Key unknown, revoked, or not yet activated. Not until fixed
400 missing_query No Overpass QL found in the request. Not until fixed
400 query_caps [timeout:] or [maxsize:] exceeds your tier. Not until fixed
429 rate_limited Too many requests per minute. Yes, after Retry-After
429 concurrency_limit Too many queries in flight at once. Yes, about a second
429 quota_exceeded Monthly request quota used up. Next month, or upgrade
503 no_backend No healthy, current database available. Yes, after Retry-After
504 upstream_timeout The query did not finish in time. Yes, if you make it cheaper
502 upstream_error The database failed to answer. Yes, with backoff

Authentication

missing_key 401

You called /api/interpreter without a key in the path, the ?key= parameter, or an Authorization header. See passing your key.

invalid_key 401

The key was supplied but will not serve traffic. Three causes:

  • Typo or truncation. Keys are copied out of email more often than they are typed. Check for a trailing space.
  • Subscription ended. Cancelled subscriptions keep working to the end of the paid period and are revoked when that period expires. Payment failures go through a retry window first, so a single failed renewal does not cut you off immediately.
  • Newly purchased and not yet activated. Rare, and it means we could not map your purchase to a tier automatically. It is our problem, not yours: mail hello@overspan.dev and we will fix it quickly. We deliberately never guess a tier, because guessing wrong either overcharges you in limits or hands out capacity nobody paid for.

Limits

rate_limited 429

You exceeded your requests-per-minute allowance. This is a token bucket, so short bursts above the number are fine as long as the average holds. A Retry-After header tells you how long until a token is available.

concurrency_limit 429

You already have your tier's maximum number of queries in flight. Unlike the rate limit this clears as soon as one of your running queries finishes, so Retry-After is one second. If you hit this constantly, the fix is usually a worker pool sized to your tier rather than an upgrade.

quota_exceeded 429

You have used your monthly request allowance. It resets at the start of the next month, UTC. Rejected requests never consume quota, so a burst of 429s does not eat into your allowance.

There is no overage billing by design. If you need more before the reset, upgrade in the billing portal and the new limit applies immediately.

Query problems

missing_query 400

The request arrived with no Overpass QL. Send it as the data parameter (GET query string or form-encoded POST body), or as the raw request body, which is what JOSM and curl often do.

query_caps 400

Your query asked for a [timeout:] or [maxsize:] above your tier's maximum. The message names the setting, the value you asked for, and the cap:

example
{
  "error": {
    "code": "query_caps",
    "message": "[timeout:600] exceeds the indie tier maximum of 60. Lower it or upgrade your tier."
  }
}

We reject rather than quietly lowering the value, because a clamped query returns different results than the one you wrote and you would have no way of knowing.

Remember the injected defaults A query that sets neither value gets [timeout:25] and [maxsize:256 MB]. Those are lower than the public servers' defaults, so set both explicitly on anything heavy. Details in differences from the public servers.

Service faults

no_backend 503

No database was both reachable and current enough to serve you. Overspan refuses to answer from a database that has fallen behind the OSM replication feed, because stale results that look fresh are worse than an honest error. Retry after the interval in Retry-After; if it persists, mail us.

upstream_timeout 504

The query was accepted and started but did not finish in time. Either it is genuinely too heavy, or the box was busy. Options, in the order worth trying: narrow the bounding box, filter earlier in the query, split the job into chunks, raise [timeout:] within your tier cap, or move up a tier.

upstream_error 502

The database failed to answer. This is our fault, not your query's. Retry with backoff. If it repeats, mail hello@overspan.dev with the approximate time and we will look at what happened.

Retrying well

A retry policy that treats us kindly and gets your job done:

  • Honour Retry-After. Where we send it, it is the real answer, not an estimate.
  • Never retry a 400 or 401 unchanged. Those need a fix, and hammering them just burns your rate limit.
  • Back off exponentially on 502 and 503, with jitter, and cap the number of attempts.
  • Treat 504 as a signal to shrink the query, not as a transient blip. Retrying an identical heavy query usually times out again.
  • Keep concurrency at or below your tier. Sizing your worker pool to the tier removes an entire class of 429 entirely.
  • Read the quota headers instead of guessing. Every response carries X-Overspan-Quota-Remaining and X-Overspan-Quota-Reset, so a client can slow itself down before it hits the wall. Details in the quickstart.

Trying to work out whether a run went badly? The usage dashboard and the usage endpoint both break your recent requests down by outcome, so you can see which of these you actually hit and how often.


Hit something not listed here? That is a documentation bug. Mail hello@overspan.dev.