Guides

Batch resolve postal codes for a customer list

A customer export with a postal code column but no coordinates is a common starting point for anything involving shipping zones, regional reporting, or store assignment. Resolving the whole column at once is faster than writing a loop.

Sending the batch

POST an array of code and country objects to /v1/postcode. Each item resolves independently and comes back in the same order.

POST /v1/postcode
Content-Type: application/json

[{"code": "10115", "country": "DE"}, {"code": "75001", "country": "FR"}]
{
  "status": "ok",
  "results": [
    {"postcode": "10115", "country_code": "DE", "results": [{"lat": 52.5300, "lon": 13.3800, "components": {"city": "Berlin", "region": "Berlin"}}]},
    {"postcode": "75001", "country_code": "FR", "results": [{"lat": 48.8630, "lon": 2.3360, "components": {"city": "Paris", "region": "Ile-de-France"}}]}
  ]
}

Matching results back to customer records

Keep the original row index or customer ID alongside each code and country pair before sending the request, and match results back onto customer records by that same position, the same approach that works for bulk forward or reverse geocoding.

Deduplicating before you send

A customer list of any real size tends to have far fewer distinct postal codes than it has rows, since many customers share the same code in any given city or neighborhood. Build a unique list of code and country pairs first, resolve that smaller list in one batch, and then map the results back onto every customer row that shares each code, rather than sending one array entry per customer and paying for the same code and country pair over and over.

Handling codes that do not resolve

An empty results array for a particular item usually means the code and country pair does not exist, which is common in an old export with typos or an outdated postal code. Flag those rows for manual review rather than silently dropping them from your report.

An edge case: formatting differences

A code stored as "SW1A1AA" without a space and one stored as "SW1A 1AA" with one may or may not resolve the same way depending on how consistently your own export formats codes, so normalizing spacing and case in your export before building the batch array reduces the number of rows that fail to resolve purely on formatting rather than on the code being genuinely wrong.

What it costs

A batch is billed one request per item, so a 2,000 row customer list costs 2,000 requests, whether sent as one bulk call or as 2,000 separate ones. Sending it as one call is still worth doing for the reduced overhead and the single set of quota headers to check, even though the request count against your allowance is identical either way. Deduplicating first, as above, is what actually reduces the request count, not the choice between bulk and individual calls.

Watching your allowance mid batch

For a list large enough to run past the free 2,500 requests a day, check X-Quota-Free-Remaining before you commit to running the whole thing in one sitting, or split it across a couple of days if you are not planning to move onto prepaid credit for a one-off job.

Resolving a whole customer list's postal codes in a single call turns what used to be a slow background job into one straightforward request. The postal code lookup docs cover the full field list.