JavaScript API for api.ideal-postcodes.co.uk
@ideal-postcodes/core-interface
is an environment agnostic implementation of the Ideal Postcodes JavaScript API client interface.
If you are looking for the browser or Node.js client which implements this interface, please check out the downstream clients links.
Links
Downstream Clients
Documentation
Methods
Usage
To install, pick one of the following based on your platform
npm install @ideal-postcodes/core-browser
npm install @ideal-postcodes/core-node
npm install @ideal-postcodes/core-interface
Instantiate a client with
import { Client } from "@ideal-postcodes/core-<package-type>";
const client = new Client({ api_key: "iddqd" });
Client configuration options
Quick Methods
The library exposes a number of simple methods to get at the most common tasks when interacting with the API
Lookup a Postcode
Return addresses associated with a given postcode
Invalid postcodes (i.e. postcode not found) return an empty array []
import { lookupPostcode } from "@ideal-postcodes/core-browser";
const postcode = "id11qd";
lookupPostcode({ client, postcode }).then(addresses => {
console.log(addresses);
{
postcode: "ID1 1QD",
line_1: "2 Barons Court Road",
}
});
lookupPostcode
docs
Search for an Address
Return addresses associated with a given query
import { lookupAddress } from "@ideal-postcodes/core-browser";
const query = "10 downing street sw1a";
lookupAddress({ client, query }).then(addresses => {
console.log(addresses);
{
postcode: "SW1A 2AA",
line_1: "Prime Minister & First Lord Of The Treasury",
}
});
lookupAddress
docs
Search for an Address by UDPRN
Return address for a given udprn
Invalid UDPRN will return null
import { lookupUdprn } from "@ideal-postcodes/core-browser";
const udprn = 23747771;
lookupUdprn({ client, udprn }).then(address => {
console.log(address);
{
postcode: "SW1A 2AA",
line_1: "Prime Minister & First Lord Of The Treasury",
}
});
lookupUdprn
docs
Search for an Address by UMPRN
Return address for a given umprn
Invalid UMPRN will return null
import { lookupUmprn } from "@ideal-postcodes/core-browser";
const umprn = 50906066;
lookupUmprn({ client, umprn }).then(address => {
console.log(address);
{
postcode: "CV4 7AL",
line_1: "Room 1, Block 1 Arthur Vick",
}
});
lookupUmprn
docs
Check Key Usability
Check if a key is currently usable
checkKeyUsability({ client }).then((key) => {
console.log(key.available);
});
checkKeyUsability
docs
Resources
Resources defined in the API documentation are exported by the library. Each resource exposes a method (#retrieve
, #list
, etc) which maps to a resource action.
These methods expose a low level interface to execute HTTP requests and observe HTTP responses. They are ideal if you have a more complex query or usecase where low level access would be useful.
Resource methods return a promise with a HTTP response object type.
Retrieve
Requesting a resource by ID (e.g. a postcode lookup for postcode with ID "SW1A 2AA") maps to the #retrieve
method.
The first argument is the client object. The second is the resource ID. The last argument is an object which accepts header
and query
attributes that map to HTTP header and the request querystring.
resourceName.retrieve(client, "id", {
query: {
api_key: "foo",
tags: "this,that,those",
licensee: "sk_99dj3",
},
header: {
"IDPC-Source-IP": "8.8.8.8",
},
timeout: 5000,
});
List
Requesting a resource endpoint (e.g. an address query to /addresses
) maps to the #list
method.
resourceName.list(client, {
query: {
api_key: "foo",
query: "10 downing street",
},
header: {
"IDPC-Source-IP": "8.8.8.8",
},
timeout: 5000,
});
The first argument is the client. The second is an object which accepts header
and query
attributes that map to HTTP header and the request querystring.
Custom Actions
Some endpoints are defined as custom actions, e.g. /keys/:key/usage
. These can be invoked using the name of the custom action.
E.g. for key usage data extraction
keys.usage(client, api_key, {
query: {
tags: "checkout,production",
},
header: {
Authorization: 'IDEALPOSTCODES user_token="foo"',
},
timeout: 5000,
});
Resource Methods
Listed below are the available resources exposed by the library:
Postcodes
Retrieve addresses for a postcode.
import { postcodes } from "@ideal-postcodes/core-browser";
postcodes
.retrieve(client, "SW1A2AA", {
header: {
Authorization: 'IDEALPOSTCODES api_key="iddqd"',
},
})
.then((response) => {
const addresses = response.body.result;
})
.catch((error) => logger(error));
Postcode resource HTTP API documentation
Postcode resource docs
Addresses
Search for an address
import { addresses } from "@ideal-postcodes/core-browser";
addresses
.list(client, {
query: {
query: "10 Downing street",
},
header: {
Authorization: 'IDEALPOSTCODES api_key="iddqd"',
},
})
.then((response) => {
const addresses = response.body.result.hits;
})
.catch((error) => logger(error));
Address resource HTTP API documentation
Address resource client docs
Autocomplete
Autocomplete an address given an address partial
import { autocomplete } from "@ideal-postcodes/core-browser";
autocomplete
.list(client, {
query: {
query: "10 Downing stre",
},
header: {
Authorization: 'IDEALPOSTCODES api_key="iddqd"',
},
})
.then((response) => {
const suggestions = response.body.result.hits;
})
.catch((error) => logger(error));
Autocomplete resource HTTP API documentation
Autocomplete resource client docs
UDPRN
Retrieve an address given a UDPRN
import { udprn } from "@ideal-postcodes/core-browser";
udprn
.retrieve(client, "12345678", {
header: {
Authorization: 'IDEALPOSTCODES api_key="iddqd"',
},
})
.then((response) => {
const address = response.body.result;
})
.catch((error) => logger(error));
UDPRN resource HTTP API documentation
UDPRN resource client docs
UMPRN
Retrieve a multiple residence premise given a UMPRN
import { umprn } from "@ideal-postcodes/core-browser";
umprn
.retrieve(client, "87654321", {
header: {
Authorization: 'IDEALPOSTCODES api_key="iddqd"',
},
})
.then((response) => {
const address = response.body.result;
})
.catch((error) => logger(error));
UMPRN resource HTTP API documentation
UMPRN resource client docs
Keys
Find out if a key is available
import { keys } from "@ideal-postcodes/core-browser";
keys
.retrieve(client, "iddqd", {})
.then((response) => {
const { available } = response.body.result;
})
.catch((error) => logger(error));
Method docs
Get private information on key (requires user_token)
import { keys } from "@ideal-postcodes/core-browser";
keys
.retrieve(client, "iddqd", {
header: {
Authorization: 'IDEALPOSTCODES user_token="secret-token"',
},
})
.then((response) => {
const key = response.body.result;
})
.catch((error) => logger(error));
Method docs
Get key usage data
import { keys } from "@ideal-postcodes/core-browser";
keys
.usage(client, "iddqd", {
header: {
Authorization: 'IDEALPOSTCODES user_token="secret-token"',
},
})
.then((response) => {
const key = response.body.result;
})
.catch((error) => logger(error));
Method docs
Keys resource HTTP API documentation
Key resource client docs
Error Handling
This library exports a static variable errors
which contains custom error constructors that wrap specific API errors. These constructors can be used to test for specific cases using the instanceof
operator.
For example:
const { IdpcInvalidKeyError } = Client.errors;
try {
const addresses = await lookupPostcode({ client, postcode: "SW1A2AA" });
} catch (error) {
if (error instanceof IdpcInvalidKeyError) {
}
}
Not all specific API errors will be caught. If a specific API error does not have an error constructor defined, a more generic error (determined by the HTTP status code) will be returned.
For example:
import {
IdpcRequestFailedError,
lookupPostcode,
} from "@ideal-postcodes/core-browser";
try {
const addresses = await lookupPostcode({ client, postcode: "SW1A2AA" });
} catch (error) {
if (error instanceof IdpcRequestFailedError) {
}
}
You may view a sketch of the error prototype chain.
Core Interface Errors
For more advanced use cases, this core-interface library provides:
Error Usage
Aside from inspecting the HTTP request status code and/or JSON body response codes, you may also test for specific error instances.
Errors that don't inherit from IdealPostcodesError
would indicate some kind of error external to the API (e.g. bad network, request timeout).
import { errors } from "@ideal-postcodes/core-browser";
const { IdpcPostcodeNotFoundError } = errors;
if (error instanceof IdpcPostcodeNotFoundError) {
}
switch (true) {
case error instanceof IdpcPostcodeNotFoundError:
default:
}
Error Prototype Chain
All errors inherit from JavaScript's Error
prototype.
Errors are grouped by HTTP status code classes.
Specific errors may be supplied for the following reasons:
- Convenience. They are frequently tested for (e.g. invalid postcode, postcode not found)
- Useful for debug purposes during the implementation stages
Prototype Chain
# Parent class inherits from Javascript Error. Returned if no JSON Response body
IdealPostcodesError < Error
|
|- IdpcApiError # Generic Error Class, returned if JSON response body present
|
|- IdpcBadRequestError # 400 Errors
|- IdpcUnauthorisedError # 401 Errors
|- IdpcRequestFailedError # 402 Errors
| |- IdpcBalanceDepletedError
| |- IdpcLimitReachedError
|
|- IdpcResourceNotFoundError # 404 Errors
| |- IdpcPostcodeNotFoundError
| |- IdpcKeyNotFoundError
| |- IdpcUdprnNotFoundError
| |- IdpcUmprnNotFoundError
|
|- IdpcServerError # 500 Errors
Error Parser
The error parser consumes a HTTP API response and returns the correct error instance.
import { errors } from "@ideal-postcodes/core-browser";
const { parse, IdpcPostcodeNotFoundError } = errors;
const invalidPostcodeUrl = "https://api.ideal-postcodes.co.uk/v1/postcodes/bad_postcode?api_key=iddqd"
const response = await fetch(invalidPostcodeUrl);
const error = parse(response);
if (error instanceof IdpcPostcodeNotFoundError) {...}
Test
npm test
Licence
MIT