October 2026: BFPO, postcode typos, larger postcodes and Loqate compatibility

Stable

BFPO addresses by BFPO number, automatic correction of mistyped postcodes, paging for large postcodes, Loqate-compatible responses that closely match Loqate's, and richer native API responses.

Summary

  • BFPO addresses (British Forces Post Office) can be looked up by BFPO number — BFPO 16 or BFPO16 — on every endpoint.
  • Mistyped postcodes are corrected when the search would otherwise find nothing: BF1 OAB (letter O) finds BF1 0AB.
  • Large postcodes page at 100 addresses, with a total and a way to fetch the next page.
  • Loqate-compatible responses now return Loqate's fields and formatting, with a few documented differences — useful if you're moving from Loqate.
  • The native API gains structured address fields, an id on every address suggestion, and a postal label and barcode.
  • Fixed: a malformed postcode no longer uses a credit. This was rare, and every credit affected has been returned — see Fixed.

Billing is unchanged: autocomplete and suggestions are free, and each completed lookup — a postcode lookup of up to 100 addresses, or one address retrieved by its id — uses one credit.

Upcoming — getAddress.io-compatible endpoints: from 14 October 2026, towns, organisation names and a few other values on /find, /get and /autocomplete will match getAddress.io's own formatting. See getAddress.io-compatible format change.

Changes that may affect your integration

Most integrations need no changes. Check these if you parse responses closely.

getAddress.io-compatible endpoints (/find, /get, /autocomplete)

WhatBeforeAfter
/find responseaddresses onlyadds page, limit (100), total and next_page; request more with ?page=2

Every standard postcode has 100 addresses or fewer, so /find still returns a full postcode on the first page. Value-format changes for these endpoints follow on 14 October 2026 — see the upcoming notice above.

Loqate-compatible endpoints (Find and Retrieve)

WhatBeforeAfter
Retrieve Line1–Line5 for an organisationorganisation on Line1premises only — the organisation is in Company and leads Label, as Loqate does
Retrieve Company, and the organisation in LabelPrime Minister & First Lord Of The TreasuryPrime Minister & First Lord of the Treasury, as Loqate does
Retrieve CityLONDONLondon
Retrieve LanguageEnglishENG
Retrieve Label, Barcode, Type, DataLevel, Districtemptypopulated as Loqate populates them
Retrieve Field1–Field20not returnedreturned (empty), as Loqate does
Retrieve BuildingNumber when there is none" """
Find address DescriptionLONDON, SW1A 2AALondon SW1A 2AA
House and flat letters in Text, BuildingName, Line1…2a, 1f2A, 1F, as Loqate does
Drill-down into a postcode (Container)every address in one responseup to 100 addresses; if more remain, the last item has Type: "Container" — pass its Id as Container for the next page (free, like every Find)
Limit on a drill-downcapped the addressescaps all items, including that continuation item; Limit=1 on a postcode that needs paging returns 400

All endpoints

WhatBeforeAfter
A partial postcode as a drill-down (/v1/postcodes/M20, /find/M20, Container=M20)at most 1,000 matching addresses — /v1/postcodes paged them 100 at a time; /find and Loqate Container returned them in one response — with the rest silently left outevery matching address, 100 per page; a partial postcode too broad to return complete gets 422 (see below)
A partial postcode too broad to return complete (one matching more than 10,000 addresses, such as a whole district)—422 with error: "postcode_too_broad" — never a silently truncated list. The size is only known once the search has run, so on the charged endpoints it uses a credit — we return it to your account within a few days, with no need to contact us. Retrying gives the same answer: use a longer postcode, such as a sector (M20 2) or a full postcode. Loqate Find stays free
country for BFPO (BF) postcodes — native API and getAddress.io-compatibleEngland"" (no home nation)
A malformed postcode on a postcode lookup (/v1/postcodes/{postcode}, /find/{postcode})rejected (400; 404 on /find), but a credit was used — a bug, see Fixedrejected without using a credit; the status codes are unchanged

New

BFPO addresses

Look up a BFPO address by its number on any endpoint — /v1/postcodes/BFPO16, /find/BFPO16, or Loqate Find with Container=BFPO16 — and get exactly that address with its real BF1/BF2 postcode (BFPO 16 never returns BFPO 160). Type-ahead accepts BFPO 16 and BFPO16 alike.

Our Loqate-compatible Retrieve keeps the BFPO number in Street and Line1 (Loqate itself leaves them empty), so a form filled from Line1 keeps it.

Postcode typo correction

A letter typed where a postcode needs a digit is corrected: BF1 OAB → BF1 0AB, SWIA OAA → SW1A 0AA. Your search always runs exactly as typed first; the correction is only tried when that finds nothing, so anything that returned results before returns the same results now (a name like "Old Inn" is never turned into a postcode). A valid postcode, including GIR 0AA, is never changed. Postcode lookups return the corrected postcode in postcode.

Native API (/v1)

All additions — no existing field changes.

  • /v1/autocomplete suggestions now have type (postcode or address) and udprn. An address suggestion goes straight to /v1/addresses/{udprn} — two calls from typing to a full address.
  • Structured address fields on every address: organisation, department, sub_building, building_name, building_number, street, dependent_street, locality, double_locality, po_box.
  • label (a ready-to-print postal label), barcode (Royal Mail customer barcode data) and type (residential or commercial).
  • parent_udprn — null for standard addresses; reserved for flat-level data.
  • /v1/postcodes/{postcode} now returns total and next_page alongside page and limit.

Fixed

A malformed postcode used a credit. Since 4 September 2026, a postcode lookup (/v1/postcodes/{postcode} or /find/{postcode}) given something that can't be a postcode — NOT-A-POSTCODE, say — was correctly rejected, but still used a credit. Our pricing says requests rejected before the search runs are free; now they are. The format is checked before any credit is taken.

This was rare: it affected very few requests, from a small number of accounts. Every credit affected has been returned — it shows as a "Credit adjustment" on your dashboard — and there's nothing you need to do.

Mistyped postcodes that can be corrected (SWIA OAA) and BFPO numbers are still searched, and charged as lookups.

Unchanged

  • Billing: suggestions free; one credit per postcode lookup (per page of up to 100) or address retrieval. A lookup that finds nothing still counts — including a page beyond the last page, which returns no addresses; follow next_page rather than counting pages.
  • Native API field values: line_1–line_3 still follow Royal Mail's printing rules (organisation first), and town stays in capitals.
  • Authentication and rate limits. Existing error responses are unchanged; the only new ones are the 400 for a too-small Limit and the 422 for a partial postcode too broad to return complete, both above. A 503 still means a temporary problem, safe to retry. One ordering detail: on /v1/postcodes and /find, a malformed postcode is now rejected before the key is checked, so a request with both a bad key and a malformed postcode gets the postcode error (400, or 404 on /find) rather than 401 — as invalid parameters already did.

See the API reference, Migrating from Loqate and Migrating from getAddress.io.