UK Postcode Lookup

The JSON API gives access to Royal Mail PAF data and Geocoding. It supports CORSopen in new window, can return data as JSON or JSONP and allows sorting.

Before you do lots of work, please check our list of Address Finder Pluginsopen in new window. You might find something suitable there.

We also have a wrapper for our JSON API on Github:

JSON API wrapper on Githubopen in new window

WARNING

  • This API gives access to UK address data only.
  • All API parameters must be in lowercase.

If you are looking to implement an international solution, please look at our Global Address Auto-Complete APIopen in new window.

Full Address (RapidAddress)

RapidAddress returns full address details for every address matching the search query postcode.

HTTP(S) Request

GET/POST http://pcls1.craftyclicks.co.uk/json/rapidaddress

or

GET/POST https://pcls1.craftyclicks.co.uk/json/rapidaddress

Query Parameters

Pass parameters either as GET or POST in JSON.

KeyTypeValuesRequiredDefaultDescription
keystringYour 20 digit code✔️Using the API requires a 20 character access token, which you should insert here. You will receive an access token when you sign up for an account.
postcodestringA UK postcode✔️This is the postcode for which you want to request data
callbackbooleantrue, falsefalseIf callback is set, the JSON data will be wrapped as JSONP with the function name from the callback
responsestringpaf_compact: Address data returned in separate fields, data_formatted: Address lines are pre-formattedpaf_compactThis sets the format of the response from the API.
linesstring1, 2, 32Only active when response is set to data_formatted. This sets the number of address lines in the response from the API.
sortstringnone: Results are not sorted, asc: Results returned in ascending order, desc: results returned in descending ordernoneThis option sets how the results are sorted in the response.
include_geocodestringtrue, falsefalseSets whether or not to include the geocoding data. Please note that the usage of this feature within this API endpoint is free.

TIP

We suggest using response=data_formatted in most cases, as it’s easier to work with. Use response=paf_compact only if you require all address parts separated out.

Example request

function getTestData(){
    // Pass parameters via JSON
    var parameters = {
        key: "xxxxx-xxxxx-xxxxx-xxxxx",
        postcode: "aa11aa",
        response: "data_formatted"
    };
    var url = "http://pcls1.craftyclicks.co.uk/json/rapidaddress";
    // or via GET parameters
    // var url = "http://pcls1.craftyclicks.co.uk/json/rapidaddress?key=xxxxx-xxxxx-xxxxx-xxxxx&postcode=aa11aa&response=data_formatted";

    request = new XMLHttpRequest();
    request.open('POST', url, false);
    // Only needed for the JSON parameter pass
    request.setRequestHeader('Content-Type', 'application/json');
    // Wait for change and then either JSON parse response text or throw exception for HTTP error
    request.onreadystatechange = function() {
        if (this.readyState === 4){
            if (this.status >= 200 && this.status < 400){
                // Success!
                data = JSON.parse(this.responseText);
            } else {
                throw 'HTTP Request Error';
            }
        }
    };
    // Send request
    request.send(JSON.stringify(parameters));
    return data;
}

// console.log(getTestData());
import urllib2
import urllib
import json

def getTestData():
    url = "https://pcls1.craftyclicks.co.uk/json/"

    url += 'rapidaddress'
    params = {
        'postcode': 'aa11aa',
        'key': 'xxxxx-xxxxx-xxxxx-xxxxx',
        'response': 'data_formatted'
    }

    req = urllib2.Request(url + '?' + urllib.urlencode(params))

    res = urllib2.urlopen(req)
    data = json.loads(res.read())
    return data

#print json.dumps(getTestData(), sort_keys=True, indent=4, separators=(',', ': '))
<?php
function getTestData(){
    $data = array(
        "postcode"  => "aa11aa",
        "key"       => "xxxxx-xxxxx-xxxxx-xxxxx",
        "response"  => "data_formatted"
    );
    $data_string = json_encode($data);

    $ch = curl_init('http://pcls1.craftyclicks.co.uk/json/rapidaddress');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data_string))
    );

    $result = curl_exec($ch);
    return $result;
}
// echo '<pre>'.getTestData().'</pre>';
?>

Response: data_formatted

For each postcode, the response contains the following information:

KeyTypeDescription
delivery_pointsarrayThis is an array of objects, each of which contains the data for an individual address. See the table below for more details about the information contained in these objects.
delivery_point_countintegerNumber of elements in the delivery_points array
postal_countystringFormer postal county for this postcode
traditional_countystringTraditional county for this postcode
townstringTown name in uppercase (Royal Mail standard)
postcodestringFormatted postcode

data_formatted: delivery_points

KeyTypeDescription
organisation_namestringRegistered organisation at the address.
department_namestringSpecific department of said organisation.
line_1stringLine 1 of the address
line_2stringLine 2 of the address
line_3stringLine 3 of the address
udprnstringRoyal Mail unique identifier
dpsstringDelivery point suffix

The API will respond to the request with the following structure.

{
    "delivery_points":[
        {
            "organisation_name":"THE BAKERY",
            "department_name":"",
            "line_1":"1 HIGH STREET",
            "line_2":"CRAFTY VALLEY",
            "udprn":"12345678",
            "dps":"1A"
        },
        {
            "organisation_name":"FILMS R US",
            "department_name":"",
            "line_1":"3 HIGH STREET",
            "line_2":"CRAFTY VALLEY",
            "udprn":"12345679",
            "dps":"1B"
        }
    ],
    "delivery_point_count":2,
    "postal_county":"POSTAL COUNTY",
    "traditional_county":"TRADITIONAL COUNTY",
    "town":"BIG CITY",
    "postcode":"AA1 1AA"
}

Response: paf_compact

For each postcode, the response contains the following information:

KeyTypeDescription
thoroughfaresarrayThis array contains thoroughfare details and delivery_points, an array containing all the address details for every address matching the postcode. See the table below for more details.
thoroughfare_countintegerNumber of elements in the thoroughfares array
postal_countystringFormer postal county for this postcode
traditional_countystringTraditional county for this postcode
townstringTown name in uppercase (Royal Mail standard)
postcodestringFormatted postcode
dependent_localitystringSub-locality within town or city
double_dependent_localitystringDistrict within sub-locality

paf_compact: thoroughfares

KeyTypeDescription
delivery_pointsarrayThis is an array of objects, each of which contains the data for an individual address. See the table below for more details about the information contained in these objects.
delivery_point_countintegerNumber of elements in the delivery_points array
dependent_thoroughfare_namestringName of the dependent thoroughfare
dependent_thoroughfare_descriptorstringThe dependent thoroughfare descriptor, e.g. Road, Street, Avenue
thoroughfare_namestringName of the thoroughfare
thoroughfare_descriptorstringThe thoroughfare descriptor, e.g. Road, Street, Avenue

paf_compact: delivery_points

KeyTypeDescription
organisation_namestringRegistered organisation at the address.
department_namestringSpecific department of said organisation.
po_box_numberstringPO Box number
building_numberstringNumber of building
sub_building_namestringSub-name of building
building_namestringName of building
udprnstringRoyal Mail unique identifier
dpsstringDelivery point suffix

The API will respond to the request with the following structure.

{
    "thoroughfare_count": 1,
    "thoroughfares": [
        {
            "delivery_points": [
                {
                    "organisation_name": "THE BAKERY",
                    "department_name": "",
                    "po_box_number": "",
                    "building_number": "1",
                    "sub_building_name": "",
                    "building_name": "",
                    "udprn": "12345678",
                    "dps":"1A"
                },
                {
                    "organisation_name": "FILMS R US",
                    "department_name": "",
                    "po_box_number": "",
                    "building_number": "3",
                    "sub_building_name": "",
                    "building_name": "",
                    "udprn": "12345679",
                    "dps":"1B"
                }
            ],
            "delivery_point_count": 2,
            "dependent_thoroughfare_name": "",
            "dependent_thoroughfare_descriptor": "",
            "thoroughfare_name": "HIGH",
            "thoroughfare_descriptor": "STREET"
        }
    ],
    "postal_county": "POSTAL COUNTY",
    "traditional_county": "TRADITIONAL COUNTY",
    "dependent_locality": "CRAFTY VALLEY",
    "double_dependent_locality": "",
    "town": "BIG CITY",
    "postcode": "AA1 1AA"
}

Street Level (BasicAddress)

BasicAddress returns details of every street matching the search query postcode.

HTTP(s) Request

GET/POST http://pcls1.craftyclicks.co.uk/json/basicaddress

or

GET/POST https://pcls1.craftyclicks.co.uk/json/basicaddress

Query Parameters

Pass parameters either in GET or in JSON.

KeyTypeValuesRequiredDefaultDescription
keystringYour 20 digit code✔️Using the API requires a 20 character access token, which you should insert here. You will receive an access token when you sign up for an account.
postcodestringA UK postcode✔️This is the postcode for which you want to request data
callbackbooleantrue, falsefalseIf callback is set, the JSON data will be wrapped as JSONP with the function name from the callback
responsestringpaf_compact: All address data returned, data_formatted: Address lines are pre-formattedpaf_compactThis sets the format of the response from the API.
linesinteger1, 2, 32Only active when response is set to data_formatted. This sets the number of address lines in the response from the API.
sortstringnone: Results are not sorted, asc: Results returned in ascending order, desc: results returned in descending order.noneThis option sets how the results are sorted in the response.
include_geocodebooleantrue, falsefalseSets whether or not to include the geocoding data. Please note that the usage of this feature within this API endpoint is free. If set, it will return the same dataset as the Geocoding API endpoint. (Please view the Geocoding documentation for the details)

TIP

We suggest using response=data_formatted in most cases, as it’s easier to work with. Use response=paf_compact only if you require all address parts separated out.

Example request

function getTestData(){
    // Pass parameters via JSON
    var parameters = {
        key: "xxxxx-xxxxx-xxxxx-xxxxx",
        postcode: "aa11aa",
    };
    var url = "http://pcls1.craftyclicks.co.uk/json/basicaddress";
    // or via GET parameters
    // var url = "http://pcls1.craftyclicks.co.uk/json/basicaddress?key=xxxxx-xxxxx-xxxxx-xxxxx&postcode=aa11aa&response=data_formatted";

    request = new XMLHttpRequest();
    request.open('POST', url, false);
    // Only needed for the JSON parameter pass
    request.setRequestHeader('Content-Type', 'application/json');
    // Wait for change and then either JSON parse response text or throw exception for HTTP error
    request.onreadystatechange = function() {
        if (this.readyState === 4){
            if (this.status >= 200 && this.status < 400){
                // Success!
                data = JSON.parse(this.responseText);
            } else {
                throw 'HTTP Request Error';
            }
        }
    };
    // Send request
    request.send(JSON.stringify(parameters));
    return data;
}

// console.log(getTestData());
import urllib2
import urllib
import json

def getTestData():
    url = "https://pcls1.craftyclicks.co.uk/json/"

    url += 'basicaddress'
    params = {
        'postcode': 'aa11aa',
        'key': 'xxxxx-xxxxx-xxxxx-xxxxx',
        'response': 'data_formatted'
    }

    req = urllib2.Request(url + '?' + urllib.urlencode(params))

    res = urllib2.urlopen(req)
    data = json.loads(res.read())
    return data

#print json.dumps(getTestData(), sort_keys=True, indent=4, separators=(',', ': '))
<?php
function getTestData(){
    $data = array(
        "postcode"  => "aa11aa",
        "key"       => "xxxxx-xxxxx-xxxxx-xxxxx",
        "response"  => "data_formatted"
    );
    $data_string = json_encode($data);

    $ch = curl_init('http://pcls1.craftyclicks.co.uk/json/basicaddress');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data_string))
    );

    $result = curl_exec($ch);
    return $result;
}
// echo '<pre>'.getTestData().'</pre>';
?>

Response: data_formatted

For each postcode, the response contains the following information:

KeyTypeDescription
thoroughfaresarrayThis array contains thoroughfare details. See the table below for more details.
thoroughfare_countintegerNumber of elements in the thoroughfares array
postal_countystringFormer postal county for this postcode
traditional_countystringTraditional county for this postcode
townstringTown name in uppercase (Royal Mail standard)
postcodestringFormatted postcode

thoroughfares

KeyTypeDescription
line_1stringLine 1 of the formatted address
line_2stringLine 2 of the formatted address
line_3stringLine 3 of the formatted address

The API will respond to the request with the following structure.

{
    "thoroughfares": [
        {
            "line_1": "HIGH STREET",
            "line_2": "CRAFTY VALLEY"
        }
    ],
    "thoroughfare_count": 1,
    "postal_county": "POSTAL COUNTY",
    "traditional_county": "TRADITIONAL COUNTY",
    "town": "BIG CITY",
    "postcode": "AA1 1AA"
}

Response: paf_compact

For each postcode, the response contains the following information:

KeyTypeDescription
thoroughfaresarrayThis array contains thoroughfare details. See the table below for more details.
thoroughfare_countintegerNumber of elements in the thoroughfares array
postal_countystringFormer postal county for this postcode
traditional_countystringTraditional county for this postcode
townstringTown name in uppercase (Royal Mail standard)
postcodestringFormatted Postcode
dependent_localitystringSub-locality within town or city
double_dependent_localitystringDistrict within sub-locality

thoroughfares

KeyTypeDescription
dependent_thoroughfare_namestringName of the dependent thoroughfare
dependent_thoroughfare_descriptorstringThe dependent thoroughfare descriptor, e.g. Road, Street, Avenue
thoroughfare_namestringName of the thoroughfare
thoroughfare_descriptorstringThe thoroughfare descriptor, e.g. Road, Street, Avenue

The API will respond to the request with the following structure.

{
    "thoroughfare_count": 1,
    "thoroughfares": [
        {
            "dependent_thoroughfare_name": "",
            "dependent_thoroughfare_descriptor": "",
            "thoroughfare_name": "HIGH",
            "thoroughfare_descriptor": "STREET"
        }
    ],
    "postal_county": "POSTAL COUNTY",
    "traditional_county": "TRADITIONAL COUNTY",
    "dependent_locality": "CRAFTY VALLEY",
    "double_dependent_locality": "",
    "town": "BIG CITY",
    "postcode": "AA1 1AA"
}