Postcode

Postcode search

Look up a US ZIP code area or Canadian postal code by text, or find the postcode that covers a point.

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.

GET
/postcode/search

Authorization

queryapiKey<token>

Your API key from the dashboard, sent as ?apiKey=<key>.

Query Parameters

postcode?string

Postcode text. Mutually exclusive with lat/lon. Case, spaces and hyphens are ignored (k1m 2b2 = K1M2B2). US: 5 digits (ZIP+4 accepted). Canada: 3-character FSA or 6-character code. Deviation (approximated): exact match only, no prefix or fuzzy matching.

Length1 <= length <= 1024
lat?number

Latitude for reverse postcode search. Requires lon; not allowed with postcode.

Range-90 <= value <= 90
lon?number

Longitude for reverse postcode search. Requires lat; not allowed with postcode.

Range-180 <= value <= 180
countrycode?string

ISO 3166-1 alpha-2 country filter (lowercase). Only us and ca can return results. Deviation (empty): any other country returns an empty result.

Value in"ad""ae""af""ag""ai""al""am""an""ao""ap""aq""ar""as""at""au""aw""az""ba""bb""bd""be""bf""bg""bh""bi""bj""bm""bn""bo""br""bs""bt""bv""bw""by""bz""ca""cc""cd""cf""cg""ch""ci""ck""cl""cm""cn""co""cr""cu""cv""cx""cy""cz""de""dj""dk""dm""do""dz""ec""ee""eg""eh""er""es""et""eu""fi""fj""fk""fm""fo""fr""ga""gb""gd""ge""gf""gg""gh""gi""gl""gm""gn""gp""gq""gr""gs""gt""gu""gw""gy""hk""hm""hn""hr""ht""hu""id""ie""im""il""in""io""iq""ir""is""it""je""jm""jo""jp""ke""kg""kh""ki""km""kn""kp""kr""kw""ky""kz""la""lb""lc""li""lk""lr""ls""lt""lu""lv""ly""ma""mc""md""me""mg""mh""mk""ml""mm""mn""mo""mp""mq""mr""ms""mt""mu""mv""mw""mx""my""mz""na""nc""ne""nf""ng""ni""nl""no""np""nr""nu""nz""om""pa""pe""pf""pg""ph""pk""pl""pm""pr""ps""pt""pw""py""qa""re""ro""rs""ru""rw""sa""sb""sc""sd""se""sg""sh""si""sj""sk""sl""sm""sn""so""sr""st""sv""sy""sz""tc""td""tf""tg""th""tj""tk""tm""tn""to""tr""tt""tv""tw""tz""ua""ug""um""us""uy""uz""va""vc""ve""vg""vi""vn""vu""wf""ws""ye""yt""za""zm""zw"
lang?string

Language for the state name (falls back to the default OSM name). Other fields are not translated. Deviation (approximated): only state is localised.

Value in"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"
format?string

geojson (default, application/geo+json), json (application/json, a results array of the feature properties) or xml (application/xml).

Default"geojson"
Value in"json""geojson""xml"
geometry?string

point (default): a point inside the postcode. original: the source polygon (ZCTA or FSA); full Canadian codes have no polygon and stay points. Applies to geojson format. Deviation (approximated): original is the Census/StatCan boundary, not USPS/Canada Post geometry.

Default"point"
Value in"point""original"

Response Body

Postcode search result in the requested format. An unknown postcode gives an empty list.

  1. response
type*unknown
features*array<>
Example Request
curl -X GET 'https://api.data.graphitelab.ai/v1/postcode/search?postcode=46204&lat=39.7684&lon=-86.1581&countrycode=us&lang=en&format=json&geometry=point'
Example Response
{  "results": [    {      "datasource": {        "sourcename": "census-zcta5",        "attribution": "US Census Bureau, TIGER/Line ZIP Code Tabulation Areas",        "url": "https://www.census.gov/programs-surveys/geography/guidance/geo-areas/zctas.html"      },      "postcode": "46204",      "ref": "46204",      "country": "United States",      "continent": "North America",      "country_code": "us",      "state": "Indiana",      "state_code": "IN",      "iso3166_2": "US-IN",      "lon": -86.15696934391093,      "lat": 39.772695,      "formatted": "46204, Indiana, United States",      "result_type": "postcode",      "place_id": "gp:pc:US-46204"    }  ]}

GET /v1/postcode/search returns the postcode feature for a postcode string, or the postcode covering a latitude and longitude. Use it to validate a ZIP or postal code, get a representative point for it, or fetch its boundary polygon. For prefix search and filtering over many postcodes, use the postcode list endpoint instead.

How it works

No Engine is called. The gateway answers from PostGIS tables in the geo schema, joined to Nominatim's placex for the state name.

  1. On first use the gateway builds a point index (gateway.postcode_index) from the source tables, and rebuilds it when their row counts change.

  2. Text lookup: the input is upper-cased with spaces and hyphens removed, then matched exactly against the index. A nine-digit US ZIP+4 is cut to its 5-digit ZIP. If a code exists as both an FSA and a full code, the FSA comes first.

  3. Point lookup: returns every ZCTA or FSA polygon that covers the point. If none does, it returns the single nearest postcode point within 1 km, with distance in meters. Otherwise the result is empty.

Data sources:

SourceUsed for
Census TIGER/Line ZCTA5US ZIP areas (polygons)
Statistics Canada FSA boundary fileCanadian 3-character areas (polygons)
Statistics Canada National Address Register (NAR)Canadian full 6-character codes (centroids of address points)
OpenStreetMap (Nominatim placex)State name and code

Quick start

curl -s "https://api.data.graphitelab.ai/v1/postcode/search?postcode=46204&countrycode=us&apiKey=$GRAPHITE_API_KEY"
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "datasource": {
          "sourcename": "census-zcta5",
          "attribution": "US Census Bureau, TIGER/Line ZIP Code Tabulation Areas",
          "url": "https://www.census.gov/programs-surveys/geography/guidance/geo-areas/zctas.html"
        },
        "postcode": "46204",
        "ref": "46204",
        "country": "United States",
        "country_code": "us",
        "state": "Indiana",
        "state_code": "IN",
        "iso3166_2": "US-IN",
        "lon": -86.15696934391093,
        "lat": 39.772695,
        "formatted": "46204, Indiana, United States",
        "result_type": "postcode",
        "place_id": "gp:pc:US-46204"
      },
      "geometry": {
        "type": "Feature",
        "properties": {},
        "geometry": { "type": "Point", "coordinates": [-86.15696934391093, 39.772695] }
      },
      "bbox": [-86.15696934391093, 39.772695, -86.15696934391093, 39.772695]
    }
  ]
}

The response is trimmed (continent omitted).

Parameters

Send postcode, or both lat and lon. Sending both forms is a 400, and so is sending neither.

NameTypeRequiredWhat it does
postcodestring (1 to 1024 chars)NoPostcode text. Case, spaces and hyphens are ignored. US: 5 digits (ZIP+4 accepted). Canada: 3-character FSA or 6-character code. Exact match only.
latnumber (-90 to 90)NoLatitude for reverse search. Requires lon; not allowed with postcode.
lonnumber (-180 to 180)NoLongitude for reverse search. Requires lat; not allowed with postcode.
countrycodestringNoLowercase ISO 3166-1 alpha-2 filter. Only us and ca can return results.
langstringNoLanguage for the state name; falls back to the default OSM name.
formatstringNogeojson (default), json (a results array of the feature properties) or xml.
geometrystringNopoint (default) or original (the source polygon; applies to geojson).

Full parameter reference

Response

With format=geojson the body is a FeatureCollection. With format=json it is { "results": [...] }, one object per feature properties.

FieldMeaning
place_idTyped ID gp:pc:<COUNTRY>-<code>, for example gp:pc:US-46204 or gp:pc:CA-K1M2B2 (no space in the code).
datasource.sourcenamecensus-zcta5, statcan-fsa or statcan-nar, each with its attribution and URL.
postcode, refThe postcode. Canadian full codes are formatted with a space (K1M 2B2).
state, state_code, iso3166_2Province or state, from OSM administrative boundaries. Only state follows lang.
lon, latA point inside the postcode area (ST_PointOnSurface), or the centroid for full Canadian codes.
distanceReverse search only: meters from the query point. 0 when a polygon covers it; non-zero for the nearest-point fallback.
result_typeAlways postcode.
geometry and bboxBy default a nested Feature holding the point, with a point-sized bbox. With geometry=original on a ZCTA or FSA, the polygon and its real bounding box.

An unknown postcode is HTTP 200 with features: [] (or results: []), not 404. This endpoint does not return rank.

Differences from Geoapify

  • approximated: US results use Census ZCTA, not USPS ZIP codes. PO-box-only ZIPs have no polygon and return empty.

  • approximated: Canadian full 6-character codes return an address-derived centroid only. FSA codes return the StatCan polygon.

  • empty: Only US and Canadian postcodes exist. Special codes such as K1A 0B1 return empty, and any other countrycode returns an empty result.

  • extra: Typed place_id (gp:pc:...) and datasource sourcename values census-zcta5, statcan-fsa, statcan-nar.

Parameter-level deviations: postcode is an exact match after normalization (no fuzzy matching); lang localizes only state; geometry=original is the Census or StatCan boundary, not USPS or Canada Post geometry.

US and Canada notes

  • US: ZCTA is a Census approximation of ZIP delivery areas. ZIPs for PO boxes only or for single organizations have no polygon. ZIP+4 input is reduced to the 5-digit ZIP.

  • Canada: a 3-character input hits the FSA (polygon available). A 6-character input hits a NAR-derived point, never a polygon, even with geometry=original. Government codes such as K1A 0B1 are not in the data.

  • Reverse search outside every polygon snaps to the nearest postcode point within 1 km (ZCTA, FSA or full-code centroid), one result.

More examples

Returns a statcan-nar centroid for a 6-character code.

curl -s "https://api.data.graphitelab.ai/v1/postcode/search?postcode=K1M2B2&countrycode=ca&apiKey=$GRAPHITE_API_KEY"

Errors and limits

StatusWhen
200Success, including an empty result for an unknown postcode.
400Invalid or missing parameters: both postcode and lat/lon, neither, a bad countrycode, lang, geometry or format, or postcode outside 1 to 1024 characters.
401Missing or invalid API key.
500Unexpected gateway error.

Limits: postcode is at most 1024 characters, and the reverse nearest-point fallback reaches 1 km.

The known gateway issues recorded for this phase (/routing admin areas, reverse geocoding type handling, /boundaries/consists-of latency) do not affect this endpoint. The first request after the index is empty or the source tables change rebuilds gateway.postcode_index, so it can be slower than later requests.

Try in Playground (signed in to your Graphite Lab organization). Signed out, use the paste-your-key widget on the reference page.