Getting started
The Zapex API answers with UK addresses, places and maps, as JSON over HTTPS from https://api.zapex.co.uk. Every route is in the API reference.
Keys
Make a key in the dashboard, and send it with each request in Authorization: Bearer <key>.
| Key | For |
|---|---|
zpx_live_… | Your server. Shown once, when it is made: keep it secret. |
zpx_pk_live_… | A page: a widget or a map. It may call only what a browser needs, from the origins you name. |
zpx_test_…, zpx_pk_test_… | The sandbox, free: below. |
Each key has scopes, which say what it may call, and rate limits: an organisation's over all its
keys, a secret key's own, and for a publishable key each IP address's, by the second and by the
day. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset for the limit the key is nearest. A request over one is 429 with Retry-After too, and scope in its body says which.
The sandbox
A test key calls the same routes over fixture data, and uses no credits. Its addresses are those of the postcodes SA1 1DF, SA1 1RE, SA1 1RP, SA1 1TY and SA1 8JQ in Swansea, with their areas and the bus stops and station near them; its location lists are its own.
curl https://api.zapex.co.uk/v1/addresses?q=8-9+wind+st \
-H "Authorization: Bearer zpx_test_…" curl https://api.zapex.co.uk/v1/addresses/100101046097 \
-H "Authorization: Bearer zpx_test_…" Errors
A failure answers with its status and a problem details body (RFC 9457, application/problem+json): type, title, status and detail, with code, which tells one failure from
another, and field, the field it is of, as locations[2].lat. The codes
are in the reference.
Credits
A live key uses its organisation’s credits: a lookup, a geocode, a query, each a credit; a search
of the typeahead is free. An organisation buys credits in packs in the dashboard. With none left,
a live key is refused with credits_exhausted (402). A key may have a monthly cap of its own.
Examples
Geocode an address, in JavaScript
const response = await fetch(
'https://api.zapex.co.uk/v1/geocode/forward?q=' + encodeURIComponent('8-9 wind st swansea'),
{ headers: { Authorization: `Bearer ${process.env.ZAPEX_KEY}` } }
);
const { results } = await response.json();
const [best] = results;
if (best && best.confidence >= 0.8) {
console.log(best.uprn, best.lines.line_1, best.location);
} Cleanse a list of addresses, in Python
import os, time, requests
api = "https://api.zapex.co.uk/v1/cleansing/jobs"
headers = {"Authorization": f"Bearer {os.environ['ZAPEX_KEY']}"}
job = requests.post(api, headers=headers, json={"items": [
{"id": "crm-1", "address": "8-9 wind st swansea"},
{"id": "crm-2", "address": "1 east burrows rd sa1 1re"},
]}).json()
while job["status"] != "completed":
time.sleep(2)
job = requests.get(f"{api}/{job['id']}", headers=headers).json()
after = 0
while after is not None:
page = requests.get(f"{api}/{job['id']}/results", headers=headers,
params={"after": after, "limit": 1000}).json()
for item in page["results"]:
print(item["id"], item["status"], (item["match"] or {}).get("uprn"))
after = page["next"] An address field in a form
<script src="https://cdn.zapex.co.uk/widgets/1/zapex-widgets.iife.js" defer></script>
<form action="/checkout" method="post">
<zapex-address api-key="zpx_pk_live_…" name="delivery"
fill="line_1:#line1, post_town:#town, postcode:#postcode"></zapex-address>
<input id="line1" name="line1"> <input id="town" name="town"> <input id="postcode" name="postcode">
</form> In React
import { ZapexAddress } from '@zapex/widgets/react';
export function Delivery({ onAddress }) {
return <ZapexAddress apiKey="zpx_pk_live_…" name="delivery" onSelect={onAddress} />;
} The nearest of your stores to a postcode
curl "https://api.zapex.co.uk/v1/location-lists/ll_…/nearest?postcode=SA1+1RE&limit=3&open_now=true" \
-H "Authorization: Bearer zpx_live_…" Which of your delivery zones hold an order
curl https://api.zapex.co.uk/v1/zones/contains \
-H "Authorization: Bearer zpx_live_…" -H "Content-Type: application/json" \
-d '{"zones": {"type": "FeatureCollection", "features": [{"type": "Feature", "id": "city-centre",
"geometry": {"type": "Polygon", "coordinates": [[[-3.95,51.61],[-3.93,51.61],[-3.93,51.63],[-3.95,51.63],[-3.95,51.61]]]}}]},
"points": [{"id": "order-1", "lat": 51.6174, "lng": -3.9370}]}' A map, with MapLibre GL
import maplibregl from 'maplibre-gl';
new maplibregl.Map({
container: 'map',
style: 'https://api.zapex.co.uk/v1/maps/styles/color?key=zpx_pk_live_…',
center: [-3.94, 51.62],
zoom: 13,
});