Documentation
overpass.ch runs the standard Overpass API. Everything you know about Overpass QL works unchanged. Only the URL is different, and it carries your API key.
Quick start
- Create a free account and confirm your e-mail address.
- Create an API key on the API keys page.
- Send a query:
curl https://api.overpass.ch/v1/YOUR_API_KEY/interpreter \ --data-urlencode 'data=[out:json][timeout:25];node["amenity"="drinking_water"](47.36,8.53,47.38,8.55);out;'
The response is a normal Overpass result. Its osm3s.timestamp_osm_base field tells you how fresh the data is.
Endpoints
Your personal base URL is https://api.overpass.ch/v1/<API_KEY>/.
| Method | Path | Description |
|---|---|---|
| GET, POST | /v1/<KEY>/interpreter | Run a query. GET with ?data=; POST with a form-encoded data= field or the raw query as body. Overpass QL and XML are both accepted. |
| GET | /v1/<KEY>/status | Your plan, limits, usage this month, running queries and the data timestamp, as JSON. |
| GET | /v1/<KEY>/timestamp | The timestamp of the current data (like /api/timestamp). |
| GET | /healthz | Service health without authentication: HTTP 200 when the service is up and the data is current. |
The upstream /api/status and /api/kill_my_queries endpoints are not available, because they would expose information about other customers.
Authentication
Put the key in the path, as above. That's the only option for tools that let you set a server URL but no headers. Alternatively, send it in a header:
curl https://api.overpass.ch/v1/interpreter -H "X-API-Key: YOUR_API_KEY" \ --data-urlencode 'data=node(3470507586);out;'
Treat keys like passwords. For keys used in a browser, restrict them to your websites under API keys → Allowed referers. Requests from other sites then get HTTP 403. Revoked keys stop working immediately.
Limits & plans
Limits apply per account and are shared by all its keys.
| Plan | Requests / month | Requests / min | Parallel | Max. timeout | Max. maxsize |
|---|---|---|---|---|---|
| Free | 10'000 | 30 | 1 | 60 s | 256 MiB |
| Small | 50'000 | 60 | 2 | 180 s | 512 MiB |
| Medium | 500'000 | 120 | 4 | 300 s | 1 GiB |
| Large | 2'000'000 | 300 | 8 | 600 s | 2 GiB |
- Requests per month count successful (HTTP 2xx) interpreter calls, cache hits included. The counter resets on the 1st of each month (UTC).
- Requests per minute uses a token bucket: you can burst up to one minute's worth, then it refills continuously.
- Parallel is the number of queries that may run at the same time.
Every response includes X-RateLimit-Limit and X-RateLimit-Remaining. When a limit is hit you get HTTP 429 with a Retry-After header.
Timeout & maxsize
Overpass lets a query request a run time and memory budget with [timeout:…] and [maxsize:…] (or the timeout and element-limit attributes of <osm-script> in XML). We apply your plan as follows:
- Values above your plan's maximum are lowered to the maximum. The query still runs.
- If you set no value, we use your plan's default timeout and a maxsize of 512 MiB (or the plan maximum, if lower).
- Other settings such as
[out:…],[bbox:…],[date:…]and[diff:…]pass through unchanged.
The values that applied are returned in the X-Effective-Timeout (seconds) and X-Effective-Maxsize (bytes) response headers. The settings block must be the first statement of the query. A second settings block is rejected with HTTP 400.
Errors
Errors from Overpass itself (syntax errors, timeouts, “runtime error” remarks) are passed through unchanged. Errors from overpass.ch are JSON: {"error": "rate_limited", "message": "…"}.
| Status | error | Meaning |
|---|---|---|
| 400 | bad_query | The settings block could not be parsed. The message says why. |
| 400 | (Overpass) | Syntax error in the query; Overpass' own HTML error page. |
| 401 | unauthorized | Missing, unknown or revoked API key. |
| 403 | forbidden_referer | The key is restricted to other websites. |
| 413 | payload_too_large | The query is larger than 1 MiB. |
| 429 | rate_limited | Too many requests per minute. Wait Retry-After seconds. |
| 429 | concurrency_limit | Too many parallel queries for your plan. |
| 429 | quota_exceeded | The monthly quota is used up. Upgrade or wait for the 1st. |
| 503 | server_busy | The server is at capacity. Retry after a few seconds. |
| 504 | (either) | The query did not finish in time. Narrow it down or raise [timeout:] within your plan. |
Caching
Identical queries within 60 seconds are answered from a cache (X-Cache: HIT). Only successful responses up to 5 MiB are cached. To force a fresh result, send Cache-Control: no-cache.
Clients
Anything that speaks Overpass works. Use https://api.overpass.ch/v1/<KEY>/ for tools that add interpreter themselves, and https://api.overpass.ch/v1/<KEY>/interpreter where a full endpoint is expected.
Overpass Turbo
Open overpass-turbo.eu → Settings → General → Server and enter:
https://api.overpass.ch/v1/YOUR_API_KEY/
Keep the trailing slash. If you restrict the key to referers, add overpass-turbo.eu.
JOSM
Edit → Preferences → Download (enable expert mode if needed) → Overpass server URL:
https://api.overpass.ch/v1/YOUR_API_KEY/
JOSM sends no referer. Use a key without referer restrictions.
QGIS (QuickOSM)
QuickOSM → Settings → Overpass API server: add https://api.overpass.ch/v1/YOUR_API_KEY/interpreter and select it.
Python, R, JavaScript
import requests
URL = "https://api.overpass.ch/v1/YOUR_API_KEY/interpreter"
query = """
[out:json][timeout:60];
area["name"="Zürich"]["admin_level"="8"]->.a;
nwr(area.a)["shop"="bakery"];
out center;
"""
r = requests.post(URL, data={"data": query}, timeout=120)
r.raise_for_status()
for el in r.json()["elements"]:
print(el.get("tags", {}).get("name"))
import osmnx as ox
ox.settings.overpass_url = "https://api.overpass.ch/v1/YOUR_API_KEY"
ox.settings.overpass_rate_limit = False # limits are per plan, no /status polling
G = ox.graph_from_place("Bern, Switzerland", network_type="drive")
const res = await fetch("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter", {
method: "POST",
body: new URLSearchParams({ data: '[out:json];node["amenity"="cafe"](47.36,8.53,47.38,8.55);out;' }),
});
if (!res.ok) throw new Error(await res.text());
const { elements } = await res.json();
library(osmdata)
set_overpass_url("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter")
q <- opq("Lausanne") |> add_osm_feature("amenity", "fountain")
fountains <- osmdata_sf(q)
Attribution
The data is © OpenStreetMap contributors and available under the Open Database Licence. If you display or publish data obtained through overpass.ch, credit it as “© OpenStreetMap contributors” with a link to openstreetmap.org/copyright, and respect the share-alike terms for derived databases. We do not remove the copyright notice from responses.
Fair use
- Use one account per person or organisation; do not create accounts to get around limits.
- Do not resell raw API access or expose your key publicly in unrestricted form.
- Prefer bounding boxes and areas over planet-wide scans. For bulk exports of whole countries, planet extracts (for example from Geofabrik) are usually a better fit.
The full rules are in the terms of service. Questions? Contact us.