- authentication
- Secret API key as a bearer token
- billing
- 1 credit per answered postcode, free for the next seven days for the same postcode; in the United States and its territories every ZIP+4 in one ZIP counts as that ZIP. A country or postcode with nothing to list, and a postcode the listing does not cover, cost nothing.
Answers every street a national address register lists inside one postcode, in the register's own spelling and sorted: the list behind a street picker under a postcode field, and the list a single lookup's street_suggestion is drawn from. One call returns the whole postcode, so a form filters locally as the visitor types rather than calling per keystroke.
Open data only: the registers publish their streets and Spaw lists them back, with no house numbers and nothing about who is there. Available wherever a register with a 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 (the North Rhine-Westphalia and Rhineland-Palatinate registers are filed by town, so they list no street at a postcode), and Great Britain by postcode district from Ordnance Survey's Open Names. Where several registers share a country region by region, as Belgium's three do, the postcode is read from the register that lists streets there, and register names it. A country with no such register, a postcode no register lists a street at, and a postcode the listing does not cover all answer 404 ADDRESS_STREETS_NOT_FOUND and cost nothing, and the message says which. No street is listed at 9999 in CH. is the answer only where the registers' coverage is complete and none of them holds an address at the postcode; 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), a postcode the installed register cannot vouch for (a British district Open Names files no street under) and one where a register whose coverage is complete holds addresses but none on a named street (many Czech villages) each say so, rather than reading as a postcode with no street.
country is an ISO 3166-1 alpha-2 code the postal format table covers and postal_code the postcode in the country's own notation, with or without its space. In Great Britain the outward code alone (N1, SW1A) is accepted too, because the listing is filed by postcode district. In the United States and its territories a ZIP+4 answers every street in its five-digit ZIP, because no register files streets by the four-digit add-on; the answer names the ZIP, and every spelling of one ZIP shares the seven-day repeat marker.
Parameters
| name | in | type | description |
|---|---|---|---|
| countryrequired | query | string | An ISO 3166-1 alpha-2 code the postal format table covers, in either case. 2 to 2 characters. |
| postal_coderequired | query | string | The postcode to list, in the country's own notation. At most 32 characters. |
Example request
curl https://spaw.co/api/v1/address/streets \ -H "Authorization: Bearer sk_live_…"
This endpoint has no console on its page. It bills per postcode and has no free guest path; the address checker under /tools/address-checker answers a single address for nothing.
Responses
200The streets the register lists at that postcode.
{
"success": true,
"data": {
"country": "CH",
"postal_code": "8001",
"register": "ch-gebaeudeadressverzeichnis",
"streets": [
"Bahnhofstrasse",
"Limmatquai",
"Münsterhof",
"Paradeplatz",
"Rennweg"
],
"count": 5
},
"meta": {
"credits_used": 1,
"credits_remaining": 9,
"cache_hit": false,
"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"
}
}404No register with a street listing covers the country, the registers list no street at the postcode, or the listing does not cover the postcode; the message says which. Nothing was charged.
{
"success": false,
"error": {
"code": "ADDRESS_STREETS_NOT_FOUND",
"message": "No street is listed at 9999 in CH.",
"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"
}
}Error codes
Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.