Skip to content

Both copy text to your clipboard — Build with AI copies a setup prompt to paste into Claude Code, Cursor, Codex or Copilot; Copy page as Markdown copies this page to paste into a chat. How it works

Category Search (v2)

The v2 Category API answers "what is near me, of this kind" — supermarkets around a point, cafés near a map centre, pharmacies within 500 m. Results are ranked by distance and carry the distance in metres.

Category search vs reverse geocode

These are easy to confuse, and picking the wrong one gets you the wrong answer:

InputReturnsUse when
Reverse Geocodea pointwhat is at that point"What address am I standing on?"
Category Searcha point + a categorythe nearest POIs of that kind"Where's the nearest supermarket?"

Reverse geocoding answers identity. Category search answers discovery.

Endpoint

GET https://gateway.mapmetrics-atlas.net/v2/category/

Parameters

ParameterTypeReqExampleDescription
categorystringsupermarketCategory to search for. Comma-separate for a union — see below.
proximitylon,lat4.895,52.370Point to search around. Longitude first. Omitted, the caller's approximate location is used.
limitinteger10Max results. Default 10, capped at 50.
radiusinteger500Hard cut-off in metres. See the note below on how it interacts with limit.
countrystringNLRestrict to one country. Otherwise inferred from proximity.
tokenstringYOUR_API_KEYAuth token, passed as a query parameter.

proximity is lon,lat — longitude first

This is GeoJSON order, and it is the reverse of the lat,lon most mapping UIs display. Swapping them does not error — you get results near a completely different place. 4.895,52.370 is Amsterdam; 52.370,4.895 is not.

Example

bash
curl "https://gateway.mapmetrics-atlas.net/v2/category/?category=supermarket&proximity=4.895,52.370&limit=3&token=YOUR_API_KEY"
json
{
  "type": "FeatureCollection",
  "query": "supermarket",
  "category": "supermarket",
  "features": [
    {
      "id": "poi.123456",
      "type": "Feature",
      "place_name": "Albert Heijn, Amsterdam",
      "center": [4.8951, 52.3702],
      "geometry": { "type": "Point", "coordinates": [4.8951, 52.3702] },
      "properties": {
        "category": "supermarket",
        "layer": "poi",
        "distance_m": 83
      }
    }
  ],
  "attribution": "..."
}

Several categories at once

Comma-separate to search a union of categories. A feature matches if it is in any of them:

?category=restaurant,cafe,bar&proximity=4.895,52.370

Filtering by distance

Every feature carries properties.distance_m — great-circle metres from your proximity point — so you can render "250 m away" without re-deriving it.

radius applies a hard cut-off in metres:

?category=restaurant&proximity=4.895,52.370&radius=300

radius trims, it does not widen

radius is applied after ranking. radius=300&limit=50 returns however many of the top 50 fall within 300 m — it does not keep searching outward to find 50 results inside the radius. So a tight radius can return fewer results than your limit, and that is expected rather than an error.

Subcategories are included

Searching a broad category also returns its more specific children — asking for restaurant also matches italian_restaurant and french_restaurant. Each feature reports its own precise properties.category, so you can group or filter client-side.

Category names

Category matching is on whole tokens, so bar will not match barber. Common non-English names are understood too — Dutch supermarkt, apotheek and koffie all resolve to their canonical categories.

An unknown category is not an error: it returns an empty features array with HTTP 200. If you get zero results, check the category name before assuming the area is empty.

Billing

Category search is billed per request, in the same geocode bucket as forward and reverse geocoding. It is not session-billed like autocomplete — there is no keystroke stream to amortise, each call is one query.

Errors

StatusMeaning
400category parameter missing.
401Token missing or invalid.
403Token lacks the geocode scope.