Quickstart

You need an API key. Keys will be issued when the service opens; until then the examples show the exact request and response shape from the OpenAPI specification. Values in responses are illustrative.

The base URL is https://api.addrova.eu (not live yet). Replace it with http://localhost:8000 to try a local development instance.

1. Geocode an address

Use POST with a JSON body, so the address never appears in a URL.

curl

curl -s https://api.addrova.eu/v1/geocode \
  -H "X-API-Key: $ADDROVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q": "4 place d'\''Armes, Belfort", "country": "FR", "limit": 3}'

Python

import os
import requests

resp = requests.post(
    "https://api.addrova.eu/v1/geocode",
    headers={"X-API-Key": os.environ["ADDROVA_API_KEY"]},
    json={"q": "4 place d'Armes, Belfort", "country": "FR", "limit": 3},
    timeout=10,
)
resp.raise_for_status()
for r in resp.json()["results"]:
    print(r["label"], r["location"], r["confidence_level"])

JavaScript (Node 18+ or browser)

const resp = await fetch("https://api.addrova.eu/v1/geocode", {
  method: "POST",
  headers: { "X-API-Key": process.env.ADDROVA_API_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ q: "4 place d'Armes, Belfort", country: "FR", limit: 3 }),
});
if (!resp.ok) throw new Error((await resp.json()).code);
const { results, attribution } = await resp.json();

Response shape

{
  "results": [
    {
      "id": "90010_xxxx_00004",
      "label": "4 Place d'Armes 90000 Belfort",
      "components": { "housenumber": "4", "street": "Place d'Armes", "postcode": "90000", "city": "Belfort", "country_code": "FR" },
      "location": { "lat": 47.64, "lon": 6.86 },
      "precision": "rooftop",
      "confidence": 0.97,
      "confidence_level": "high",
      "confidence_calibrated": true,
      "country": "FR",
      "sources": ["ban"]
    }
  ],
  "attribution": [
    { "source": "ban", "text": "© BAN — Base Adresse Nationale, Licence Ouverte 2.0", "license": "etalab-2.0" }
  ]
}

precision is rooftop, street, centroid (a named place smaller than a town, such as a hamlet) or locality. confidence_level is high (calibrated and at or above the country threshold, 0.985 for France by default), medium (0.5 or more) or low. confidence_calibrated tells whether the confidence is calibrated for that country: high exists only when it is, and elsewhere the best level is medium; do not show a percentage when it is false. You may store the results, as long as you keep the attribution.

2. Reverse geocode

curl -s "https://api.addrova.eu/v1/reverse?lat=47.64&lon=6.86&limit=1" \
  -H "X-API-Key: $ADDROVA_API_KEY"

Reverse geocoding takes coordinates in the URL. Each result has a distance_m from your query point.

3. Repair a messy address

curl -s https://api.addrova.eu/v1/repair \
  -H "X-API-Key: $ADDROVA_API_KEY" -H "Content-Type: application/json" \
  -d '{"address": "4 pl darmes 90000 belfor", "country": "FR"}'

The response has a status (unchanged, repaired, unrepairable or pending), the corrected result, a confidence and the list of changes with a reason for each (abbreviation, typo, missing…). Repair is billed on success only. The asynchronous LLM fallback is not enabled: no address is sent to any external service.

4. Geocode a file

curl -s https://api.addrova.eu/v1/batch \
  -H "X-API-Key: $ADDROVA_API_KEY" \
  -F file=@addresses.csv -F address_column=address -F country=FR

The call returns 202 with a job id and a Location header. Poll GET /v1/batch/{id} until status is succeeded, then download GET /v1/batch/{id}/result. Defaults: 50 MB and 100,000 rows. The input file is deleted as soon as processing ends; the result is deleted after one hour by default, or at once with DELETE /v1/batch/{id}.

5. Handle errors

Errors are application/problem+json with a code: invalid_request, unauthorized, quota_exceeded and rate_limited (both 429, with a Retry-After header), engine_unavailable (503) and so on. The offending value is never echoed back. Quote the X-Request-Id response header when you contact support: we cannot look up your query, because we do not keep it.

6. Drop-in compatibility

Already using Google or Nominatim? See migrate from Google and migrate from Nominatim.