Migrating to Geocoder v3
Geocoder v3 is a new version of Entur's geocoding API with cleaner parameter names, structured response objects, and unambiguous IDs. This guide maps every v2 parameter and response field to its v3 equivalent.
See also the Geocoder v3 documentation.
Parameter changes
Common (autocomplete + reverse)
| v2 | v3 | Notes |
|---|---|---|
size | limit | |
lang | lang | unchanged; also accepted on /place |
layers | layers | see layers |
sources | sources | see sources |
boundary.country | countries | comma-separated |
boundary.county_ids | counties | comma-separated |
boundary.locality_ids | localities | comma-separated |
tariff_zone_ids | (removed) | use fareZones instead |
| (new in v3) | fareZones | comma-separated; refs must be FareZone-shaped (AUTH:FareZone:ID). |
tariff_zone_authorities | (removed) | use fareZoneAuthorities instead |
fare_zone_authorities | fareZoneAuthorities | comma-separated |
multiModal | multimodal | values: parent (default), child, all; see multimodal |
categories (v2 reverse only) | stopPlaceTypes | NeTEx stop place types; see below |
stopPlaceTypes takes NeTEx stop place types (railStation, airport, ...). On its own it restricts results to stop places of those types and excludes other layers - same semantics as v2 categories. The v2 layer-like category values (street, vegadresse, GroupOfStopPlaces, poi) map to layers instead.
Combine stopPlaceTypes with an explicit layers filter to mix mode-filtered stop places with whole layers in one request. The two compose as a union: the type filter constrains only the stopPlace layer, while any other requested layer is returned additively. To get rail stations together with groups of stop places (v2's categories OR behaviour, in a single request):
Code
If layers is given but does not include stopPlace, the type filter has no stopPlace layer to constrain and is ignored.
Autocomplete (/v3/autocomplete)
| v2 | v3 | Notes |
|---|---|---|
text | q | optional in v3: omitting q with at least one filter lists all matching places |
focus.point.lat | lat | focus point latitude |
focus.point.lon | lon | focus point longitude |
focus.scale | radius | focus radius in km (default 50, decimals accepted); see default differs from v2 |
focus.weight | weight | 0-1 (default 0.5); see weight semantics |
focus.function | (removed) | v2's focus.function (linear, exp, etc.) is removed; v3 behaves roughly like v2's exp |
| (new in v3) | bbox | restrict results to minLon,minLat,maxLon,maxLat - a hard filter, unlike the focus point's soft bias |
Reverse (/v3/reverse)
| v2 | v3 | Notes |
|---|---|---|
point.lat | lat | query point latitude |
point.lon | lon | query point longitude |
boundary.circle.radius | radius | km in both v2 and v3 (decimals accepted) |
| (new in v3) | distanceSort | sort by distance from the query point (default true) or by relevance when false |
Place (/v3/place)
| v2 | v3 | Notes |
|---|---|---|
ids | ids | comma-separated; ID shape differs between v2/v3 (see ID format) |
layers
The v3 layer values are the same indexed data v2 already returned, just labelled precisely - in v2 venue held NSR stop places and everything else fell under address:
v2 layers | v3 layers | data origin |
|---|---|---|
address | address | matrikkel addresses |
address | street | matrikkel streets |
venue | stopPlace | NSR stop places |
address | groupOfStopPlaces | NSR group of stop places |
address | poi | OSM POIs; custom-poi (new in v3) |
address | place | kartverket-stedsnavn (cities, districts) |
Default behaviour (no layers filter): same result set as v2 - only the layer value changed. All layers are eligible, with one exclusion: addresses are hidden from autocomplete unless the query text contains a digit or sources includes kartverket-matrikkelenadresse. Reverse hides addresses unless the caller opts in via sources=kartverket-matrikkelenadresse or layers=address.
sources
| v2 | v3 |
|---|---|
openstreetmap | openstreetmap |
openaddresses | kartverket-matrikkelenadresse |
| (new in v3) | kartverket-stedsnavn |
| (new in v3) | nsr |
| (new in v3) | custom-poi |
Weight semantics (changed)
weight is renamed straight across from focus.weight, but the math is different. In v2 it was an open-ended scalar fed through a curve (default ~15). In v3 it is a linear blend between importance ranking (0) and pure location preference (1) - avoid the extremes unless that is what you want:
weight=0- no focus bias, results ranked purely on text relevance and importance.weight=1- pure location preference: importance is ignored entirely, only proximity counts.weight=0.5(default) - balanced: importance and proximity contribute roughly equally to ranking.
The v3 default tilts toward importance more than v2 does, so far-away major cities can still win against near-focus same-prefix streets (e.g. "Bergen" from Oslo still returns Bergen, not Bergensgata). If you tuned focus.weight in v2 do not just copy the number across.
Default radius differs from v2
Do not copy your v2 focus.scale value into v3 radius. v2 saturates large values (anything past ~300 km behaves the same, so the v2 default of 2500 was effectively ~120 km); v3 treats the number as a literal focus radius, so radius=2500 disables the bias entirely. If you used v2's default or any large focus.scale, use radius in the 50-150 km range.
Focus parameters are a bundle
lat, lon, radius, and weight on /v3/autocomplete belong together. Sending any of them without both lat and lon is a 400 error.
multimodal
Applies to /v3/autocomplete and /v3/reverse.
An NSR multimodal stop groups several stop places (e.g. a bus terminal + train station hub) under a parent. Most NSR stop places are monomodal - standalone, not part of any such group - and those always appear in results regardless of this parameter. multimodal only decides whether multimodal parents, children, or both come through alongside them.
parent(default) - monomodal stops + multimodal parents; multimodal children hidden.child- monomodal stops + multimodal children; multimodal parents hidden.all- monomodal stops + multimodal parents + multimodal children.
The role of each returned stop is reported per feature in the stopPlaceRole response field (parent / child / standalone), so you no longer need to infer it from source as in v2.
ID format
v3 uses canonical, fully-qualified IDs. v2 uses legacy/abbreviated forms for backwards compatibility.
| Entity | v2 ID | v3 ID |
|---|---|---|
| Stop place | NSR:StopPlace:N | NSR:StopPlace:N |
| Group of stop places | NSR:GroupOfStopPlaces:N | NSR:GroupOfStopPlaces:N |
| OSM POI | OSM:TopographicPlace:N | OSM:TopographicPlace:N |
| Matrikkel address | bare numeric (e.g. 225678815) | KVE:PostalAddress:N |
| Matrikkel street | KVE:TopographicPlace:KOMNR-NAME | KVE:TopographicPlace:KOMNR-NAME (unchanged) |
| Stedsnavn place | bare numeric (e.g. 434810) | KVE:PlaceName:N |
| Boundary filter (kommune/fylke code) | bare numeric (e.g. 0301, 03) | KVE:TopographicPlace:N |
Grunnkrets (in address.boroughId) | whosonfirst:borough:N | KVE:Borough:N (N = 8-digit grunnkretsnummer: KOMNR + 4-digit sequence, e.g. 34200205) |
In v2 bare numerics on the wire are ambiguous - they can be stedsnavn places or postal addresses. v3 removes the ambiguity by giving each entity a fully-qualified namespace.
Response format
Both v2 and v3 return a GeoJSON FeatureCollection. High-level shape changes:
- Feature
propertiesuse structured objects (names,address,transportModes) instead of v2's flat fields. - A
metadataobject at the top level replaces v2'sgeocodingblock. It carries the echoed query,resultCount, and an ISO 8601timestamp. Errors come back as HTTP 4xx with anapplication/problem+jsonbody rather than undergeocoding.errors. /v3/reverseresponses includedistanceon each feature, in kilometres with 3-decimal precision (same units as v2).- Features with a real extent (streets, groups of stop places) carry a GeoJSON
bbox([minLon, minLat, maxLon, maxLat]); point features omit it.
The per-property table below is authoritative; see layers and sources for value-set changes on layer and source.
Property mapping (properties.*)
Field-by-field migration. Anything not listed is unchanged; anything marked _(removed)_ has no v3 equivalent.
| v2 | v3 | notes |
|---|---|---|
id | id | ID shape differs - see ID format |
name | names.default | |
label | names.display | formatted display name with locality context |
popular_name | names.label | colloquial name; rarely populated today |
housenumber | address.houseNumber | |
street | address.streetName | |
postalcode | address.postalCode | |
country_a / countrycode | address.countryCode | v2 was ISO 3166-1 alpha-3 ("NOR") on country_a; countrycode was declared but never populated. v3 collapses both into countryCode as alpha-2 lowercase ("no"). Case-sensitive client comparisons will break silently. |
county | address.county | |
county_gid | address.countyId | v2 prefixed whosonfirst:county:; v3 returns the raw indexed ID (e.g. KVE:TopographicPlace:03) |
locality | address.locality | |
locality_gid | address.localityId | v2 prefixed whosonfirst:locality:; v3 returns the raw indexed ID |
borough | address.borough | |
borough_gid | address.boroughId | v2 returns whosonfirst:borough:N; v3 returns KVE:Borough:N where N is the grunnkretsnummer (Norwegian sub-municipal statistical unit) |
city | address.locality | v2 carried both city and locality for the same value; v3 keeps only locality |
layer | layer | new enum values; see layers |
source | source | NSR stops normalised: v2 returned "openstreetmap" (multimodal parent), "geonames" (child), or "whosonfirst" (standalone); v3 always returns "nsr". The parent/child/standalone role v2 encoded here is now exposed explicitly in the new stopPlaceRole field (next row). openaddresses -> kartverket-matrikkelenadresse. See sources. |
| (new in v3) | stopPlaceRole | Stop place hierarchy role: parent / child / standalone. Replaces inferring it from the v2 source (openstreetmap/geonames/whosonfirst). Set on stopPlace features; parent/child both mean multimodal. |
category | stopPlaceTypes + categories | NeTEx stop place types (e.g. railStation) split out from OSM tags (e.g. restaurant) |
mode | transportModes | array of { mode, subMode } objects instead of pair-encoded JSON |
tariff_zones | fareZones | not a straight rename; see below |
distance | distance | reverse only; kilometres with 3-decimal precision in both v2 and v3 |
description | description | per-language description. v2 shape: [{lang: text}, ...] (array of singleton maps). v3 shape: {lang: text, ...} (flat object keyed by ISO 639-2 alpha-3 code) |
accuracy | (removed) | Pelias-ism (point/centroid); not meaningful here |
gid | (removed) | the Pelias source:layer:id triple; use id |
source_id | (removed) | duplicate of id |
type (in properties) | (removed) | always "Feature" on the feature itself; the duplicate inside properties is gone |
fareZones is not a straight rename of tariff_zones. v3 fareZones carries only AUTH:FareZone:ID-shaped refs, while v2's tariff_zones merged both TariffZone and FareZone refs for backwards compatibility. TariffZone refs are no longer surfaced in v3 responses, and TariffZone-shaped values sent as filter input do not match anything.
Autocomplete example
v2 request:
Code
v2 response:
Code
v3 request:
Code
v3 response:
Code
Reverse geocode example
v2 request:
Code
v3 request:
Code
v3 response (abbreviated):
Code