# POST /v1/reverse-geocode

> Index: https://kartpunkt.se/llms.txt

operationId: `reverseGeocode`. The nearest addresses to a point.
Tag: `addresses`.

The nearest current addresses to a WGS84 point, nearest first with their `distance_m`, and the nearest named road beside them as `road`. For a vehicle's position, choose the street it drove on from the results yourself: see the recipe "A vehicle's position". To find addresses from text, use `POST /v1/geocode`.

## Request

`POST https://api.kartpunkt.se/v1/reverse-geocode` with `Authorization: Bearer $KARTPUNKT_API_KEY` and `Content-Type: application/json`, from your backend (never browser code: the key would leak, and CORS is not enabled).

Example body:

```json
{
  "point": {
    "lat": 59.922385,
    "lon": 17.582745
  },
  "limit": 3
}
```

JSON body:

- `point` ([Point](https://api.kartpunkt.se/docs/shapes/Point.md), required)
- `types` (array of "address", at least 1, optional, default ["address"]): What to look for: addresses today, from Lantmäteriet's Belägenhetsadress or, for a kp_test_ key, the synthetic dataset. Place names and POIs join later.
- `limit` (integer 1..10, optional, default 1): How many addresses to return, nearest first. With distinct 'street' it counts streets: limit 3 answers the three nearest streets, one address each.
- `radius_m` (number <= 50000, optional, default 2000): Ignore addresses farther away than this, in straight-line metres. For a vehicle's position send "radius_m": 5000, "distinct": "street", "limit": 3, as the recipe "A vehicle's position" does: 5000 m reaches the nearest address from a rural road.
- `distinct` ("street", optional): Send 'street' for one address per street: the nearest address of each street within radius_m, nearest first, with limit counting streets. A street is one street name in one postort and one kommun, as a search street hit is. Left out, several results can lie on one street.

## Response 200

Example:

```json
{
  "results": [
    {
      "id": "se.syn.syn-0000t9b",
      "type": "address",
      "label": "Östra Ågatan 12B, 757 97 Uppsala",
      "street": "Östra Ågatan",
      "number": 12,
      "letter": "B",
      "postcode": "75797",
      "locality": "Uppsala",
      "municipality_code": "0380",
      "municipality": "Uppsala",
      "county_code": "03",
      "county": "Uppsala län",
      "district_code": "903801",
      "district": "Uppsala norra",
      "point": {
        "lat": 59.92238511056452,
        "lon": 17.582745460249157
      },
      "position_type": "entrance",
      "match_type": null,
      "score": 1,
      "distance_m": 0.03
    },
    {
      "id": "se.syn.syn-0000t9a",
      "type": "address",
      "label": "Östra Ågatan 12A, 757 97 Uppsala",
      "street": "Östra Ågatan",
      "number": 12,
      "letter": "A",
      "postcode": "75797",
      "locality": "Uppsala",
      "municipality_code": "0380",
      "municipality": "Uppsala",
      "county_code": "03",
      "county": "Uppsala län",
      "district_code": "903801",
      "district": "Uppsala norra",
      "point": {
        "lat": 59.92238919581831,
        "lon": 17.58281664402885
      },
      "position_type": "entrance",
      "match_type": null,
      "score": 1,
      "distance_m": 4.03
    },
    {
      "id": "se.syn.syn-0000t99",
      "type": "address",
      "label": "Östra Ågatan 12, 757 97 Uppsala",
      "street": "Östra Ågatan",
      "number": 12,
      "letter": null,
      "postcode": "75797",
      "locality": "Uppsala",
      "municipality_code": "0380",
      "municipality": "Uppsala",
      "county_code": "03",
      "county": "Uppsala län",
      "district_code": "903801",
      "district": "Uppsala norra",
      "point": {
        "lat": 59.92239328453523,
        "lon": 17.582887649142425
      },
      "position_type": "building",
      "match_type": null,
      "score": 1,
      "distance_m": 8.03
    }
  ],
  "road": {
    "name": "Östra Ågatan",
    "road_number": null,
    "road_class": 6,
    "speed_limit_kmh": 50,
    "speed_limit_varies": false,
    "owner": "municipal",
    "surface": "paved",
    "municipality_code": "0380",
    "distance_m": 22.02,
    "fallback": false
  },
  "provenance": {
    "synthetic": true,
    "network": {
      "id": "snap_01k7exampleexampleexample0",
      "dataset": "nvdb",
      "source_date": "2026-10-13",
      "built_at": "2026-10-13T07:00:00.000Z",
      "graph": "snap_01k7exampleexampleexample0"
    },
    "sources": [
      {
        "id": "synthetic",
        "name": "Kartpunkt synthetic test addresses",
        "licence": "CC0-1.0",
        "attribution": "Syntetiska testadresser från Kartpunkt, inte verkliga adresser.",
        "url": "https://creativecommons.org/publicdomain/zero/1.0/",
        "updated": "2026-10-13"
      },
      {
        "id": "nvdb",
        "name": "Trafikverket, NVDB",
        "licence": "CC0-1.0",
        "attribution": "Vägdata från NVDB, Trafikverket, CC0 1.0",
        "url": "https://creativecommons.org/publicdomain/zero/1.0/",
        "updated": "2026-10-13"
      }
    ]
  }
}
```

- `results` (array of [Address](https://api.kartpunkt.se/docs/shapes/Address.md)): The nearest addresses, nearest first.
- `road` (object | null): The nearest road a car can use with a name or number, within 100 m of the point; null when none is, or no road graph is built yet. It is NVDB's real road for every key. It has no id and is not counted in results. To choose it or an address, see the recipe "A vehicle's position".
  - `name` (string | null): The road's street name (gatunamn), the name addresses on it are formed with, else its other official name. null when the road has only a number.
  - `road_number` (string | null): The road's number as signed, e.g. 'E6' for a europaväg or '158'; null when it has none. Never null together with name.
  - `road_class` (integer 0..9 | null): Functional road class (funktionell vägklass) as Trafikverket delivers it, from 0 for the roads most important to the whole network, such as motorways, to 9 for the least. 0-2 is a through road and 6-9 a local street; null when the road has none.
  - `speed_limit_kmh` (integer | null): The base speed limit (hastighetsgräns) in km/h, e.g. 50, where the road is nearest the point, whatever the time of the call. A point has no direction of travel, so where the two directions have different limits this is the lower. null where no limit is recorded or the limit is gångfart (walking pace), which has no figure.
  - `speed_limit_varies` (boolean): true when the stretch also has a limit that applies only at certain times or to certain vehicles, which this answer does not carry: a summer limit, a lower limit on weekday mornings or one for heavy vehicles. false otherwise, and when no limit is recorded.
  - `owner` ("state" | "municipal" | "private" | null): The road owner (väghållare), who keeps the road where it is nearest the point: 'state' (Trafikverket), 'municipal' (a kommun) or 'private' (a road association, a company or a person). The kind only, never who; null where none is recorded.
  - `surface` ("paved" | "gravel" | null): The surface (slitlager) where the road is nearest the point: 'paved' or 'gravel'; null where none is recorded.
  - `municipality_code` (string | null): Kommunkod, four digits, e.g. '1080': the kommun NVDB registers the road's stretch in, never the kommun's name; null where none is recorded. It is a fact about the road, so near a kommun border it can differ from results[0].municipality_code.
  - `distance_m` (number): Straight-line metres (spheroidal) from the point sent to the nearest point of the road.
  - `fallback` (boolean): true when no address in results is within 50 m of the point: results is empty, or its first address is farther away.
- `provenance` ([Provenance](https://api.kartpunkt.se/docs/shapes/Provenance.md))

## Errors

Every error is `{ error, message, param?, doc_url }`; `message` says what to do next. All codes: [https://api.kartpunkt.se/errors](https://api.kartpunkt.se/errors). What to do on each, with retries: [https://api.kartpunkt.se/docs/recipes/errors-and-retries.md](https://api.kartpunkt.se/docs/recipes/errors-and-retries.md).

- [`invalid_request`](https://api.kartpunkt.se/errors/invalid_request) (400): The request does not match the API schema. Fix the fields named in this message; see /openapi.json.
- [`unauthorized`](https://api.kartpunkt.se/errors/unauthorized) (401): Missing or unknown API key. Send it as 'Authorization: Bearer <key>' (or 'x-api-key'), read from the KARTPUNKT_API_KEY environment variable. The user creates a kp_test_ key on their Kartpunkt account page (https://kartpunkt.se/konto) and puts it in KARTPUNKT_API_KEY themselves; never ask them to paste a key into chat.
- [`live_access_required`](https://api.kartpunkt.se/errors/live_access_required) (403): This account is not approved for live data: kp_live_ keys are for customers under contract. Use a kp_test_ key. To ask for live access, the account holder writes to hej@kartpunkt.se, or orders a plan at https://kartpunkt.se/konto#plan.
- [`use_not_permitted`](https://api.kartpunkt.se/errors/use_not_permitted) (403): This operation would use a data source in a way its licence or approval does not allow (see GET /v1/sources). It cannot be answered for this key.
- [`quota_exceeded`](https://api.kartpunkt.se/errors/quota_exceeded) (429): Request limit or plan quota reached (per minute, per day, or the account plan's monthly quota). Wait the number of seconds in the Retry-After header, then retry; without Retry-After, no wait helps: tell the account holder what this message says.
- [`internal_error`](https://api.kartpunkt.se/errors/internal_error) (500): Something failed on our side. Retry after a few seconds; if it keeps failing, contact hej@kartpunkt.se.
- [`live_data_unavailable`](https://api.kartpunkt.se/errors/live_data_unavailable) (503): Live data is not available yet: it opens when Kartpunkt's import of Lantmäteriet's address register completes. Use a kp_test_ key until then.

## Limits

| Limit | Synchronous |
| --- | --- |
| `limit` (at most) | 10 |
| `radius_m` (at most) | 50000 |
| Request body | 1 MB |

## Metering

With a `kp_live_` key, one live call per request; each address in the answer counts toward the plan's daily address limit.
