# Kartpunkt
> Official Swedish addresses as an API, from Lantmäteriet's address register
> (Belägenhetsadress): search and autocomplete, reverse geocoding,
> validation, change tracking and postnummer lookup. Trafikverket's road
> network (NVDB) as primitives: snap, roads with their facts, routes,
> distances, matrices, reach, GPS traces and route optimization. Each answer
> names the network snapshot it was computed on. Hosted in the EU.
Status: live. `kp_live_` keys answer from Lantmäteriet's address register:
about 3.85 million current addresses, published weekly by Lantmäteriet
and checked for daily. A live key answers once its account is
approved for live access and has a plan (`/konto`). Otherwise it is refused
with a code and a message that says what to do. `kp_test_` keys answer from
a synthetic dataset with the same shapes, on NVDB's real roads, and their
answers carry `provenance.synthetic: true`. Build against a test key;
switching to a live key changes nothing else. On the free Utvecklare plan
an account's test keys share 2000 calculations a month and cannot submit
jobs. On a paid plan (Bas, Pro or Avtal) they submit jobs and use the
plan's calculations, as live keys do.
## When to use Kartpunkt
Use it when your code needs Swedish street addresses from the official
register, or facts and routes on Sweden's road network:
- Address search and autocomplete in a Swedish address form
(`POST /v1/geocode`).
- Turning a coordinate into an address, for example a vehicle's position
(`POST /v1/reverse-geocode`; see the recipe "A vehicle's position").
- Checking an address a customer typed, at checkout or sign-up, before you
ship to it or store it (`POST /v1/addresses/validate`).
- Postnummer to postort and kommun (`GET /v1/postcodes/{postcode}`).
- Keeping addresses you stored current (`POST /v1/addresses/changes`).
- Reading the address a stored id names, now or as it was at a date
(`POST /v1/addresses/lookup`).
- Distances along the roads from many origins to one or a few destinations
(`POST /v1/distances`), and the route itself between two points to draw on
a map (`POST /v1/route`), for example for trip logs (körjournal).
- Routes on several profiles, lorries and buses included, with facts such
as speed limits, owner or bearing class along them.
- Distance matrices (`POST /v1/matrix`), the area reachable within minutes
or metres (`POST /v1/reach`), matching a GPS trace to the roads it
travelled (`POST /v1/trace`), the roads at a point
(`POST /v1/roads/nearby`), and NVDB vector tiles for a map
(`GET /v1/tilesets`).
- Planning vehicles' routes over stops and shipments: which vehicle visits
which, in what order and when, with capacities, time windows and skills
(`POST /v1/optimize`), and checking a plan you have, or one a person
changed, on the same terms (`POST /v1/optimize/check`).
Do not use it for:
- Addresses outside Sweden. Only Swedish addresses are in the register.
- Place, business or point-of-interest names, turn-by-turn directions, or base
map tiles (the only tiles are NVDB's roads, `GET /v1/tilesets`).
- Box addresses. A postnummer used only for PO boxes is not in the register.
- People. There are no owner, resident or tenure data.
- Copying the register. Bulk or sequential harvesting is not allowed.
- Calls from browser code. Call it from your backend.
## Terms
Words used in one sense throughout:
- **Answers.** What a call returns with a 200; a refused call returns an
error instead, a 4xx or 5xx with a code from the error table.
- **A status is an answer.** Many results carry a `status`, and only `ok`
carries a path or a value. A 200 with another status, such as `no_path`
or `avoided_road_required`, is an answer, not an error.
- **Meets the network.** Every point routed from or to is moved onto a road
of the profile: the road its `street` names when one is near, else the
nearest. The path starts or ends where it meets the network.
- **Kept off.** A road `avoid` keeps off is never travelled along; an entry
in `mode: "barrier"` is not crossed at grade either.
- **Snapshot.** One immutable build of NVDB's road network, named by
`provenance.network.id` with its NVDB `source_date`. Sending that id as
`network` answers on the same roads while that snapshot is served.
- **Calculation.** The unit plans meter routing and planning in, counted on
every key of an account, `kp_test_` keys included. Each operation's page
says how it counts under Metering.
- **Synthetic.** A `kp_test_` key's addresses come from a synthetic dataset:
they look real and do not exist. Its roads are NVDB's real ones.
- **Stretch.** A length of one road. In `avoid.stretches` it is a GeoJSON
LineString you draw along a road; a `ref` (RoadRef) names one by its NVDB
link and measures.
- **Segment.** One piece of a route or a matched trace, on one stretch, with
its `length_m`, `ref`, facts and `geometry`. A route's `segments` run in
order from origin to destination.
- **Points.** Every point is `{ lat, lon }`, an address's `point` included.
Every end routed from or to is a StreetPoint, `{ lat, lon, street? }`; a
trace's points are `{ lat, lon, time? }`.
- **Lengths.** Every length is metres, and its name says what it measures:
- `distance_m` on a route, a distances result, a trace, a nearest bus stop
or a matrix cell (`distances_m`) is metres along the network.
- `distance_m` on an address or a road found near a point you sent is the
straight line to it: geocode with `near`, reverse geocoding, roads
nearby.
- `snap_m` is the straight line from a point you sent to where it meets
the network, `/v1/snap` included. It is never part of `distance_m`.
- `length_m` is a segment's or a stretch's own length.
- `radius_m` bounds a straight-line search round a point you sent: snap,
roads nearby, reverse geocoding. `max_distance_m` bounds a distance
along the network.
## Rules for agents
### Before the first call
- Read the key from the environment variable `KARTPUNKT_API_KEY`. Never ask
the user to paste it into chat, and never hardcode it.
- Check auth first: `GET /v1/postcodes/75331` must return 200 before you
write integration code. A 401 means the key is missing or wrong, and a 403
means a `kp_live_` key's account is not approved for live data. A 429
without `Retry-After` means its account has no plan with live calls yet.
- Build and test with a `kp_test_` key. Synthetic addresses look real but
do not exist: never store them as real addresses or show them to end
users as real. A route or a distance marked synthetic is a real one, on
the network a `kp_live_` key routes on, and a synthetic address far from
any road answers `no_road_near`.
- Every answer to a `kp_test_` key says `provenance.synthetic: true`, a
route with no address in it too. `provenance.sources[].id` names the data
an answer rests on: `synthetic` for synthetic addresses, `lantmateriet`
for live ones, `nvdb` for the road network.
- Read the registries before you hard-code a name: `GET /v1/profiles`,
`GET /v1/facts` (every fact with its kind and unit), `GET /v1/sources`
(each source's licence, attribution and allowed uses) and
`GET /v1/networks` (the snapshots). They take a key like every call.
### Every answer
- Every answer from the network or the address register carries
`provenance`: `synthetic`, `network` and `sources[]`. `network` is the
snapshot's `id`, its NVDB `source_date`, `built_at`, `graph`, `profile`
and `experimental`; each source has `licence`, `attribution` and
`updated`, the date of the data you were given. Store `provenance` with
the answer.
- Show every `sources[].attribution` wherever the data is shown: CC BY 4.0
requires it for Lantmäteriet's addresses. The `X-Data-Attribution` header
carries the same texts in ASCII (å→a, ä→a, ö→o, ©→(c)), so show the
body's exact text, not the header's. `X-Kartpunkt-Network` carries the
snapshot's id.
- When a `status` is not `ok`, draw nothing and show the status, and read
an unknown status the same way. Do not retry it: it is an answer.
- Every `POST` takes a JSON body with `Content-Type: application/json`, so a
position or the text a person typed never sits in a URL, which proxies
and logs keep. `GET` paths carry only ids, a road reference or a
postnummer.
- Every error is `{ error, message, param?, doc_url }`: `message` says what
to do next, and `doc_url` is the code's page. Invalid input is 400
`invalid_request`, whose message names each field by its path
(`origins.0.point.lat`) and the rule it breaks, and `param` the field
refused: fix those fields. A field an operation does not take is refused
the same way, never ignored.
- On 429, wait `Retry-After` seconds when it is a minute or less, then send
the call again. A longer `Retry-After` is a daily or monthly quota, and a
429 without `Retry-After` is not fixed by waiting: tell the user what the
message says. A plan is ordered by the account holder, never by you.
- One calculation runs at a time: on 503 `routing_unavailable` with
`Retry-After`, wait that many seconds and send the call again. Every
code's handling is the recipe
[Errors and retries](https://api.kartpunkt.se/docs/recipes/errors-and-retries.md).
### Addresses
- Addresses are single answers, as Lantmäteriet's approval requires: one
search, one point, one address or a few stored ids per call, within each
page's Limits. Your own list is the one exception, as an `address_list`
job; there is no address export and no sweep of addresses you were not
sent. A use a source's terms do not allow is 403 `use_not_permitted`.
- Send your own address list (a register, collection points, a month of
trips) as one job, never as a loop of synchronous calls: `POST /v1/jobs`
with `operation: "address_list"` and
`input: { kind: "validate" | "geocode" | "reverse", rows }`, up to 50000
rows. The result has one row per row sent, in order, with your `id`, a
`status` and the address only when `matched`; never candidates. Every row
counts as one live call and one address, held at submit, so split a list
longer than today's address limit across days.
- Store `id` and `label` from address results; `id` is stable across weekly
refreshes. Store the address source's `provenance.sources[].updated` with
them too.
- Keep stored addresses current with `POST /v1/addresses/changes`, weekly
at most: what to send and what to do with each status is the recipe
[Keeping stored addresses current](https://api.kartpunkt.se/docs/recipes/keeping-stored-addresses-current.md).
- To try every status with a `kp_test_` key, send as `since` the day before
the `updated` date of any answer to that key, and the ids
`se.syn.synh-0380-0001` (answers `changed`: its postnummer changed),
`se.syn.synh-riv-0002` (`closed`) and `se.syn.synh-riv-0001` (`unchanged`).
- `position_type` says what an address's point marks, or `null` where the
register does not say. An `approximate` point was placed only roughly: do
not rely on it where the metre matters. Treat an unknown value as `other`.
- `match_type` on a geocode or validate address: accept `exact`, have a
person confirm `corrected`, a word read as a misspelling, and show
`partial` as a suggestion. Treat an unknown value as `partial`; it is
`null` on reverse geocoding, so read `distance_m` there.
- Neither changes ranking, validation or `score`. Report per län or
distrikt from `county_code` and `district_code`, either may be `null`;
never derive a län from the kommunkod.
- For a vehicle's position, send
`{"point": {"lat": …, "lon": …}, "radius_m": 5000, "distinct": "street", "limit": 3}`
to `POST /v1/reverse-geocode`. Your code then chooses the street it drove
on from the results and `road`, as the recipe
[A vehicle's position](https://api.kartpunkt.se/docs/recipes/a-vehicle-s-position.md)
says. On `road.fallback`, store the road (its `name`, else its
`road_number`) with its `road.municipality_code`: near a kommun border it
can differ from `results[0].municipality_code`.
- `{"point": {"lat": 59.8586, "lon": 17.6389}}` (Svartbäcksgatan 1, Uppsala)
shows both: its three nearest addresses lie on two streets, and `road` is
Svartbäcksgatan, so the choice stores Svartbäcksgatan 1. With a `kp_test_`
key the addresses are synthetic and `road` is a real road from NVDB, so
`provenance.sources` credits NVDB after Kartpunkt's synthetic source.
### Roads and routing
- Profiles: `walk`, `car_shortest`, `car_fastest`, `hgv` and `bike`.
`bike`, the shortest way by bicycle timed at 16 km/h, is experimental and
not yet checked on the national network: its answers say
`provenance.network.experimental: true`, so show that its routes are
experimental.
- On `hgv`, send the vehicle as `vehicle`, the Vehicle shape: weight, axle
load, height, width, length, hazmat, kind and bearing class.
- Reach's budget is `{ "duration_s": [...] }` or `{ "distance_m": [...] }`,
one area per value. A `duration_s` budget needs a profile weighed by time or at one
pace (`car_fastest`, `hgv`, `walk`, `bike`); `car_shortest` takes
`distance_m` only.
- Facts: send the keys you need as `facts`, none by default, on
`/v1/route`, `/v1/distances`, `/v1/trace` and `/v1/roads/nearby`. Each
segment carries each fact's value on it, and `facts` sums each one over
the path by the fact's kind: metres per value, a `{min, max, unknown_m}`
range, metres or a count.
- A fact states what NVDB records, never a verdict. `fast_road` or
`unlit_outside_built_up` is metres, not whether a route is safe, which is
your assessment, and `bearing_class` is a class, not a weight a road may
carry. Timed restrictions (`timed_restriction`, with its window) are
reported, never routed around.
- `separated` counts walk or cycle links NVDB records as separated from
traffic. It never says a road has a path beside it.
- To draw the route between two points, such as a trip by car or a walk,
send `origin`, `destination`, any `via` and a `profile` to
`POST /v1/route`, and draw its `segments` in order when `status` is `ok`.
`duration_s` is free-flow at the speed limits, 5 km/h on foot, not a
prediction. The steps are the recipe
[Drawing a route](https://api.kartpunkt.se/docs/recipes/drawing-a-route.md).
- Route, distances and matrix take the same routing options: `profile`,
`vehicle`, `avoid` and `prefer`. `prefer: [{ fact: "fast_road" }]`, on any
profile, answers the route whose cost is least when each metre with the
fact costs 2, or `cost` above 1 and at most 10, and every other metre 1.
Without `prefer` the call answers the shortest, so ask both and show both.
- `avoid` keeps a path off stretches you draw, off facts and off roads by
number; the answer is the path that keeps off all of it, beside
`alternatives.unrestricted`. Where only what is kept off joins the two
ends, the status is `avoided_road_required`, with `blocked_by` naming each
entry in the way: show it to whoever decides rather than guessing. Each
kind, barriers and a closure between two places included, is in the
recipe [Keeping paths off roads](https://api.kartpunkt.se/docs/recipes/keeping-paths-off-roads.md).
- Every StreetPoint takes an optional `street`: it then meets the road of
that name when one is near, else the nearest road. The answer gives
`snap_m` and `street_matched` for each end: on the path on route and
distances (`destination_snap_m` and `destination_street_matched` for the
destination), per point on snap and nearest. Send the street whenever you
know it, since an address point is often nearer another street's road.
- For distances along the roads from many origins to one to five
destinations, send `destinations`, `origins` and a `profile` to
`POST /v1/distances`. Origins are points: the API takes no address ids for
distances. Every origin is answered in `results`, one entry per
destination, each with its own `status`; how to read, match and store them
is the recipe
[Many origins to a few destinations](https://api.kartpunkt.se/docs/recipes/many-origins-to-a-few-destinations.md).
- To find what is nearest each point along the network, bus stops today,
send `kind: "bus_stop"` and `points` to `POST /v1/nearest`. Its distances
are metres along the network by the profile, `walk` unless sent, never a
straight line.
- Road references: every segment and road has `ref`, a string
`@-`: an NVDB link sequence and the measures 0-1 it covers,
six decimals, e.g. `1000123:45@0.250000-0.500000`. It names the same
stretch in every snapshot that holds its link, so store it as the road's
identity and read it back with `GET /v1/roads/{ref}`, URL-encoded, its
facts as one query parameter per key: `?facts=speed_limit&facts=surface`.
Never parse it or derive anything from its parts; it is `null` on a road
with no NVDB link, as on the synthetic dataset's own roads.
- Leave `network` out to answer on the snapshot served now. Send
`network: {"id": ""}` to answer on the network an
earlier answer used while it is served, or
`network: {"as_of": ""}` for the one served at a moment,
never both. A synchronous call on a snapshot no longer served is 409
`network_not_active`, and a job on it answers only while its graph runs
on the current engine, else the job fails `snapshot_engine_unavailable`, as the recipe
[Errors and retries](https://api.kartpunkt.se/docs/recipes/errors-and-retries.md)
says with the other network refusals.
### Jobs and limits
- Each operation's page has a Limits table, synchronous and as a job. Above
the synchronous limits a call answers 413 `too_large`, or 400
`invalid_request` naming the field: send the same input as a job. Never
split an input into many synchronous calls to avoid a job, whatever the
operation.
- Any of the eight job operations, the ones the `POST /v1/jobs` page
lists, runs as a job with the same input. Submit it, wait for it and read
it as the recipe
[Running a job](https://api.kartpunkt.se/docs/recipes/running-a-job.md)
says, always with an `idempotency_key`. Keys are per account, and an
account reads its own jobs only.
- Jobs need a paid plan: a `kp_test_` key on the free Utvecklare plan is
refused 403 `live_access_required`, whatever the operation. Tell the
account holder, who orders a plan on https://kartpunkt.se/konto#plan or
at hej@kartpunkt.se.
- Jobs run behind synchronous calls on the same routing engine: a job's
next chunk waits while a synchronous calculation runs, so a job slows down
under load but never fails for it. Keep interactive calls synchronous and
send batches as jobs.
- Send every body as plain JSON; a compressed body is not accepted.
`POST /v1/jobs` takes up to 8 MB and every other call up to 1 MB: 50000
origins fit with an id and a street of a few dozen characters each. A
larger body is 413 `too_large`: split the origins over several jobs.
- Each account has a daily request limit, and a `kp_live_` key the quotas
of the account's plan: live calls a month, counted by every address
operation, and returned addresses a day, by every address operation but
postnummer lookup. Past a quota a call is 429 `quota_exceeded`, with
`Retry-After` to 00:00 UTC, or to 00:00 UTC on the 1st for a monthly one.
- Calculations a month count every key of the account, as each operation's
page says under Metering. A job counts its input's, once, when it is
submitted. The free Utvecklare
plan has 2000 a month, Bas 5000, Pro 50000, and the Routes & distances
add-on 50000 more (https://kartpunkt.se/konto#plan).
### What not to send
- Do not send protected identities (skyddade personuppgifter) to the API.
Send coordinates only, never who lives there, and leave out anyone with a
protected identity.
- Coordinates go in JSON bodies only. A trace is used for its answer and
never stored or logged.
- Call the API from server-side code only, never from browser code: the key
would leak, and CORS is not enabled. Proxy autocomplete through your
backend.
- Never loop over a list of addresses to geocode it in bulk: sequential or
bulk harvesting is not allowed, and keys that sweep will be revoked. Call
the API only for addresses a user actually needs.
## Getting a key
The user signs in at [kartpunkt.se/konto](https://kartpunkt.se/konto) (with
Google), creates a `kp_test_` key there and puts it in the project's `.env` as
`KARTPUNKT_API_KEY=…` themselves. Ask them to do that; never ask them to paste
the key into chat, and never write a key into code or commit it. The same
page shows each key's last use, the account's usage per day and operation,
and revokes keys. (Running Kartpunkt locally:
[127.0.0.1:3110/konto](http://127.0.0.1:3110/konto).)
For the person you work for, the same reference is at
[api.kartpunkt.se/docs](https://api.kartpunkt.se/docs), with try-it: they
enter a `kp_test_` key in the page's authentication field, in their own
browser. You do not need it: the pages this index links and
[openapi.json](https://api.kartpunkt.se/openapi.json) say everything it
does.
## Operations
One Markdown page per operation: its request, fields, response, errors, limits and metering. Base URL https://api.kartpunkt.se. Auth: `Authorization: Bearer $KARTPUNKT_API_KEY` or `x-api-key: $KARTPUNKT_API_KEY`, from your backend only. Coordinates are WGS84 `lat` and `lon` decimals. The same operations, machine-readable: [openapi.json](https://api.kartpunkt.se/openapi.json).
Response headers: `X-Data-Attribution` (the attribution texts in ASCII: å→a, ä→a, ö→o, ©→(c); show the body's exact `provenance.sources[].attribution`), `RateLimit-Policy` and `RateLimit` (draft-ietf-httpapi-ratelimit-headers: `"minute";q=;w=60` and `"minute";r=;t=`), `Retry-After` (on 429, and on 503 `routing_unavailable` when a distance calculation is running). Every answer computed on the network or the address register carries `provenance` and the header `X-Kartpunkt-Network` when a network snapshot was used.
### registries
What the API answers on: profiles, facts, sources and their terms, vector tiles, and the network snapshots.
- [GET /v1/profiles](https://api.kartpunkt.se/docs/operations/listProfiles.md): The routing profiles.
- [GET /v1/facts](https://api.kartpunkt.se/docs/operations/listFacts.md): The facts catalog.
- [GET /v1/sources](https://api.kartpunkt.se/docs/operations/listSources.md): The data sources and their terms.
- [GET /v1/tilesets](https://api.kartpunkt.se/docs/operations/listTilesets.md): NVDB vector tiles.
- [GET /v1/networks](https://api.kartpunkt.se/docs/operations/listNetworks.md): Network snapshots.
- [GET /v1/networks/{id}](https://api.kartpunkt.se/docs/operations/getNetwork.md): One network snapshot.
### addresses
Swedish addresses from Lantmäteriet's register: search, reverse geocoding, validation, change tracking and postnummer.
- [POST /v1/geocode](https://api.kartpunkt.se/docs/operations/searchAddresses.md): Search and autocomplete locations.
- [POST /v1/reverse-geocode](https://api.kartpunkt.se/docs/operations/reverseGeocode.md): The nearest addresses to a point.
- [POST /v1/addresses/validate](https://api.kartpunkt.se/docs/operations/validateAddress.md): Validate an address.
- [POST /v1/addresses/changes](https://api.kartpunkt.se/docs/operations/checkAddressChanges.md): What changed for stored addresses.
- [POST /v1/addresses/lookup](https://api.kartpunkt.se/docs/operations/lookupAddress.md): One address by its id.
- [GET /v1/postcodes/{postcode}](https://api.kartpunkt.se/docs/operations/lookupPostcode.md): A postnummer's postorter and kommuner.
### roads
The road network (NVDB) as roads: where points meet it, roads near a point and a road by its reference, with facts.
- [POST /v1/snap](https://api.kartpunkt.se/docs/operations/snapPoints.md): Meet points to the road network.
- [POST /v1/roads/nearby](https://api.kartpunkt.se/docs/operations/listRoadsNearby.md): Roads near a point, with facts.
- [GET /v1/roads/{ref}](https://api.kartpunkt.se/docs/operations/getRoad.md): A road by its reference.
### routing
Paths along the network: a route, distances, nearest points, matrices, reachable areas and GPS traces.
- [POST /v1/route](https://api.kartpunkt.se/docs/operations/planRoute.md): A route, with facts along it.
- [POST /v1/distances](https://api.kartpunkt.se/docs/operations/measureDistances.md): Distances from many origins to their destinations.
- [POST /v1/nearest](https://api.kartpunkt.se/docs/operations/findNearest.md): What is nearest each point along the network.
- [POST /v1/matrix](https://api.kartpunkt.se/docs/operations/buildMatrix.md): An origins × destinations matrix.
- [POST /v1/reach](https://api.kartpunkt.se/docs/operations/measureReach.md): What can be reached within a budget.
- [POST /v1/trace](https://api.kartpunkt.se/docs/operations/matchTrace.md): The roads a GPS trace travelled, with facts.
### planning
Vehicles' routes over stops and shipments: a plan optimized, or a given plan checked.
- [POST /v1/optimize](https://api.kartpunkt.se/docs/operations/optimizeRoutes.md): Plan vehicles' routes over stops and shipments.
- [POST /v1/optimize/check](https://api.kartpunkt.se/docs/operations/checkPlan.md): Check a given plan of vehicles' routes.
### jobs
Any routing or planning call as a job, for inputs above the synchronous limits.
- [POST /v1/jobs](https://api.kartpunkt.se/docs/operations/submitJob.md): Run an operation as a job.
- [GET /v1/jobs/{id}](https://api.kartpunkt.se/docs/operations/getJob.md): A job, with its result once done.
- [DELETE /v1/jobs/{id}](https://api.kartpunkt.se/docs/operations/cancelJob.md): Cancel a job.
## Shapes
The named shapes the operations use, one page each.
- [ErrorBody](https://api.kartpunkt.se/docs/shapes/ErrorBody.md): Every error response: a stable code, what to do next, the field refused, and the code's page.
- [Profile](https://api.kartpunkt.se/docs/shapes/Profile.md): A routing profile: who travels, which roads they may use and how a path is weighed.
- [Provenance](https://api.kartpunkt.se/docs/shapes/Provenance.md): What an answer was computed from: the network snapshot, the sources read, and whether its data is synthetic.
- [SourceRef](https://api.kartpunkt.se/docs/shapes/SourceRef.md): A data source an answer read, with how to credit it.
- [Address](https://api.kartpunkt.se/docs/shapes/Address.md): An address point or a street-level hit.
- [Point](https://api.kartpunkt.se/docs/shapes/Point.md): A WGS84 coordinate.
- [AddressChange](https://api.kartpunkt.se/docs/shapes/AddressChange.md): What happened to one id sent, comparing what was served at `since` with what is served now.
- [StreetPoint](https://api.kartpunkt.se/docs/shapes/StreetPoint.md): A WGS84 coordinate, with the street it lies on when known.
- [NetworkSelector](https://api.kartpunkt.se/docs/shapes/NetworkSelector.md): The network snapshot to answer on, by id or as_of, one of the two.
- [RoadRef](https://api.kartpunkt.se/docs/shapes/RoadRef.md)
- [Vehicle](https://api.kartpunkt.se/docs/shapes/Vehicle.md): The vehicle's weight, dimensions and kind, on a profile whose `takes_vehicle` is true in GET /v1/profiles (hgv).
- [Avoid](https://api.kartpunkt.se/docs/shapes/Avoid.md): What the path keeps off, on any profile; left out or empty, nothing.
- [AvoidFact](https://api.kartpunkt.se/docs/shapes/AvoidFact.md): A fact to keep off, by its key among those GET /v1/facts marks avoidable.
- [AvoidValue](https://api.kartpunkt.se/docs/shapes/AvoidValue.md): A road kept off by its value, with no line drawn: { fact: 'road_number', values: ['E20', '47'], mode: 'barrier' }, or only between two points on it: { fact: 'road_number', values: ['113'], between:…
- [Preference](https://api.kartpunkt.se/docs/shapes/Preference.md): A fact to prefer to keep off: { fact: 'fast_road', cost: 2 }.
- [FactSummary](https://api.kartpunkt.se/docs/shapes/FactSummary.md): A fact summed over a path: metres per value for a category, {min, max, unknown_m} for a measure, metres for a flag, or a count.
- [SnapResult](https://api.kartpunkt.se/docs/shapes/SnapResult.md): Where a point sent met the network.
- [Segment](https://api.kartpunkt.se/docs/shapes/Segment.md): A stretch of a path: its metres, its road reference, the facts asked for and its line.
- [Path](https://api.kartpunkt.se/docs/shapes/Path.md): A path between two ends, and why there is none where there is none.
- [TracePoint](https://api.kartpunkt.se/docs/shapes/TracePoint.md): A GPS fix: a WGS84 coordinate, with its time when known.
- [AddressIdPlace](https://api.kartpunkt.se/docs/shapes/AddressIdPlace.md): fields `{ address_id, as_of }`.
- [Unreachable](https://api.kartpunkt.se/docs/shapes/Unreachable.md): Why a task no vehicle takes is out of reach, and where its place met the network.
- [Unresolved](https://api.kartpunkt.se/docs/shapes/Unresolved.md): fields `{ place, cause }`.
- [Job](https://api.kartpunkt.se/docs/shapes/Job.md): A job: its operation, status and times, and its result once succeeded.
- [JobCheck](https://api.kartpunkt.se/docs/shapes/JobCheck.md): A job checked and not queued (dry_run): a submit of the same body now would be accepted.
## Recipes
Kartpunkt's operations are general. These are the calls for common uses,
built only from the rules above, one page each.
- [Errors and retries: what to do with each refusal](https://api.kartpunkt.se/docs/recipes/errors-and-retries.md)
- [Keeping paths off roads: avoid, barriers and closures](https://api.kartpunkt.se/docs/recipes/keeping-paths-off-roads.md)
- [Drawing a route: segments and geometry](https://api.kartpunkt.se/docs/recipes/drawing-a-route.md)
- [Address ids: store the id, read the address when you need it](https://api.kartpunkt.se/docs/recipes/address-ids.md)
- [Many origins to a few destinations: distances along the roads](https://api.kartpunkt.se/docs/recipes/many-origins-to-a-few-destinations.md)
- [Trip logs (körjournal): a trip's start and end address](https://api.kartpunkt.se/docs/recipes/trip-logs.md)
- [Route optimization (ruttoptimering): vehicles over stops](https://api.kartpunkt.se/docs/recipes/route-optimization.md)
- [Check or compare a plan](https://api.kartpunkt.se/docs/recipes/check-or-compare-a-plan.md)
- [Running a job: submit, wait, read, cancel](https://api.kartpunkt.se/docs/recipes/running-a-job.md)
- [A vehicle's position](https://api.kartpunkt.se/docs/recipes/a-vehicle-s-position.md)
- [Keeping stored addresses current](https://api.kartpunkt.se/docs/recipes/keeping-stored-addresses-current.md)
- [Your own address list: one job, one row per row](https://api.kartpunkt.se/docs/recipes/your-own-address-list.md)
- [When there is no path: a path's status and what to send next](https://api.kartpunkt.se/docs/recipes/when-there-is-no-path.md)
## Errors
Every error is JSON `{ error, message, param?, doc_url }`. `error` is a stable code; `message` says what to do next; `param` names the refused field of an invalid request; `doc_url` is the code's page. Every code, with its status and message: [https://api.kartpunkt.se/errors](https://api.kartpunkt.se/errors). Each operation's page lists the codes it answers.
## Optional
- [Account and keys](https://kartpunkt.se/konto): sign in, create a `kp_test_` key, see usage, revoke keys (Swedish).
- [Developers](https://kartpunkt.se/en/developers.md): the developer page, with the first three steps and the plan limits.
- [Pricing](https://kartpunkt.se/en/pricing.md): the plans and what each includes.
- [Utvecklare](https://kartpunkt.se/utvecklare.md): the developer page in Swedish, with the prompt to paste into an agent.
- [API reference for people](https://api.kartpunkt.se/docs): the OpenAPI document rendered, with try-it for a `kp_test_` key.
- [llms-full.txt](https://kartpunkt.se/llms-full.txt): this index, every page above and the site's pages in Markdown, in one file.
- [Contact](mailto:hej@kartpunkt.se): Zephyr Valley AB, hej@kartpunkt.se.