postcodes.io: Self-Hosted UK Postcode and Geolocation API
UK postcode & geolocation API, serving up open data
At a glance
- What is it?
- postcodes.io is an Express and PostgreSQL/PostGIS service for UK postcode lookup, search, reverse geocoding and bulk requests. It is aimed at developers who can consume the public API or operate the service with Docker, but this repository does not include the upstream data pipeline.
- Who is it for?
- Developers needing a documented HTTP interface for UK postcode and location data should consider postcodes.io when a self-hosted Express and PostGIS deployment is acceptable. Teams expecting repository-managed data ingestion, address validation, international coverage or a documented rollback procedure should verify those needs first.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly HTML, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The postcode.io service and its intended users
postcodes.io solves a specific data-access problem: it places UK postcode and geolocation information behind an HTTP API. According to the README, the service exposes the ONS Postcode Directory, Ordnance Survey Open Names and Scottish Postcode Directory datasets. It is intended for developers who need postcode resolution, administrative and location data, autocomplete, nearest-postcode queries or reverse geocoding without downloading and joining those source datasets themselves.
The documented capabilities include full postcode lookup, outward-code lookup, postcode search and autocomplete, reverse geocoding, nearest-postcode search, terminated-postcode search, and bulk postcode lookup or reverse geocoding. This makes the project relevant to address-oriented applications, mapping workflows, location search and data normalization involving UK postcodes. The README does not describe street-level address validation, delivery checking, routing or postcode coverage outside the United Kingdom, so those should not be inferred from the service's broader location-related name.
There are two documented ways to use it: consume the Public API at `https://postcodes.io`, or run the service yourself. The self-hosted path requires Docker Compose and a separate PostgreSQL/PostGIS database image. That division is important for evaluators. The repository contains the HTTP service, not the process that builds the published database.
Express requests backed by a published PostGIS dump
The architecture has a clear boundary between the web tier and postcode data. The application is written in TypeScript and uses Express 5 for HTTP handling. Its dependencies also include `pg` for PostgreSQL access, the `postcode` package, CORS middleware, request logging through `morgan`, structured logging through `pino`, Prometheus metrics from `prom-client`, and Express Prometheus instrumentation. Based on `package.json`, a production build is produced under `dist`, with `dist/app.js` declared as the package entry point and `dist/server.js` used by the start script.
The data tier is PostgreSQL with PostGIS support. The README says the API runs against a pre-built PostgreSQL/PostGIS database published as a `pg_dump` by an upstream pipeline. That means a request is handled by the HTTP service and resolved against a prepared spatial database. It does not mean this repository fetches ONS or Ordnance Survey files on startup. The repository layout reinforces that boundary through separate Dockerfiles, a database image and a `latest` file used by the development seed target to locate the dump.
The `docker-compose.yml` defines two services. `api` uses `idealpostcodes/postcodes.io:latest`, depends on `db`, connects through the `db` hostname and exposes container port 8000 on host port 8000. `db` uses `idealpostcodes/postcodes.io.db:latest` and supplies the `postcodesiodb` database. This split also creates an operational consideration: deploying the application and accepting a new postcode dataset are separate concerns.
Starting postcodes.io locally with Docker Compose
The quickest documented setup is Docker Compose. From a checkout of this repository, run the command below. The README presents it as the Quick Start for querying UK postcode data on a local machine.
docker-compose upThe Compose file starts the API and database, maps host port 8000 to API port 8000, and connects the service through the database variables shown in the configuration. The `api` service has `restart: unless-stopped`, while the database service has the same restart policy. Because the API container includes a health check that invokes `healthcheck.js`, a started container is not by itself proof that every postcode query is available. Check the container output and the documented API behavior before sending application traffic.
The repository also documents a public API and its API documentation at the following addresses:
https://postcodes.io
https://postcodes.io/docsNo new HTTP request example is given in the README for a first local lookup, so this article does not invent an endpoint or query string. The `openapi/` directory and linked API documentation are the appropriate places to select the first request for your use case. This omission is a documentation constraint worth accounting for when evaluating developer experience, especially for bulk and reverse-geocoding workflows.
Bulk, reverse and terminated postcode workflows
The feature list points to several distinct query classes rather than a simple key-value postcode directory. Search and autocomplete support interactive lookup interfaces. Outward-code lookup addresses UK postcode prefixes, while postcode lookup can resolve administrative and location records for a full postcode or outward code. Terminated postcode search addresses historical or discontinued postcode records, a distinction that matters when applications must preserve references to old addresses.
Reverse geocode postcodes allows latitude and longitude input to be connected with postcode data. Nearest postcode search supports proximity-oriented use cases, and bulk lookup can process multiple postcodes. The README also lists bulk reverse geocoding, indicating that collection processing is part of the intended service surface rather than an incidental endpoint.
However, the repository description does not specify bulk request limits, pagination rules, rate limits, supported coordinate systems, result schemas for every endpoint, or the behavior returned for invalid and partial postcodes. Those details should be checked in the linked API documentation and OpenAPI files. The public status page is also linked, which is relevant when evaluating an external API dependency. For self-hosting, operators need to decide how requests are bounded in their own infrastructure because no rate-policy details appear in the README.
Repository scope excludes the upstream database pipeline
The largest adoption constraint is not an HTTP endpoint. It is the separation between the service and its data supply. The README explicitly says the repository contains the HTTP service only, while the PostgreSQL/PostGIS database is published as a `pg_dump` from an upstream pipeline. A team that wants to modify source ingestion, transformation rules or database generation must locate or build another workflow.
The Makefile shows how the development database can be recreated from the dump URL stored in `./latest`. Its `seed` target drops and recreates `postcodesiodb`, enables PostGIS, downloads the referenced dump, removes restricted and unrestricted publication statements, loads the data into PostgreSQL, and then runs a `prewarm` target. This is useful for development data setup, but it is not evidence that production operators can reproduce the upstream transformation pipeline from this repository.
The maintenance target `prewarm` performs `VACUUM ANALYZE` and uses `pg_prewarm` for hot tables and indexes, with a comment that it is safe to rerun. These operational scripts reflect PostgreSQL administration rather than only application deployment. The README does not document a production backup schedule, data retention policy, migration rollback or zero-downtime database replacement process. Those omissions matter more than the initial container startup when the service will hold a production spatial dataset.
Release activity, dependencies and the MIT license boundary
The repository is not archived, and its last push was on 2026-09-30. Releases listed for September 2026 include `20.1.0` on 2026-09-29, `20.0.3` on 2026-09-29, and `20.0.2` on 2026-09-14. This is recent project activity, although the available repository metadata is not enough to claim that every deployment path is bug-free or that the service has a long-term support policy.
The root `package.json` reports version `12.0.0`, while the recent release list contains version `20.1.0`. Based on the available files, that discrepancy should be checked against the intended branch and release artifact before automation pins a package version. The Docker Compose configuration uses the `latest` image tag, which is convenient for initial setup but does not give an operator an immutable deployment reference.
The project is licensed under the MIT License, and both the README and `package.json` identify that license. The source-code license does not by itself settle the permissions or attribution obligations attached to the ONS Postcode Directory, Ordnance Survey Open Names and Scottish Postcode Directory datasets. Organizations should review the terms of each included dataset separately, especially when redistributing database images or bulk extracts. No legal conclusion about those source datasets can be drawn from the MIT identifier alone.
Where the Docker service differs from direct data access
A real alternative is to obtain the underlying postcode datasets and load or query them directly in your own PostgreSQL/PostGIS environment. This bypasses the Express API, its endpoint semantics, client integration and service availability. It also places schema design, data refresh, PostGIS setup, indexing and query compatibility on the adopting team.
postcodes.io offers a narrower operational responsibility in one sense and a broader one in another. Consumers receive HTTP endpoints for postcode lookup, reverse geocoding, autocomplete and bulk operations, while the service operator still manages containers, PostgreSQL, backups and dataset replacement. Direct database access gives more control over joins and analytical queries, but it does not turn this repository into the missing upstream ETL pipeline.
The choice therefore depends on the interface required. Use postcodes.io when an HTTP API is the desired contract and its documented response fields match the application. Use direct PostGIS data access when raw schema control, custom analytical joins or independent query workloads matter more than endpoint convenience. For the public service, account for network availability and the separately published status page. For self-hosting, account for database image size, seed duration and the unspecified production refresh procedure.
Editorial conclusion
Developers needing a documented HTTP interface for UK postcode and location data should consider postcodes.io when a self-hosted Express and PostGIS deployment is acceptable. Teams expecting repository-managed data ingestion, address validation, international coverage or a documented rollback procedure should verify those needs first. For an initial adoption decision, inspect the public API documentation, confirm the required PostGIS database image is available, and compare the supplied endpoints with the exact postcode and geolocation workflows you need.
Frequently asked questions
How do I start a local postcodes.io service?
The README's Quick Start uses `docker-compose up`. The Compose configuration starts an API container and a PostgreSQL/PostGIS database container, with the API exposed on host port 8000.
Does the postcodes.io repository build the UK postcode database?
No. The README says the HTTP service runs against a pre-built PostgreSQL/PostGIS database published as a `pg_dump` by an upstream pipeline. This repository contains only the HTTP service.
Can postcodes.io do reverse geocoding and bulk postcode lookups?
The documented feature list includes reverse geocoding, nearest-postcode search, bulk postcode lookup and bulk reverse geocoding. The README does not state request limits or rate limits, so those must be checked in the API documentation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ideal-postcodes-postcodes-io)Was this useful?