API reference

A point-in-polygon boundary API. Send a coordinate; get back the country, region and municipality that contain it, plus matches from your own uploaded boundary sets — in one call.

Reading this as an AI agent?

Fetch the machine-readable reference instead. It is plain Markdown, complete, and covers what an automated client cannot do as well as what it can.

https://atlasfetch.xyz/llms.txt

Base URL

https://api.atlasfetch.xyz

Every path on this page is relative to it. Lookups go to https://api.atlasfetch.xyz/location/lookup — not to atlasfetch.xyz, which is the website.

When to use AtlasFetch

Reach for it when the question is “which place is this point in?”

  • Reverse geocoding to administrative areas — a coordinate becomes the country, region (state, province) and municipality (city, district or county) that contain it, as names plus ISO 3166-1 / ISO 3166-2 codes. Worldwide, from OpenStreetMap boundaries.
  • Geofencing against your own polygons — upload GeoJSON delivery zones, service areas or sales territories and test a point against them in the same call as the administrative layers.
  • Jurisdiction and region checks — which country or region a user, order or device is in, for pricing, availability, tax or licensing rules.
  • Enriching location data — tag GPS pings, orders or sign-ups with region codes, and optionally an H3 cell index or Google Plus Code.
  • Privacy-sensitive workloads — looked-up coordinates are never stored.

Not a fit

  • Street addresses, postcodes or place search. This is not forward geocoding, and reverse lookups stop at the municipality, not the street.
  • Routing, distances or map tiles.
  • Boundary geometry itself. It answers containment; it does not return the reference polygons.
  • Many coordinates in one request. One request is one coordinate.
  • Enter/exit events. It answers which zones contain a point now; tracking transitions between calls is up to your code.

Boundaries follow OpenStreetMap. For a legally binding jurisdiction decision, confirm against the authoritative source.

Authentication

Two mechanisms, and the difference decides what a program can do.

  • API keyAuthorization: Bearer <key>. A 64-character hex string, no prefix. This is what a program uses.
  • Session cookie — issued by an interactive Google sign-in in a browser. An automated client cannot obtain one.

A key is enough for lookups and for managing boundary sets. It is not enough to mint keys, read usage, or manage billing.

Create a key on the dashboard, or call GET https://api.atlasfetch.xyz/demo/key for a shared public one — no signup, but its 1,000 lookups a month and its rate limit are pooled across every anonymous user. Use it to try things, not to ship.

The lookup

GET https://api.atlasfetch.xyz/location/lookup?lat=51.5072&lng=-0.1276
Authorization: Bearer <key>
curl -H "Authorization: Bearer $ATLASFETCH_KEY" \
  "https://api.atlasfetch.xyz/location/lookup?lat=51.5072&lng=-0.1276"
ParameterDefaultMeaning
latrequiredLatitude, −90 to 90
lngrequiredLongitude, −180 to 180
baseall threeComma list: country, region, municipal
setnoneComma list of your own boundary sets
encodenoneComma list: h3, pluscode
h3res9H3 resolution 0–15. r9 is ~400 m across
pluslen10Plus Code length: 2, 4, 6, 8, 10–15
{
  "base": {
    "country":   { "code": "GB",     "name": "United Kingdom" },
    "region":    { "code": "GB-ENG", "name": "England" },
    "municipal": { "code": "GB-WSM", "name": "City of Westminster" }
  },
  "sets": {
    "delivery_zones": [
      { "name": "Zone A", "properties": { "category": "express" } }
    ]
  },
  "errors": []
}

Guarantees you can rely on

  • errors[] is always present, empty or not. Read it unconditionally.
  • A layer that matched nothing is null, not absent.
  • encoded is absent entirely unless encode was asked for.
  • Every response carries X-Lookups-Remaining.
  • Boundaries are identified by codes, never OSM ids — ISO 3166-1 for country, ISO 3166-2 for region, and for municipal the official ISO code where OSM carries one, otherwise a generated B-<country>-<n>.
  • municipal is the finest unit available, not a consistent kind of thing. Los Angeles returns a city; rural Kansas returns Barton County. Where a country’s fine tier is patchy, a coarser complete tier answers instead — a county beats null for most uses. Do not assume the value names a city.
Generated B- codes are not yet stable across a full reseed. Treat them as display labels rather than durable keys. ISO codes are stable.

One call, one lookup

A request is exactly one lookup regardless of how many layers, sets or grid codes it touches. Metering happens before matching, so a call that matches nothing still costs a lookup — the work was done either way. A request rejected with 400 or 429 is not billed.

Partial failure is still a 200

A set you cannot query does not fail the request. It is skipped, an entry is appended to errors[], and the status stays 200. A set is only queryable when it is marked available and granted to the key making the call.

"errors": [
  { "type": "access", "message": "Set 'zones' is not granted to key 'prod'" }
]

type is access (a set was skipped) or usage (quota exhausted, mirroring a 402).

Grid codes

The looked-up point can be returned as a Google Plus Code and/or an H3 cell index. Not metered, not plan-gated.

GET https://api.atlasfetch.xyz/location/lookup?lat=51.5072&lng=-0.1276&encode=h3,pluscode

"encoded": { "h3": "89195da49b7ffff", "pluscode": "9C3XGV4C+VX" }

They are output only

pluscode= and h3= are not accepted as a location; sending one returns 400. That is deliberate, not a missing feature.

A Plus Code and an H3 index name areas, not points. A length-4 Plus Code is a 111 km square; an H3 cell at resolution 4 is 52 km across. Accepting one as the location would mean picking a representative point inside it and returning whichever boundary contains that point as though it were the answer — one of several equally defensible answers, with no way for you to tell which situation you were in.

If you have a cell and want a lookup, decode it yourself and decide what its centre means for your use case. That keeps the judgement where the context is.

Picking a precision

H3WidthPlus CodeWidth
r4~52 km4~111 km
r6~7.4 km6~5.6 km
r8~1.1 km8~278 m
r9 (default)~402 m10 (default)~14 m
r11~57 m11~3 m
r15~1 m12~56 cm

Plus Code widths are at the equator. pluslen=9 is invalid — 9 is not a Plus Code length.

Custom boundary sets

Your own polygons, grouped into named sets, matched in the same call as the reference layers. These endpoints accept an API key or a session.

MethodPathPurpose
GET/boundaries/setsList sets with counts and granted key ids
POST/boundaries/setsCreate a set
PATCH/boundaries/sets/:nameToggle available, grant/revoke keys
DELETE/boundaries/sets/:nameDelete the set and its contents
POST/boundariesAdd a boundary (GeoJSON geometry)
GET/boundaries/view?set=Your own boundaries, with geometry
DELETE/boundaries/:idRemove one boundary
A new set is created available: false with no grants, so it matches nothing until you switch it on and grant it to a key. Grants are addressed by API key id, and the endpoint that lists ids needs a session — so a client holding only a raw key can create a set and upload into it, but cannot grant the set to itself. That step happens in the dashboard.

Public endpoints

No authentication, no metering.

MethodPathPurpose
GET/healthLiveness
GET/demo/keyThe shared public demo key
GET/payments/plansPlan catalogue with prices and caps
GET/versionWhich API build is serving
GET/openapi.jsonOpenAPI 3.1 spec — generate a client from it
There is no bulk geometry endpoint. /explore/world and /explore/country/:code served simplified country outlines and were removed on 8 September 2026 — unauthenticated, uncached and expensive (243 KB and 16.8 s per call), they were the one lever an anonymous caller could pull against the database. AtlasFetch answers point-in-polygon questions; it does not hand out boundary geometry.

Status codes

CodeMeaningRetry?
200Success — check errors[] for per-set problems
400Invalid parameters; error says whatNo
401Missing, malformed or revoked keyNo
402Monthly allowance exhaustedAfter reset
403Plan does not include this, or a cap exceededNo
409Conflict, e.g. duplicate set nameNo
429Per-key rate limit — honour Retry-AfterYes

Rate limiting is per key, per second. Quota is per account, per month.

Privacy and data

We do not store the coordinates you look up. Usage metering records the endpoint, the key and a timestamp — never the point.

Reference boundaries derive from OpenStreetMap under the ODbL. Attribution and share-alike obligations pass through to you — see data attribution. Your own uploaded boundaries are private to your account and are never returned to anyone else.

Try it without writing any code

The playground loads a demo key automatically and shows the exact request URL.

Open the playground