# UK Postcode API
> UK postcode and geography lookup as an API, built on the open postcodes.io dataset. Resolve any UK postcode to its latitude/longitude and full administrative hierarchy — district, ward, county, parish, parliamentary constituency, region, NHS health authority and statistical areas (LSOA, MSOA). Validate a postcode, reverse-geocode coordinates to the nearest postcodes (with distance), find postcodes near a given one, autocomplete a partial postcode for address forms, look up an outcode (the first half, e.g. SW1A) and fetch a random postcode. Real data, no key needed upstream. Ideal for checkout and address forms, delivery and logistics, store locators, and UK geo-analytics.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/postcode-api/..."
```

## Pricing
- **Free** (Free) — 10,000 calls/Mo, 2 req/s
- **Starter** ($3/Mo) — 130,000 calls/Mo, 8 req/s
- **Pro** ($17/Mo) — 700,000 calls/Mo, 25 req/s
- **Mega** ($65/Mo) — 3,500,000 calls/Mo, 50 req/s

## Endpoints

### Postcodes

#### `GET /v1/autocomplete` — Autocomplete a partial postcode

**Parameters:**
- `postcode` (query, required, string) — A partial postcode, e.g. SW1A Example: `SW1A`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/autocomplete?postcode=SW1A"
```

**Response:**
```json
{
    "data": {
        "count": 10,
        "query": "SW1A",
        "completions": [
            "SW1A 0AA",
            "SW1A 0PW",
            "SW1A 0RS",
            "SW1A 1AA",
            "SW1A 1AB",
            "SW1A 1AG",
            "SW1A 1AH",
            "SW1A 1BA",
            "SW1A 1BB",
            "SW1A 1BD"
        ]
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.201Z",
        "request_id": "dc2e07a1-1ded-4ac0-95ec-6e75e39b91c8"
    },
    "status": "ok",
    "message": "Autocomplete completed successfully",
    "success": true
}
```

#### `GET /v1/lookup` — Full details for a postcode

**Parameters:**
- `postcode` (query, required, string) — A UK postcode, e.g. SW1A 1AA Example: `SW1A1AA`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/lookup?postcode=SW1A1AA"
```

**Response:**
```json
{
    "data": {
        "postcode": {
            "ccg": "NHS North West London",
            "lsoa": "Westminster 018C",
            "msoa": "Westminster 018",
            "nuts": "Westminster",
            "incode": "1AA",
            "parish": "Westminster, unparished area",
            "region": "London",
            "country": "England",
            "outcode": "SW1A",
            "quality": 1,
            "eastings": 529090,
            "latitude": 51.50101,
            "postcode": "SW1A 1AA",
            "longitude": -0.141563,
            "northings": 179645,
            "admin_ward": "St James's",
            "admin_county": null,
            "admin_district": "Westminster",
            "primary_care_trust": "Westminster",
            "nhs_health_authority": "London",
            "european_electoral_region": "London",
            "parliamentary_constituency": "Cities of London and Westminster"
        }
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.312Z",
        "request_id": "f1a99214-d985-43f0-afe5-69128e33ab32"
    },
    "status": "ok",
    "message": "Postcode retrieved successfully",
    "success": true
}
```

#### `GET /v1/nearest` — Postcodes near a postcode

**Parameters:**
- `postcode` (query, required, string) — A UK postcode Example: `SW1A1AA`
- `limit` (query, optional, string) — Max results (default 10) Example: `10`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/nearest?postcode=SW1A1AA&limit=10"
```

**Response:**
```json
{
    "data": {
        "count": 1,
        "postcode": "SW1A1AA",
        "postcodes": [
            {
                "ccg": "NHS North West London",
                "lsoa": "Westminster 018C",
                "msoa": "Westminster 018",
                "nuts": "Westminster",
                "incode": "1AA",
                "parish": "Westminster, unparished area",
                "region": "London",
                "country": "England",
                "outcode": "SW1A",
                "quality": 1,
                "eastings": 529090,
                "latitude": 51.50101,
                "postcode": "SW1A 1AA",
                "longitude": -0.141563,
                "northings": 179645,
                "admin_ward": "St James's",
                "distance_m": 0,
                "admin_county": null,
                "admin_district": "Westminster",
                "primary_care_trust": "Westminster",
                "nhs_health_authority": "London",
                "european_electoral_region": "London",
                "parliamentary_constituency": "Cities of London and Westminster"
            }
        ]
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.416Z",
        "request_id": "a48aa394-5f92-474d-8cee-fd285138bdec"
    },
    "status": "ok",
    "message": "Nearest postcodes retrieved successfully",
    "success": true
}
```

#### `GET /v1/outcode` — Outcode (area) detail

**Parameters:**
- `outcode` (query, required, string) — An outcode (first half), e.g. SW1A Example: `SW1A`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/outcode?outcode=SW1A"
```

**Response:**
```json
{
    "data": {
        "outcode": {
            "parish": [
                "Wandsworth, unparished area",
                "Westminster, unparished area"
            ],
            "country": [
                "England"
            ],
            "outcode": "SW1A",
            "latitude": 51.50454046527776,
            "longitude": -0.13218813888888892,
            "admin_ward": [
                "Nine Elms",
                "St James's"
            ],
            "admin_county": [],
            "admin_district": [
                "Wandsworth",
                "Westminster"
            ]
        }
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.511Z",
        "request_id": "926480c9-2861-4e22-805b-4813ddb88e41"
    },
    "status": "ok",
    "message": "Outcode retrieved successfully",
    "success": true
}
```

#### `GET /v1/random` — A random postcode

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/random"
```

**Response:**
```json
{
    "data": {
        "postcode": {
            "ccg": "NHS Devon",
            "lsoa": "Plymouth 027E",
            "msoa": "Plymouth 027",
            "nuts": "Plymouth",
            "incode": "1EP",
            "parish": "Plymouth, unparished area",
            "region": "South West",
            "country": "England",
            "outcode": "PL1",
            "quality": 1,
            "eastings": 247578,
            "latitude": 50.370653,
            "postcode": "PL1 1EP",
            "longitude": -4.144743,
            "northings": 54507,
            "admin_ward": "St Peter and the Waterfront",
            "admin_county": null,
            "admin_district": "Plymouth",
            "primary_care_trust": "Plymouth Teaching",
            "nhs_health_authority": "South West",
            "european_electoral_region": "South West",
            "parliamentary_constituency": "Plymouth Sutton and Devonport"
        }
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.616Z",
        "request_id": "10f4dd4f-1472-4fab-be3a-0131cad9d533"
    },
    "status": "ok",
    "message": "Random postcode retrieved successfully",
    "success": true
}
```

#### `GET /v1/reverse` — Nearest postcodes to coordinates

**Parameters:**
- `lat` (query, required, string) — Latitude Example: `51.501`
- `lon` (query, required, string) — Longitude Example: `-0.1416`
- `limit` (query, optional, string) — Max results (default 10) Example: `10`
- `radius` (query, optional, string) — Search radius in metres (max 2000)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/reverse?lat=51.501&lon=-0.1416&limit=10"
```

**Response:**
```json
{
    "data": {
        "count": 1,
        "latitude": 51.501,
        "longitude": -0.1416,
        "postcodes": [
            {
                "ccg": "NHS North West London",
                "lsoa": "Westminster 018C",
                "msoa": "Westminster 018",
                "nuts": "Westminster",
                "incode": "1AA",
                "parish": "Westminster, unparished area",
                "region": "London",
                "country": "England",
                "outcode": "SW1A",
                "quality": 1,
                "eastings": 529090,
                "latitude": 51.50101,
                "postcode": "SW1A 1AA",
                "longitude": -0.141563,
                "northings": 179645,
                "admin_ward": "St James's",
                "distance_m": 2.7920763597315994,
                "admin_county": null,
                "admin_district": "Westminster",
                "primary_care_trust": "Westminster",
                "nhs_health_authority": "London",
                "european_electoral_region": "London",
                "parliamentary_constituency": "Cities of London and Westminster"
            }
        ]
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.734Z",
        "request_id": "ea20a0aa-70e3-48d9-b68a-36d3d154c9e2"
    },
    "status": "ok",
    "message": "Reverse geocode completed successfully",
    "success": true
}
```

#### `GET /v1/validate` — Validate a postcode

**Parameters:**
- `postcode` (query, required, string) — A UK postcode Example: `SW1A1AA`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/validate?postcode=SW1A1AA"
```

**Response:**
```json
{
    "data": {
        "valid": true,
        "postcode": "SW1A1AA"
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.827Z",
        "request_id": "d4755a58-64c2-4b5f-9969-90117b93d36d"
    },
    "status": "ok",
    "message": "Validation completed successfully",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Service description & endpoints

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/postcode-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "service": "postcode-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/lookup": "Full details for a postcode (postcode=).",
            "GET /v1/random": "A random postcode.",
            "GET /v1/nearest": "Postcodes near a postcode (postcode=, limit=).",
            "GET /v1/outcode": "Outcode (area) detail (outcode=, e.g. SW1A).",
            "GET /v1/reverse": "Nearest postcodes to coordinates (lat=, lon=, radius=, limit=).",
            "GET /v1/validate": "Validate a postcode (postcode=).",
            "GET /v1/autocomplete": "Autocomplete a partial postcode (postcode=)."
        },
        "description": "UK postcode & geography lookup via postcodes.io: resolve a postcode to coordinates and administrative areas (district, ward, county, parliamentary constituency, region, NHS area), validate a postcode, reverse-geocode coordinates to the nearest postcodes, find nearby postcodes, autocomplete a partial postcode, look up an outcode and fetch a random postcode. Real data, no key."
    },
    "meta": {
        "timestamp": "2026-06-08T01:19:43.901Z",
        "request_id": "3b00c7fa-0846-4a11-9afe-28169f940d4a"
    },
    "status": "ok",
    "message": "Meta",
    "success": true
}
```


---
Marketplace page: https://www.oanor.com/api/postcode-api
OpenAPI spec: https://www.oanor.com/api/postcode-api/openapi.json
