Docs
A free, public, edge-native forward geocoder for Italian addresses. Backed by Overture Maps. Public for now — please be kind to it.
1. Quick start
curl --get "https://geocoding.qubitdata.it/v1/search" \
--data-urlencode "q=Via Romagnosi 1, Milano"
2. Response shape
Google Geocoding API-compatible envelope: { status, results[] }. Drop-in replacement for most clients written against Google's API.
{
"status": "OK",
"results": [
{
"address_components": [
{ "long_name": "1", "short_name": "1", "types": ["street_number"] },
{ "long_name": "Via Romagnosi", "short_name": "Via Romagnosi", "types": ["route"] },
{ "long_name": "20121", "short_name": "20121", "types": ["postal_code"] },
{ "long_name": "Milano", "short_name": "Milano", "types": ["locality", "political"] },
{ "long_name": "Milano", "short_name": "MI", "types": ["administrative_area_level_2", "political"] },
{ "long_name": "Lombardia", "short_name": "Lombardia", "types": ["administrative_area_level_1", "political"] },
{ "long_name": "Italy", "short_name": "IT", "types": ["country", "political"] }
],
"formatted_address": "Via Romagnosi, 1, 20121 Milano MI, Italy",
"geometry": {
"location": { "lat": 45.4684, "lng": 9.19054 },
"location_type": "ROOFTOP",
"viewport": { "northeast": {...}, "southwest": {...} }
},
"place_id": "qd_xxxxxxxxxxxxx",
"types": ["street_address"]
}
],
"query": {
"raw": "Via Romagnosi 1, Milano",
"parsed": { "road": "via romagnosi", "number": "1", "city": "milano" }
}
}
Status codes follow Google: OK, ZERO_RESULTS, INVALID_REQUEST, OVER_QUERY_LIMIT, REQUEST_DENIED, UNKNOWN_ERROR.
The query field is a proprietary extension Google omits — useful to debug parsing.
geometry.location_type
| Value | Meaning |
|---|---|
| ROOFTOP | Civic-level match. Highest precision (~10 m). |
| RANGE_INTERPOLATED | Civic interpolated between bracketing rows or snapped to a same-parity ±2 neighbour. ~30 m. |
| GEOMETRIC_CENTER | Street centroid: no civic-level row. ~50 m. Also used on cross-comune fallbacks. |
| APPROXIMATE | Road matched without a usable city signal. |
Per-result fields
- place_id — deterministic qd_-prefixed ID stable for the (road, comune, civic) triple. Not a Google place ID.
- partial_match — true when the query was corrected (typo, missing civic, ecc.).
- types — ["street_address"] when a civic resolved, ["route"] otherwise.
- geometry.viewport — synthetic bbox sized to the precision of the location_type.
Optional top-level fields (proprietary extensions)
- did_you_mean — original road as typed; the result was returned for the corrected form.
- did_you_mean_city — original city as typed; the result was returned for the corrected form.
- alternates — equally-good fuzzy candidates (array of road names).
- postcode_override — the comune the CAP pinned to (overrides a conflicting typed city).
- street_centroid — true when the result came from the street-only fallback index.
- actual_city — on nearby_comune hits, the comune the result is actually located in (the typed city is in did_you_mean_city).
3. Italian-aware parsing
- V.le, P.zza, C.so, Lgt. expanded to Viale, Piazza, Corso, Lungotevere
- Civic suffixes preserved: 12/A, 12B, 12 bis/ter/quater, 12-14 (range → lower endpoint), snc
- Diacritics stripped: Via Ètna → via etna
- SS / SP road numbers stay in road name (not parsed as civic): Strada Statale 16
- Tail-city inference: Via Roma 1 Milano resolves the city without a comma.
- CAP disambiguation: a 5-digit postcode overrides or fills the city.
- Drops scala / sc / piano / int / interno / km markers and their values.
- Ordinal positions tolerated: Vico 2° Adamo ↔ Vico Adamo 2° hit the same record.
- First-name initials expanded against the dataset: Via C. Romani → Via Carolina Romani. Multi-initial chains supported: Via G. B. Tiepolo.
4. Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | query_too_short | q must be ≥ 3 chars |
| 403 | turnstile_required | Demo endpoint: missing Turnstile token. |
| 403 | turnstile_invalid | Demo endpoint: Turnstile siteverify rejected the token. |
| 422 | unparseable | parser couldn't extract a road from the query |
| 429 | rate_limit_exceeded | per-key or per-IP throttle. retry-after header set. |
| 503 | index_unavailable | retry; index transiently unreachable |
| 503 | demo_unavailable | Demo endpoint not configured (Turnstile or DemoRL missing). |
5. Support
Questions, integration help, enterprise terms: support@qubitdata.it