Skip to content

API reference/address

List the addresses at a postcode

GET/api/v1/address/postcode/{postcode}

authentication
Secret API key as a bearer token
billing
From the licensed partner: 25 credits per answered list, priced at twice or more what the partner charges for it, and nothing for a partner that could not answer. From an open register: 1 credit when the listing holds streets at the postcode, free for the next seven days for the same postcode, and free for an empty list. A country neither covers, and a postcode the listing cannot speak for, answer 501 and cost nothing.

Answers the addresses at one postcode, for callers that want a "find my address" picker under a postcode field.

Two sources answer. A licensed partner, where one is configured, lists every delivery point for the countries it is licensed for and is asked first — a full British list derives from a postal operator's own address file, and serving it needs a licence (can you look up UK addresses from a postcode for free?). Otherwise, wherever an open national register's street listing is installed (Switzerland, Austria, Czechia, Norway, Belgium, Luxembourg, Latvia, Australia and the Netherlands in full, Denmark as its register stood on 26 September 2026, the parts of the United States, France and Brazil their registers carry, Berlin, whose register is filed by postcode, and Great Britain's streets by postcode district from Ordnance Survey's Open Names), the answer is the streets that register lists inside the postcode, in its own spelling, sorted and with no house numbers: street, locality, postal_code and country are filled, house_number, unit and identifier stay null. In the United States and its territories a ZIP+4 lists the streets of its five-digit ZIP, and each address's postal_code is that ZIP. An empty list is answered only where the registers' coverage is complete and none of them holds an address at the postcode. A country with neither a licensed list nor an open street listing answers 501 ADDRESS_LIST_UNAVAILABLE and charges nothing, rather than returning an empty list that would read as "there are no addresses here" — and so does a postcode the installed listing cannot speak for, with a message saying which: a code outside the register's area (Northern Irish BT, forces BFPO and BF, and non-geographic BX codes are outside Ordnance Survey's Great Britain data), a postcode in a part of the country no installed register covers (Germany outside Berlin, or a Belgian region whose register is not installed), a postcode the installed register cannot vouch for (a British district Open Names files no street under, since it files each road under one district), and a postcode where a register whose coverage is complete holds addresses but none on a named street (many Czech villages number their houses without one). Nothing else in the address API depends on it.

country is an ISO 3166-1 alpha-2 code and defaults to GB. The postcode is passed in the path, with or without its space (NW1 6XE and NW16XE are the same postcode). At most 100 addresses are returned for one postcode; count is how many the answer carries.

Parameters

name in type description
postcoderequiredpathstringThe postcode to list, in the country's own notation.
countryquerystringAn ISO 3166-1 alpha-2 code the postal format table covers. Default: GB.

Example request

curl https://spaw.co/api/v1/address/postcode/NW1 6XE \
  -H "Authorization: Bearer sk_live_…"
const response = await fetch('https://spaw.co/api/v1/address/postcode/NW1 6XE', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer sk_live_…',
  },
});
const result = await response.json();
import requests

response = requests.get(
    'https://spaw.co/api/v1/address/postcode/NW1 6XE',
    headers={'Authorization': 'Bearer sk_live_…'},
)
result = response.json()
$ch = curl_init('https://spaw.co/api/v1/address/postcode/NW1 6XE');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer sk_live_…'],
]);
$result = json_decode(curl_exec($ch), true);
from spaw import Client

client = Client('sk_live_…')
result = client.addresses_at_postcode('NW1 6XE')
import Spaw from 'spaw';

const spaw = new Spaw({ apiKey: 'sk_live_…' });
const result = await spaw.addressesAtPostcode('NW1 6XE');
use Spaw\Client;

$spaw = new Client('sk_live_…');
$result = $spaw->addressesAtPostcode('NW1 6XE');

This endpoint has no console on its page. A licensed partner's list is billed at 25 credits and an open register's streets at 1, and a partner's list is real money per click rather than a credit off a monthly grant.

Responses

200The addresses the partner lists at that postcode, or the streets an open register lists there — an empty list only where the registers' coverage is complete and none of them holds an address at the postcode.

{
    "success": true,
    "data": {
        "postcode": "NW1 6XE",
        "country": "GB",
        "available": true,
        "addresses": [
            {
                "address_line1": "221B Baker Street",
                "address_line2": null,
                "organization": null,
                "street": "Baker Street",
                "house_number": "221B",
                "unit": null,
                "locality": "London",
                "administrative_area": null,
                "postal_code": "NW1 6XE",
                "country": "GB",
                "identifier": "10023456789"
            }
        ],
        "count": 1
    },
    "meta": {
        "credits_used": 2,
        "credits_remaining": 8,
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

401The key is missing, malformed, or revoked.

{
    "success": false,
    "error": {
        "code": "UNAUTHENTICATED",
        "message": "Provide a valid API key as a bearer token.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

402The balance is empty. The lookup did not run.

{
    "success": false,
    "error": {
        "code": "INSUFFICIENT_CREDITS",
        "message": "Your credit balance is empty.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

422The request body could not be validated; `error.errors` lists the fields.

{
    "success": false,
    "error": {
        "code": "VALIDATION_FAILED",
        "message": "The email field is required.",
        "errors": {
            "email": [
                "The email field is required."
            ]
        },
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

429Over 5 requests per second for the key. Retry after the limit resets.

{
    "success": false,
    "error": {
        "code": "RATE_LIMITED",
        "message": "Too many requests. Retry after the limit resets.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

501Neither a licensed address-list partner nor an open register's street listing covers the country — here Italy, which has neither — or the installed listing cannot speak for the postcode: a code outside the register's area, a postcode in a part of the country no installed register covers, a postcode the installed register cannot vouch for, or one whose addresses are on no named street. The message says which (`The DE street listing does not cover 50667: …` for a Cologne postcode, since the only German register filed by postcode is Berlin's). Nothing was charged.

{
    "success": false,
    "error": {
        "code": "ADDRESS_LIST_UNAVAILABLE",
        "message": "Listing the addresses at a postcode needs a licensed address-list partner or an open register with a street listing, and neither is configured for IT.",
        "request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
    }
}

Error codes

Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.

markdown version·openapi.json