UK Postcode Lookup
Pricing
from $8.50 / 1,000 postcode results
UK Postcode Lookup
Bulk lookup of up to 1,000 Great Britain postcodes: latitude/longitude, eastings/northings, local authority, ward, constituency, LSOA/MSOA and GSS codes from the ONS Postcode Directory via Postcodes.io. Clear not-found, terminated and invalid statuses.
Pricing
from $8.50 / 1,000 postcode results
Rating
0.0
(0)
Developer
Cliqto Media
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Paste a list of Great Britain postcodes. UK Postcode Lookup returns one row per postcode with latitude/longitude, OS grid eastings/northings, local authority, ward, parliamentary constituency, LSOA/MSOA and their official GSS codes from the ONS Postcode Directory (via Postcodes.io). No login or API key is needed.
It is for CRM, logistics, marketing and data teams who need to enrich a postcode column. A run can have just 1 postcode; the 5-postcode example takes a few seconds and costs about $0.05. The full price is paid only for postcodes found with coordinates (active or terminated); other answered rows cost a tiny check fee.

Table of contents
- What it does
- Quick start
- Input
- Output
- Pricing and limits
- Use cases
- Scheduling and monitoring
- API, export and integrations
- Limits and partial results
- Troubleshooting
- FAQ
- Data source and licence
- Support
What it does
You add up to 1,000 postcodes. The Actor cleans each one (case, spaces), looks it up in the ONS Postcode Directory and saves one Dataset row for each input, in the same order. Every row has a status, so you always know why a row has no data.
status | Meaning | Charged? |
|---|---|---|
found | Active postcode with coordinates and areas | Yes (if it has coordinates) |
terminated | Old postcode, no longer used. Last known location and end date only | Yes (if it has coordinates) |
not_found | Valid shape, but not in the directory | Check fee only |
invalid_format | Not a full UK postcode (for example SW1A or hello). No lookup is made | Check fee only |
unsupported_licensed_region | Northern Ireland (BT…). No lookup is made, see limits | Check fee only |
error | The source did not answer. This is not a "not found" answer | No |
Repeated postcodes are looked up once. The repeat row copies the data and has duplicateOfIndex set. It costs only the check fee.
Good fit
- Add map coordinates to a list of customer or store postcodes.
- Join postcodes to ONS statistics with LSOA, MSOA, output area and district GSS codes.
- Group leads by local authority, region or parliamentary constituency.
- Find typos and old postcodes in a CRM export.
Not a fit / limits
- No Northern Ireland (BT) data. Its licence does not allow free commercial reuse.
- No street addresses or house numbers. Coordinates are the postcode centre, not a building.
- No reverse geocoding (coordinates → postcode) and no autocomplete.
- Isle of Man (IM) and Channel Islands (GY, JE) postcodes return
foundbut without coordinates or census areas. Some old IM postcodes areterminatedwithout coordinates.
Quick start
- Open the Input tab.
- Keep the 5 example postcodes in Postcodes (
postcodes) or paste your own, one per line. - Keep Check terminated postcodes (
includeTerminated) on. - Click Start.
- Open the Overview table in the Output tab and check
status,latitudeandadminDistrict.
Expected result: 5 found rows in about 3 seconds, for example SW1A 2AA → Westminster, 51.503541, -0.12767.
Input
Input fields
| Field | Plain name | Type | Required | Default / prefill | Allowed values | Effect | Recommendation |
|---|---|---|---|---|---|---|---|
postcodes | Postcodes | array of strings | yes | prefill: SW1A 2AA, EH99 1SP, CF99 1SN, M60 2LA, B1 1BB | 1–1,000 items | The postcodes to look up. Case and spaces do not matter (sw1a2aa works). Empty lines are skipped. Items longer than 40 characters are cut and marked invalid_format | Split lists over 1,000 into several runs |
includeTerminated | Check terminated postcodes | boolean | no | true | true, false | When a postcode is not active, also check the list of old (terminated) postcodes. Adds one small request per unknown postcode | Keep true for old CRM data. Use false if you only want active postcodes |
An empty list, more than 1,000 items or an unknown field stops the run before any lookup.
Input examples
Enrich a short list
{"postcodes": ["SW1A 2AA", "EH99 1SP", "CF99 1SN", "M60 2LA", "B1 1BB"]}
Expected output: 5 found rows with coordinates, district, ward, constituency and LSOA/MSOA. Cost: 5 results + 1 start.
Clean a messy CRM column
{"postcodes": ["sw1a2aa", "AB1 0AA", "ZZ1 1ZZ", "not a postcode", "BT1 5GS", "SW1A 2AA"],"includeTerminated": true}
Expected output: found, terminated (since 1996-06), not_found, invalid_format, unsupported_licensed_region, and a duplicate of row 0. Cost: 2 results + 4 checks + 1 start.
Output
One Dataset item per input item. All fields are always present; null means "no data", never zero.
Output example
{"inputIndex": 0,"input": "SW1A 2AA","postcode": "SW1A 2AA","status": "found","statusReason": "Active postcode","errorCode": null,"duplicateOfIndex": null,"latitude": 51.503541,"longitude": -0.12767,"eastings": 530047,"northings": 179951,"positionalQuality": 1,"country": "England","region": "London","adminDistrict": "Westminster","adminDistrictCode": "E09000033","adminWard": "St James's","adminWardCode": "E05013806","parliamentaryConstituency": "Cities of London and Westminster","parliamentaryConstituencyCode": "E14001172","lsoa": "Westminster 018C","lsoaCode": "E01004736","msoa": "Westminster 018","msoaCode": "E02000977","introducedOn": "1980-01","terminatedOn": null,"provider": "Postcodes.io (ONS Postcode Directory)","fetchedAt": "2026-10-12T07:46:24.376Z"}
This example is trimmed: the real row also has outcode, incode, county, parish, output area, built-up area, police, NHS and rural-urban fields.
Output fields
| Field | Meaning | Type | Can be empty? | Example |
|---|---|---|---|---|
inputIndex | Position in your input list (starts at 0) | integer | no | 0 |
input | Your value, with outer spaces removed | string | no | sw1a2aa |
postcode | Normalized postcode | string | yes (invalid input) | SW1A 2AA |
status | Row result, see the table above | string | no | found |
statusReason | Plain-English reason | string | no | Active postcode |
errorCode | Technical code, only for error rows | string | yes | SOURCE_UNAVAILABLE |
duplicateOfIndex | For a repeat: inputIndex of the first copy | integer | yes | 0 |
latitude, longitude | WGS84 centre of the postcode | number | yes | 51.503541, -0.12767 |
eastings, northings | OS National Grid reference | integer | yes | 530047, 179951 |
positionalQuality | ONSPD accuracy, 1 (best) to 9 (no grid reference) | integer | yes | 1 |
outcode, incode | The two parts of the postcode | string | yes | SW1A, 2AA |
country, region | Nation and English region | string | yes | England, London |
adminDistrict, adminDistrictCode | Local authority and GSS code | string | yes | Westminster, E09000033 |
adminCounty, adminCountyCode | County (only in two-tier areas) | string | yes | null |
adminWard, adminWardCode | Electoral ward | string | yes | St James's, E05013806 |
parish, parishCode | Parish or unparished area | string | yes | Westminster, unparished area |
parliamentaryConstituency, parliamentaryConstituencyCode | Westminster constituency (2024 boundaries) | string | yes | Cities of London and Westminster, E14001172 |
lsoa, lsoaCode | Census 2021 Lower Layer Super Output Area | string | yes | Westminster 018C, E01004736 |
msoa, msoaCode | Census 2021 Middle Layer Super Output Area | string | yes | Westminster 018, E02000977 |
outputArea | Census 2021 output area code | string | yes | E00023936 |
builtUpArea | Built-up area | string | yes | City of Westminster |
policeForceArea | Police force | string | yes | Metropolitan Police |
nhsIcb | NHS Integrated Care Board | string | yes | NHS West and North London Integrated Care Board |
ruralUrban2021 | Rural-urban classification 2021 | string | yes | Urban: Nearer to a major town or city |
introducedOn | Month the postcode started (YYYY-MM) | string | yes | 1980-01 |
terminatedOn | Month it stopped (YYYY-MM), for terminated postcodes | string | yes | 1996-06 |
provider | Data provider | string | no | Postcodes.io (ONS Postcode Directory) |
sourceUrl | Source endpoint used for this row | string | yes | https://api.postcodes.io/postcodes |
fetchedAt | When the row was fetched (UTC) | string | no | 2026-10-12T07:46:24.376Z |
GSS "not applicable" codes (like E99999999 or M99999999) in code fields and outputArea are returned as null. A terminated row has only coordinates and terminatedOn: the directory keeps no area data for old postcodes.
Output surfaces
| Situation | Where | What you see |
|---|---|---|
| Normal run | Dataset views Overview, Geography, Status details | One row per input |
| Nothing found | Dataset + RUN_SUMMARY | Rows with not_found / invalid_format, run status NO_RESULTS, run succeeds |
| Source problem | Dataset + RUN_SUMMARY | Unfinished rows have status: error; summary PARTIAL or ERROR |
| Stopped early | Dataset + RUN_SUMMARY | Remaining rows have status: error with DEADLINE_REACHED or MAX_CHARGE_REACHED; summary CAPPED |
| Summary | Key-value store record RUN_SUMMARY | status, message, counts per status, charged results, data licence and attribution |
Pricing and limits
Pricing unit
This Actor uses pay-per-event pricing. Platform usage is included: you pay only for these events.
| Event | When | Free plan | Bronze | Silver | Gold+ |
|---|---|---|---|---|---|
| Postcode result | One unique found or terminated postcode with coordinates | $0.01 | $0.0095 | $0.009 | $0.0085 |
| Postcode checked | Any other answered row: not_found, invalid_format, duplicate, Northern Ireland, or found without coordinates | $0.00005 | $0.00005 | $0.00005 | $0.00005 |
| Actor start | Once per run (default 256 MB memory), also when the run fails | $0.002 | $0.002 | $0.002 | $0.002 |
Free: error rows (source problem, time limit or cost cap). A run of 1,000 unknown postcodes costs $0.052.
Cost examples (Free plan prices)
| Scenario | Input | Charged results | Cost |
|---|---|---|---|
| Prefill | 5 postcodes | 5 | $0.052 |
| Typical list | 100 postcodes, 96 found | 96 + 4 checks | $0.962 |
| Full run | 1,000 postcodes, 951 unique found | 951 + 49 checks | $9.514 |
| Nothing found | 3 unknown or invalid postcodes | 0 + 3 checks | $0.002 |
| Many unknown | 1,000 unknown postcodes | 0 + 1,000 checks | $0.052 |
Set Maximum cost per run in the run options to cap spending. When the cap is reached, the Actor stops charging, marks the remaining rows error with MAX_CHARGE_REACHED and sets the summary to CAPPED.
Limits
- Up to 1,000 postcodes per run. A 1,000-postcode run took about 5 seconds in our tests.
- Internal time limit for lookups: 240 seconds.
- With
includeTerminated: true, every unknown postcode needs one extra request (about 0.25 s each). A list with many hundreds of unknown postcodes can reach the 240-second limit: the remaining rows areerrorwithDEADLINE_REACHED(free) and the summary isCAPPED.
Use cases
| Buyer job | Input | Key fields | Next step |
|---|---|---|---|
| Map customers | postcodes from a CRM column | latitude, longitude, status | Map tool, BI dashboard |
| Join to ONS statistics | postcodes | lsoaCode, msoaCode, outputArea, adminDistrictCode | ONS / Census tables |
| Sales territories | postcodes | region, adminDistrict, adminCounty, parliamentaryConstituency | CRM fields |
| Data cleaning | postcodes | status, postcode (normalized), terminatedOn | Fix or remove bad records |
Scheduling and monitoring
- The ONS Postcode Directory is updated about every three months. To keep a list fresh, schedule a run after each update and compare
statusandterminatedOnwith the last run. - Watch
RUN_SUMMARY.status:COMPLETEandNO_RESULTSare normal,PARTIALandERRORmean the source had a problem.
API, export and integrations
- API: start a run with
POST https://api.apify.com/v2/acts/cliqtomedia~gb-postcode-lookup/runsand the input JSON, then read the default Dataset. See the API tab for ready code. - Export: download the Dataset as CSV, Excel, JSON or XML from the Output tab.
- No-code: connect the Actor in Make, Zapier or n8n with the Apify integration.
Use with AI agents (MCP)
- MCP server with only this Actor:
https://mcp.apify.com?tools=cliqtomedia/gb-postcode-lookup - Smallest useful input:
{"postcodes": ["SW1A 2AA"]} - Key output fields:
status(found / terminated / not_found / invalid_format / unsupported_licensed_region / error),latitude,longitude,adminDistrict,lsoaCode. - A run with up to 100 postcodes usually finishes in under 10 seconds. Cost: $0.002 per run plus $0.0085–$0.01 per found postcode and $0.00005 per other answered row. Up to 1,000 postcodes per run; Northern Ireland is not supported.
Limits and partial results
- Northern Ireland (BT): NI postcode data needs a commercial licence from Land & Property Services. These rows are marked
unsupported_licensed_regionbefore any lookup and cost only the check fee. - Freshness: data follows the ONS Postcode Directory loaded by Postcodes.io (ONSPD August 2026 when we checked on 2026-10-12). It is updated quarterly. Very new postcodes may be
not_founduntil the next update. - Source problems: requests have a 20-second timeout and up to 3 tries. If the source stops answering, the rest of the rows are saved as
error(notnot_found) and are not charged. The summary saysPARTIAL(some results) orERROR(none, the run fails).
Troubleshooting
Many rows are invalid_format
Symptom: rows like SW1A or SW1A-2AA are not looked up.
Reason: the Actor needs a full postcode (outward and inward part). Letters, digits and spaces only.
Action: fix the column in your source, for example remove dashes, and run again.
A postcode I know is real is not_found
Reason: it may be very new (not yet in the quarterly directory) or mistyped.
Action: check statusReason, try includeTerminated: true, or check again after the next ONSPD update.
Rows have status: error
Reason: Postcodes.io did not answer in time or limited requests. These rows are free.
Action: open RUN_SUMMARY for errorCode, then run the same input again later.
FAQ
Do I need an API key or account for Postcodes.io?
No. The Actor uses the public Postcodes.io API without a key.
Why do terminated postcodes have no district or ward?
The directory keeps only the last location and end date for old postcodes. Use latitude/longitude if you need an area.
Am I charged for duplicates or errors?
error rows are free. Duplicates and other rows without a paid result cost $0.00005 each. The full price is charged only for the first copy of a found or terminated postcode with coordinates, plus $0.002 per run.
Is the data complete?
It covers active and terminated postcodes in England, Scotland and Wales from the ONS Postcode Directory. Isle of Man and Channel Islands postcodes are listed but have no coordinates. Coordinates are postcode centres. Some areas, like county or parish, are empty where they do not apply.
Data source and licence
Data: ONS Postcode Directory via Postcodes.io. Great Britain postcode data may be used under the Open Government Licence v3.0 and OS OpenData terms. Attribution (also in RUN_SUMMARY):
Contains Ordnance Survey data © Crown copyright and database right 2025. Contains Royal Mail data © Royal Mail copyright and database right 2025. Contains National Statistics data © Crown copyright and database right 2025. Contains NRS data © Crown copyright and database right 2025. Source: Office for National Statistics licensed under the Open Government Licence v3.0.
This Actor is not affiliated with ONS, Ordnance Survey, Royal Mail or Postcodes.io.
Support
For bugs, questions or feature requests, open an issue in the Issues tab. Include the run ID and the postcodes that look wrong. Do not send private customer data.