Skip to content

Addresses

Three operations for addresses in 34 countries: the EU, the EEA, Switzerland, the United Kingdom, Turkey and the United Arab Emirates.

Operation Endpoint What it does
address.forms GET /v1/address/forms, GET /v1/address/forms/{country} The fields of an address in a country, which are required, the postcode and the subdivisions.
address.validate POST /v1/address/validate Checks an address against its country and returns it normalised.
address.format POST /v1/address/format Writes an address as the lines its country prints it on.

A key needs the scope address, or the operation itself (see scopes).

Availability. address.forms is live and free. address.validate and address.format are in preview and have no price yet: a live key gets 503 operation_unavailable until they have one. Test keys already get real answers from all three, for free. Current prices are in GET /v1/pricing.

The countries: AE AT BE BG CH CY CZ DE DK EE ES FI FR GB GR HR HU IE IS IT LI LT LU LV MT NL NO PL PT RO SE SI SK TR.

Terminal window
curl https://api.accountcloud.io/v1/address/forms/NL \
-H "Authorization: Bearer ac_test_…"
{
"country": "NL",
"verified": true,
"fields": [
{
"id": "street",
"label": "Street",
"type": "text",
"required": true,
"max_length": 255,
"options": null,
"options_source": null,
"example": null,
"autocomplete": "address-line1",
"layout": { "row": 1, "column": 1, "span": 8 }
},
{
"id": "postal_code",
"label": "Postal code",
"type": "text",
"required": true,
"max_length": 20,
"options": null,
"options_source": null,
"example": "1234 AB",
"autocomplete": "postal-code",
"layout": { "row": 3, "column": 5, "span": 4 }
}
],
"postcode": { "pattern": "[1-9]\\d{3} ?(?:[A-RT-Z][A-Z]|S[BCE-RT-Z])", "example": "1234 AB" },
"subdivisions": []
}

The example is shortened: NL has six fields (street, house_number, house_number_addition, address_line_2, postal_code and city).

  • fields are in the order to ask them. A field’s id is its key in the address of the other two operations.
  • type is text, or select for a closed list: its options, or the country’s subdivisions when options_source is subdivisions.
  • autocomplete is the HTML autocomplete token. layout places the field on a 12-column grid.
  • postcode.pattern is a regular expression for the normalised postcode; null where a country has no postcodes.
  • subdivisions are the provinces, states or regions, where the country uses them. Send the code.
  • verified says whether the form was checked against the rules of the country’s postal operator.

Add ?locale=nl for Dutch labels; the default is en. GET /v1/address/forms returns the forms of all countries in data, or only those in ?countries=NL,BE,DE. A country we do not support gets 404 country_not_supported, with the list in supported_countries.

Send country and the fields of that country’s form, by id:

Terminal window
curl https://api.accountcloud.io/v1/address/validate \
-H "Authorization: Bearer ac_test_…" \
-H "Content-Type: application/json" \
-d '{"address": {"country": "NL", "street": "Hoofdstraat", "house_number": "12", "postal_code": "1234ab", "city": "Amsterdam"}}'
{
"valid": true,
"address": { "country": "NL", "street": "Hoofdstraat", "house_number": "12", "postal_code": "1234 AB", "city": "Amsterdam" },
"errors": []
}

address is the address normalised: trimmed, empty fields left out, the postcode in its national form and a subdivision as its code. Store that one.

An incomplete or wrong address is still a 200, with valid: false and what is wrong per field:

{
"valid": false,
"address": { "country": "NL", "street": "Hoofdstraat", "postal_code": "12345", "city": "Amsterdam" },
"errors": [
{ "field": "postal_code", "code": "postcode_invalid", "message": "This is not a valid postcode in NL, for example 1234 AB." }
]
}

The code of an error is required, too_long, postcode_invalid, subdivision_invalid, invalid_option or unknown_field. A missing or unsupported country, or a field that is not a string, is a 422 validation_failed.

Terminal window
curl https://api.accountcloud.io/v1/address/format \
-H "Authorization: Bearer ac_test_…" \
-H "Content-Type: application/json" \
-d '{"address": {"country": "NL", "street": "Hoofdstraat", "house_number": "12", "postal_code": "1234ab", "city": "Amsterdam"}, "from_country": "BE"}'
{
"country": "NL",
"lines": ["Hoofdstraat 12", "1234 AB Amsterdam", "Netherlands"],
"text": "Hoofdstraat 12\n1234 AB Amsterdam\nNetherlands"
}

The lines follow the convention of the address’s country, not the sender’s, without the name of the recipient. A valid postcode is normalised first.

  • from_country is the country the letter is sent from. When it differs from the address’s country, the country line is added. Leave it out for a domestic address.
  • locale is the language of the country line, such as nl for Nederland. The default is en.

Unlike validation, a field that the country’s form does not have is a 422 validation_failed here.

The address forms are partly based on the address data of Google’s libaddressinput, licensed under CC BY 4.0, with our own changes per country.