Forward geocoding
Turn an address or place name into coordinates and a structured address for the United States and Canada.
Signed in? Open this endpoint in the dashboard playground, which uses your organization automatically. Signed out, use Try in Playground below with your API key.
apiKey<token>Your API key from the dashboard, sent as ?apiKey=<key>.
text?stringFree-form address query. Alternative to the structured address parameters; do not combine them. Parsed by libpostal.
1 <= length <= 1024name?stringPlace or amenity name. Structured address input; do not combine with text.
1 <= length <= 1024housenumber?stringHouse number. Structured address input; do not combine with text.
1 <= length <= 1024street?stringStreet name. Structured address input; do not combine with text.
1 <= length <= 1024postcode?stringPostcode or ZIP code. Structured address input; do not combine with text.
1 <= length <= 1024city?stringCity name. Structured address input; do not combine with text.
1 <= length <= 1024state?stringState, province or territory name or code. Structured address input; do not combine with text.
1 <= length <= 1024country?stringCountry name. Structured address input; do not combine with text.
1 <= length <= 1024type?stringRequested location type. Only results of this type are returned. country, state, city and locality are also passed to Nominatim as a feature type.
Deviation (approximated): When type is set the Address Point (canonical and interpolation) stages are skipped, so street and postcode queries are answered from OSM data only. locality matches suburb, district and unknown results.
"country""state""city""postcode""street""amenity""locality"lang?stringResult language (ISO 639-1, case-insensitive).
Deviation (approximated): Only Nominatim (accept-language) and, for en/de/fr/it, Photon honour the language. Address Point results keep the source spelling.
"en""ab""aa""af""ak""sq""am""ar""an""hy""as""av""ae""ay""az""bm""ba""eu""be""bn""bh""bi""bs""br""bg""my""ca""ch""ce""ny""zh""cv""kw""co""cr""hr""cs""da""dv""nl""en""eo""et""ee""fo""fj""fi""fr""ff""gl""ka""de""el""gn""gu""ht""ha""he""hz""hi""ho""hu""ia""id""ie""ga""ig""ik""io""is""it""iu""ja""jv""kl""kn""kr""ks""kk""km""ki""rw""ky""kv""kg""ko""ku""kj""la""lb""lg""li""ln""lo""lt""lu""lv""gv""mk""mg""ms""ml""mt""mi""mr""mh""mn""na""nv""nb""nd""ne""ng""nn""no""ii""nr""oc""oj""cu""om""or""os""pa""pi""fa""pl""ps""pt""qu""rm""rn""ro""ru""sa""sc""sd""se""sm""sg""sr""gd""sn""si""sk""sl""so""st""es""su""sw""ss""sv""ta""te""tg""th""ti""bo""tk""tl""tn""to""tr""ts""tt""tw""ty""ug""uk""ur""uz""ve""vi""vo""wa""cy""wo""fy""xh""yi""yo""za"limit?integerMaximum number of results.
Deviation (approximated): Geoapify documents no default; this service returns 5 results when limit is omitted.
1 <= value <= 1005countrycodes?array<>ISO 3166-1 alpha-2 country filter, comma-separated or repeated (up to 10). Defaults to us,ca when omitted.
Deviation (unsupported): Only the United States and Canada are indexed. Any other country code is accepted but returns an empty result set.
items <= 10filter?array<>Hard result filter. Repeat the parameter or separate items with |. Items: rect:lon1,lat1,lon2,lat2, circle:lon,lat,radiusMeters, countrycode:us,ca (or none/auto for no filter) and place:<gp:osm place id> (bounding box of that OSM object).
Deviation (approximated): circle is pushed down as its bounding box and then applied exactly after the search. place: accepts only gp:osm:<n|w|r><id> Place IDs and filters by that object's bounding box, not its exact boundary; other Place ID kinds return 400. Filters outside the US and Canada return an empty result set.
bias?array<>Soft ranking bias. Repeat the parameter or separate items with |. Items: proximity:lon,lat, rect:lon1,lat1,lon2,lat2, circle:lon,lat,radiusMeters, countrycode:us,ca.
Deviation (approximated): Bias adds up to 0.1 per matching item to the sort order only; rank.confidence is never changed. proximity adds 0.1 / (1 + distance_km / 25). circle also seeds the proximity point sent to Photon.
format?stringResponse serialization: geojson (served as application/geo+json), json or xml.
"geojson""json""geojson""xml"Geocoding results. Format depends on format; the default is GeoJSON. Empty features/results when nothing matches.
- response
GeoJSON FeatureCollection (format=geojson, the default; served as application/geo+json).
type*unknownfeatures*array<>query?Echo of the request input plus the parsed address.
curl -X GET 'https://api.data.graphitelab.ai/v1/geocode/search?text=1600+Pennsylvania+Ave+NW%2C+Washington%2C+DC+20500&name=Lincoln+Memorial&housenumber=1600&street=Pennsylvania+Avenue+NW&postcode=20500&city=Washington&state=DC&country=United+States&type=city&lang=en&limit=5&countrycodes=us&countrycodes=ca&filter=circle%3A-77.0365%2C38.8977%2C5000&filter=countrycode%3Aus&bias=proximity%3A-77.0365%2C38.8977&format=json'{ "results": [ { "name": "Prime Minister's Residence", "country": "Canada", "country_code": "ca", "state": "Ontario", "state_code": "ON", "county": "Eastern Ontario", "city": "Ottawa", "postcode": "K1M 2B2", "street": "Sussex Drive", "housenumber": "24", "lon": -75.6937963, "lat": 45.4441429, "formatted": "24 Sussex Drive, Ottawa, ON K1M 2B2, Canada", "address_line1": "24 Sussex Drive", "address_line2": "Ottawa, ON K1M 2B2, Canada", "result_type": "building", "datasource": { "sourcename": "openstreetmap", "attribution": "© OpenStreetMap contributors", "license": "Open Database License", "url": "https://www.openstreetmap.org/copyright" }, "rank": { "confidence": 1, "confidence_city_level": 1, "confidence_street_level": 1, "confidence_building_level": 1, "match_type": "full_match" }, "place_id": "gp:osm:w230454276", "bbox": { "lon1": -75.694683, "lat1": 45.4435841, "lon2": -75.6926233, "lat2": 45.4448567 } }, { "name": "24 Sussex Drive", "country": "Canada", "country_code": "ca", "state": "Ontario", "state_code": "ON", "city": "Ottawa", "postcode": "K1M 2B2", "street": "Sussex Drive", "lon": -75.6938552, "lat": 45.444413, "formatted": "Sussex Drive, Ottawa, ON K1M 2B2, Canada", "address_line1": "Sussex Drive", "address_line2": "Ottawa, ON K1M 2B2, Canada", "result_type": "unknown", "datasource": { "sourcename": "openstreetmap", "attribution": "© OpenStreetMap contributors", "license": "Open Database License", "url": "https://www.openstreetmap.org/copyright" }, "rank": { "confidence": 0.5, "confidence_city_level": 1, "confidence_street_level": 1, "confidence_building_level": 0, "match_type": "match_by_street", "importance": 0.00000999999999995449 }, "place_id": "gp:osm:w39675229", "bbox": { "lon1": -75.694034, "lat1": 45.444253, "lon2": -75.693684, "lat2": 45.444571 } } ], "query": { "text": "24 Sussex Drive, Ottawa, ON", "parsed": { "housenumber": "24", "street": "sussex drive", "city": "ottawa", "state": "on", "expected_type": "building" } }}Full schema: API reference
GET /v1/geocode/search converts a free-form address (or structured address fields) into coordinates plus a normalized, structured address. Use it when you have text from a user or a database and need a point on the map, a clean formatted address, or a stable place_id. It is the Geoapify-compatible forward geocoder (operationId: forwardGeocode).
How it works
The request runs through the Geocoding Waterfall (ADR 0002), which is hand-rolled in the gateway:
-
libpostal parses
textinto house number, street, city, state and postcode. Structured parameters skip parsing. -
Canonical Address exact match in the Address Point layer (Overture and NAR, with NAD filling gaps; stored in the same Postgres/PostGIS cluster as Nominatim).
-
Nominatim (OSM plus Census TIGER), structured query first, then free text.
-
Interpolation between neighbouring Address Points.
-
Photon (OSM-based search index) as the last resort.
A stage's answer is accepted when its best candidate scores at least 0.8. Otherwise the next stage runs and the best candidate overall wins. The scoring fills the rank fields. The X-Geo-Stage response header names the stage that produced the first result: canonical, nominatim, interpolation, photon or none.
Quick start
curl -s \
"https://api.data.graphitelab.ai/v1/geocode/search?text=1600%20Pennsylvania%20Ave%20NW,%20Washington,%20DC%2020500&apiKey=$GRAPHITE_API_KEY"The default format is GeoJSON. This query is answered by an exact Address Point match (response trimmed):
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"country_code": "us",
"state_code": "DC",
"city": "Washington",
"postcode": "20500",
"street": "PENNSYLVANIA Avenue Northwest",
"housenumber": "1600",
"lon": -77.03654697024702,
"lat": 38.89767510742324,
"formatted": "1600 PENNSYLVANIA Avenue Northwest, Washington, DC 20500, United States",
"result_type": "building",
"datasource": {
"sourcename": "nad+overture",
"attribution": "National Address Database, U.S. Department of Transportation; © Overture Maps Foundation and its address sources"
},
"rank": { "confidence": 1, "match_type": "full_match", "importance": 1 },
"place_id": "gp:addr:canonical:37388970"
},
"geometry": { "type": "Point", "coordinates": [-77.03654697024702, 38.89767510742324] }
}
],
"query": {
"text": "1600 Pennsylvania Ave NW, Washington, DC 20500",
"parsed": { "housenumber": "1600", "street": "pennsylvania ave nw", "city": "washington", "state": "dc", "postcode": "20500", "expected_type": "building" }
}
}Parameters
Use one input mode: text, or the structured fields. Combining them returns 400, and sending neither returns 400.
| Name | Type | Required | What it does |
|---|---|---|---|
text | string (1-1024) | No | Free-form address, parsed by libpostal. Do not combine with structured fields. |
name, housenumber, street, postcode, city, state, country | string (1-1024) | No | Structured address input. Do not combine with text. |
type | country, state, city, postcode, street, amenity, locality | No | Return only this location type. Skips the Address Point stages, so street and postcode queries are answered from OSM data only. |
lang | ISO 639-1 code, default en | No | Result language. Only Nominatim and, for en/de/fr/it, Photon honor it. |
limit | integer 1-100, default 5 | No | Maximum number of results. |
countrycodes | array of 2-letter codes (max 10) | No | Country filter, comma-separated or repeated. Defaults to us,ca. |
filter | array of strings | No | Hard filter: rect:lon1,lat1,lon2,lat2, circle:lon,lat,radiusMeters, countrycode:us,ca, place:<gp:osm place id>. Repeat the parameter or separate items with a pipe character. |
bias | array of strings | No | Soft ranking: proximity:lon,lat, rect:, circle:, countrycode:. Repeat the parameter or separate items with a pipe character. |
format | json, geojson, xml; default geojson | No | Response serialization. GeoJSON is served as application/geo+json. |
Response
Each GeoJSON feature (or entry in results for json and xml) carries:
-
lon,lat, and ageometryPoint in GeoJSON. -
formatted,address_line1,address_line2and the structured parts (housenumber,street,city,state_code,postcode,country_code). -
result_type: for examplebuilding,street,city,unknown. -
place_id: typedgp:<kind>:<key>.gp:addr:*is an Address Point,gp:osm:*is an OSM object (for examplegp:osm:w230454276, a way). OSM Place IDs can be used infilter=place:. -
datasource: the source this result came from. OSM-derived results carry "© OpenStreetMap contributors" and the ODbL. Address Point results carry their sources (for examplenad+overture) with each licence's attribution; when several sources agree they are listed indatasource.sources[]. -
rank:confidence(0 to 1) with city, street and building level variants,match_type(for examplefull_match,match_by_street,match_by_city_or_disrict) andimportancewhere present. -
bbox: present on OSM results that have an extent. -
query.parsed: how the input was parsed, includingexpected_type.
Differences from Geoapify
-
unsupported: US and Canada only. Other countries return an empty result set with HTTP 200, not an error.
-
empty:
timezone,plus_code,plus_code_short,category,categories,iso3166_2,district,suburbandrank.popularityare never returned. -
extra:
datasource.sources[]and theX-Geo-Stageresponse header are additions. -
approximated:
rankcomes from our own scoring: same scale, not identical values.lang,type,filter,biasandlimitare approximated:-
typeskips the Address Point stages;localitymatches suburb, district and unknown results. -
langis honored only by Nominatim and (en/de/fr/it) Photon; Address Point results keep the source spelling. -
limitdefaults to 5 (Geoapify documents no default). -
filter:circleis pushed down as its bounding box, then applied exactly.place:accepts onlygp:osm:<n|w|r><id>and filters by that object's bounding box, not its exact boundary; other Place ID kinds return 400. -
biasadds up to 0.1 per matching item to the sort order only and never changesrank.confidence.proximityadds 0.1 / (1 + distance_km / 25).
-
US and Canada notes
-
US addresses come from Overture, NAD and OSM/TIGER. Canadian addresses come from Overture, NAR (StatCan National Address Register) and OSM.
-
Canadian postcodes in a query are anchored by the full code or its 3-character FSA prefix (for example
K1M). -
Province and territory names or codes are accepted in
state(for exampleON,Ontario,Québec). -
Canadian OSM results can carry bilingual names, as in
New Brunswick / Nouveau-Brunswick.lang=fris honored only by Nominatim and Photon. -
Address Point results echo the source's casing, for example
PENNSYLVANIA Avenue Northwest. -
countrycodesorfilterlimited to other countries returns an empty result set.
More examples
OSM match in Canada, with a second street-level candidate:
curl -s \
"https://api.data.graphitelab.ai/v1/geocode/search?text=24%20Sussex%20Drive,%20Ottawa,%20ON&apiKey=$GRAPHITE_API_KEY"Errors and limits
| Status | Meaning |
|---|---|
| 400 | Invalid parameters: text combined with structured fields, neither provided, or a filter=place: that is not a known gp:osm:* Place ID. |
| 401 | Missing or invalid API key. |
| 500 | Internal gateway error. |
| 503 | All Geocoding Engines unavailable (no candidates and every attempted stage errored). |
limit is capped at 100 (default 5), countrycodes at 10 items, and string inputs at 1024 characters. Over 60 requests per minute returns 429.
Known issues from the phase 18 live checks: Address Point results echo the source's casing (PENNSYLVANIA Avenue Northwest), query.parsed values are lowercased, and the first requests right after a deploy can take 6 to 13 seconds while Engines warm up.
Try in Playground (signed in to your Graphite Lab organization). Signed out, use the paste-your-key widget on the reference page.