The AutoPostcode address API exposes two endpoints for looking up real UK addresses. Both take a single API key in the x-api-key header, both return JSON, both are CORS-enabled, and both draw from the same shared credit balance.
Which endpoint do I need?
| Use case | Endpoint | Input |
|---|---|---|
| User already typed a postcode and clicks Find address | /api/public/lookup | Full postcode |
| Single search box that resolves as they type (Fetchify / Loqate style) | /api/public/autocomplete | Any partial text (street, town, postcode, house number) |
Authentication
Every request must include your API key. Keys start with ap_live_ and are minted per website from your dashboard (Websites → Copy full key). The endpoint accepts any of these forms — use whichever fits your stack:
x-api-key: ap_live_…(recommended)Authorization: Bearer ap_live_…api-key: ap_live_…?api_key=ap_live_…query string (server-to-server proxies only — never expose in browser code)
AI-agent tip: if you're building a proxy on another platform, store the key as a server secret (e.g. AUTOPOSTCODE_API_KEY) and forward it as the x-api-key header — do not ship the key to the browser. A 401 response includes a hint field naming exactly which header we read; use it to debug misconfigured proxies.
1. Postcode Lookup
Send a full UK postcode; get back every deliverable address on that postcode as a JSON array. Ideal for the classic "enter postcode → pick address from dropdown" checkout pattern.
Endpoint
Request
curl "https://autopostcode.com/api/public/lookup?postcode=SW1A%201AA" \
-H "x-api-key: ap_live_xxxxxxxxxxxxxxxx"// Postcode Lookup — return every address on a full UK postcode.
const API_KEY = "ap_live_xxxxxxxxxxxxxxxx";
async function lookupPostcode(postcode) {
const res = await fetch(
"https://autopostcode.com/api/public/lookup?postcode=" +
encodeURIComponent(postcode),
{ headers: { "x-api-key": API_KEY } }
);
if (!res.ok) throw new Error("Lookup failed: " + res.status);
return res.json(); // Array of address objects
}
lookupPostcode("SW1A 1AA").then(console.log);Response
[
{
"postcode": "SW1A 1AA",
"line1": "Buckingham Palace",
"line2": "",
"line3": "",
"town": "London",
"county": "Greater London",
"country": "United Kingdom"
}
]2. Address Autocomplete
Send a free-text query — the endpoint matches against street, town, postcode and building number and returns ranked address suggestions. Debounce input by ~300 ms and only fire once q is at least 3 characters.
Endpoint
Request
curl "https://autopostcode.com/api/public/autocomplete?q=10%20downing" \
-H "x-api-key: ap_live_xxxxxxxxxxxxxxxx"// Address Autocomplete — Fetchify-style search-as-you-type.
const API_KEY = "ap_live_xxxxxxxxxxxxxxxx";
async function searchAddresses(query) {
if (!query || query.trim().length < 3) return { count: 0, suggestions: [] };
const res = await fetch(
"https://autopostcode.com/api/public/autocomplete?q=" +
encodeURIComponent(query),
{ headers: { "x-api-key": API_KEY } }
);
if (!res.ok) throw new Error("Search failed: " + res.status);
return res.json();
}
searchAddresses("86 marland fold").then(console.log);Response
{
"query": "10 downing",
"count": 1,
"suggestions": [
{
"suggestion": "10 Downing Street, London, Greater London, SW1A 2AA",
"postcode": "SW1A 2AA",
"line1": "10 Downing Street",
"line2": "",
"line3": "",
"town": "London",
"county": "Greater London",
"country": "United Kingdom"
}
],
"credits_remaining": 1584
}Complete working example — vanilla JS widget
A drop-in autocomplete box: debounced input, in-flight request cancellation, dropdown list, graceful empty / error states, and address-field population on select.
// Drop-in vanilla-JS address autocomplete.
// Renders a search box, debounces input, calls the API, shows a
// dropdown, and populates address fields on select.
//
// Expected HTML:
// <input id="apc-search" placeholder="Start typing your address" />
// <ul id="apc-suggestions"></ul>
// <input id="line1" /> <input id="line2" /> <input id="town" />
// <input id="county" /> <input id="postcode" />
const API_KEY = "ap_live_xxxxxxxxxxxxxxxx";
const ENDPOINT = "https://autopostcode.com/api/public/autocomplete";
const input = document.getElementById("apc-search");
const list = document.getElementById("apc-suggestions");
let timer, controller;
input.addEventListener("input", () => {
clearTimeout(timer);
timer = setTimeout(() => runSearch(input.value.trim()), 300);
});
async function runSearch(q) {
list.innerHTML = "";
if (q.length < 3) return;
if (controller) controller.abort();
controller = new AbortController();
try {
const res = await fetch(
ENDPOINT + "?q=" + encodeURIComponent(q),
{ headers: { "x-api-key": API_KEY }, signal: controller.signal }
);
const data = await res.json();
if (!data.suggestions?.length) {
list.innerHTML = "<li>No addresses found.</li>";
return;
}
for (const s of data.suggestions) {
const li = document.createElement("li");
li.textContent = s.suggestion;
li.onclick = () => fill(s);
list.appendChild(li);
}
} catch (err) {
if (err.name !== "AbortError") {
list.innerHTML = "<li>Unable to search addresses.</li>";
}
}
}
function fill(addr) {
document.getElementById("line1").value = addr.line1 || "";
document.getElementById("line2").value = addr.line2 || "";
document.getElementById("town").value = addr.town || "";
document.getElementById("county").value = addr.county || "";
document.getElementById("postcode").value = addr.postcode || "";
input.value = addr.suggestion;
list.innerHTML = "";
}Complete working example — React hook
The same behaviour as a reusable hook. Feed it a controlled input value; render suggestions however you like.
// React hook — address autocomplete with debounce + abort.
import { useEffect, useRef, useState } from "react";
const API_KEY = import.meta.env.VITE_AUTOPOSTCODE_KEY!;
const ENDPOINT = "https://autopostcode.com/api/public/autocomplete";
export function useAddressSearch(query: string) {
const [suggestions, setSuggestions] = useState<any[]>([]);
const [status, setStatus] = useState<"idle"|"loading"|"empty"|"error">("idle");
const ctrl = useRef<AbortController | null>(null);
useEffect(() => {
if (query.trim().length < 3) { setSuggestions([]); setStatus("idle"); return; }
const t = setTimeout(async () => {
ctrl.current?.abort();
ctrl.current = new AbortController();
setStatus("loading");
try {
const res = await fetch(
ENDPOINT + "?q=" + encodeURIComponent(query),
{ headers: { "x-api-key": API_KEY }, signal: ctrl.current.signal }
);
const data = await res.json();
setSuggestions(data.suggestions ?? []);
setStatus(data.suggestions?.length ? "idle" : "empty");
} catch (e: any) {
if (e.name !== "AbortError") setStatus("error");
}
}, 300);
return () => clearTimeout(t);
}, [query]);
return { suggestions, status };
}Response fields
- postcode — canonical UK postcode (e.g. SW1A 1AA)
- line1 — building name/number + thoroughfare
- line2 — dependent locality (often empty)
- line3 — double-dependent locality (rare)
- town — post town
- county — administrative county
- country — United Kingdom
- Autocomplete only: suggestion — a single pre-formatted display string
Errors & status codes
| Status | Meaning | What to do |
|---|---|---|
| 200 | Success | Render suggestions / addresses. |
| 401 | Missing or invalid API key | Check the x-api-key header. |
| 402 | Insufficient credits | Top up in dashboard. |
| 429 | Rate limited | Debounce input, back off and retry. |
Setup recipe for AI agents
Building with an AI code assistant? Point it at this page — or paste the recipe below straight into the prompt. It contains everything needed to wire up a working address search box in one pass.
# AutoPostcode — one-shot setup recipe (for AI agents)
#
# Goal: add a live UK address search box to a checkout / signup form.
# Data returned: PAF-verified UK addresses (line1, line2, town, county, postcode).
#
# 1. Get a key at https://autopostcode.com (starts with ap_live_)
# 2. Store as VITE_AUTOPOSTCODE_KEY (or proxy through your backend).
# 3. Call the autocomplete endpoint on every debounced keystroke:
#
# GET https://autopostcode.com/api/public/autocomplete?q=<user_text>
# Header: x-api-key: ap_live_...
#
# 4. Render response.suggestions[] as a dropdown.
# 5. On click, populate line1 / line2 / town / county / postcode fields.
#
# For a postcode-first flow (button-triggered) use instead:
# GET https://autopostcode.com/api/public/lookup?postcode=<postcode>
# Header: x-api-key: ap_live_...
#
# Both endpoints:
# - Cost 1 credit per successful call (no-result calls are free).
# - Support GET (query string) and CORS from any origin.
# - Return JSON with the same address field names.Ready to build?
Grab a key from the free trial and paste one of the snippets above — most teams are returning live addresses within minutes.
Frequently asked questions
What is the difference between Postcode Lookup and Address Autocomplete?
Postcode Lookup takes a complete UK postcode (e.g. SW1A 1AA) and returns every address on it — perfect for a 'Find my address' button on a checkout. Address Autocomplete takes any partial free-text query (street name, town, postcode, building number, or a mix) and returns matching addresses as the user types — perfect for a Fetchify/Loqate-style live search-as-you-type box.
Which endpoint should I use?
Use Postcode Lookup if your form already has a postcode field and a button. Use Address Autocomplete if you want a single search box that resolves as the user types. Both use the same API key and the same shared credit balance.
How do I authenticate?
Send your API key in the x-api-key request header. Keys start with ap_live_ and are minted per website from your dashboard. Requests without a valid key return 401.
What is the base URL?
https://autopostcode.com/api/public/ — both endpoints are simple GETs on this base. CORS is open so you can call directly from the browser.
How much does each call cost?
One credit per successful lookup and one credit per autocomplete request that returns suggestions. Failed calls (no match, invalid postcode) are not billed. Every response includes credits_remaining.
What data source powers the API?
Every result is matched against the AutoPostcode UK address database — around 31 million deliverable addresses across roughly 1.8 million postcodes, refreshed continuously.
Ready to get started?
Add Royal Mail PAF-verified UK address lookup to your site in minutes — start free, no card required.
