Postcodes for Laravel: GB Postcode Lookup Package | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Postcodes for Laravel: GB Postcode Lookup and Geography Data

   [Laravel](https://www.msaied.com/public/articles?category=laravel) [Composer Pacakge](https://www.msaied.com/public/articles?category=composer-pacakge) 

 Postcodes for Laravel: GB Postcode Lookup and Geography Data
=============================================================

 Postcodes for Laravel is a typed client for the GB Postcodes API. It covers postcode lookup, geography data, proximity search, a Laravel validation rule, and test fakes — all in one Composer package.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 1 Oct 2026 · Updated 2 Oct 2026 · 3 min read

ShareCopy linkCopied

 ![Postcodes for Laravel: GB Postcode Lookup and Geography Data](https://cdn.msaied.com/730/d8f9ca2085c0f6cc42cc82368bce275a.png) 

  On this page +1. [What Is Postcodes for Laravel?](#what-is-postcodes-for-laravel)
2. [Installation](#installation)
3. [Looking Up a Postcode](#looking-up-a-postcode)
4. [Validating a Postcode in a Form](#validating-a-postcode-in-a-form)
5. [Proximity and Boundary Searches](#proximity-and-boundary-searches)
6. [Testing with Fakes](#testing-with-fakes)
7. [Key Takeaways](#key-takeaways)

 What Is Postcodes for Laravel?
------------------------------

[Postcodes for Laravel](https://github.com/Josh-Dovey/postcodes-laravel) is Joshua Dovey's Composer package that wraps the GB Postcodes API. Unlike earlier Postcodes.io wrappers, this client returns **typed objects** rather than plain arrays and bundles boundary geometry, census figures, and estimated population data alongside the standard coordinate and administrative fields.

The package requires **PHP 8.2+** and **Laravel 12 or 13**.

Installation
------------

```bash
composer require joshdovey/postcodes

```

Add your API key to `.env`:

```env
POSTCODES_API_KEY=your-key

```

Successful responses are cached for one day by default. The client retries on timeouts, connection failures, burst rate limits, and server errors (twice by default), but will not retry an exhausted plan quota.

Looking Up a Postcode
---------------------

The `Postcodes` facade returns a `Postcode` object. `get()` returns `null` when a postcode cannot be resolved; `getOrFail()` throws a `NotFoundException`.

```php
use JoshDovey\Postcodes\Facades\Postcodes;

$postcode = Postcodes::get('M16 0RA');

$postcode?->latitude();
$postcode?->longitude();
$postcode?->geography->localAuthorityName;
$postcode?->geography->wardName;

```

The `geography` object includes parliamentary constituencies, NHS integrated care boards, police force areas, and more. `autocomplete()` returns a Laravel collection of matches for a partial postcode string, and `search()` resolves up to 100 postcodes in a single batched API request.

Validating a Postcode in a Form
-------------------------------

`ValidPostcode::unit()` checks whether a full postcode actually exists in the dataset, not just whether its format is correct.

```php
use JoshDovey\Postcodes\Rules\ValidPostcode;

$request->validate([
    'postcode' => ['required', ValidPostcode::unit()],
]);

```

Values with an invalid shape fail locally without hitting the API. By default, a format-valid postcode passes if the API call throws an error. To reject it in that scenario, call `(new ValidPostcode)->strict()` or set `postcodes.validation.strict` to `true` in the published config.

Proximity and Boundary Searches
-------------------------------

`radius()` finds postcodes within a given distance of a starting postcode. Distance defaults to kilometres; miles are available per call or globally via the client config.

```php
$nearby = Postcodes::radius('M16 0RA', radius: 2, limit: 100);

foreach ($nearby as $result) {
    echo $result->postcode . ' ' . $result->distance;
}

```

`within()` accepts a GeoJSON polygon, multipolygon, or feature for catchment-style queries. Additional methods cover distance between two postcodes, distance matrices, and reverse geocoding. Boundary geometry is included in responses by default; call `withoutBoundaries()` or pass a `fields` selection to trim the payload when you only need coordinates or names.

Testing with Fakes
------------------

`Postcodes::fake()` replaces the HTTP client with stubbed responses and records every request, making assertions straightforward.

```php
use JoshDovey\Postcodes\Testing\Fixtures;

$fake = Postcodes::fake([
    'v1/postcodes/validate*' => Fixtures::validation('M16 0RA'),
]);

$result = Postcodes::validate('M16 0RA');

$fake->assertSent('v1/postcodes/validate*');

```

Key Takeaways
-------------

- Returns typed `Postcode` objects with geography, boundary, and population data.
- `ValidPostcode::unit()` validates existence against the live dataset, not just format.
- `radius()` and `within()` handle delivery-area and catchment queries out of the box.
- Responses are cached for one day; the client retries transient failures automatically.
- `Postcodes::fake()` provides first-class test support with fixture stubs and request assertions.
- Requires PHP 8.2+ and Laravel 12 or 13.

---

*Source: [Laravel News — Postcodes for Laravel](https://laravel-news.com/postcodes-for-laravel)*

- [Laravel](https://www.msaied.com/public/articles?search=Laravel)
- [PHP](https://www.msaied.com/public/articles?search=PHP)
- [Composer Package](https://www.msaied.com/public/articles?search=Composer%20Package)
- [Postcode](https://www.msaied.com/public/articles?search=Postcode)
- [GB Postcodes](https://www.msaied.com/public/articles?search=GB%20Postcodes)
- [Geolocation](https://www.msaied.com/public/articles?search=Geolocation)

 Frequently asked questions 
---------------------------

  What is the difference between Postcodes for Laravel and the older Laravel Postcodes.io wrapper?Postcodes for Laravel connects to the GB Postcodes API (a different service from Postcodes.io) and returns typed objects instead of plain arrays. It also includes boundary geometry, census data, and estimated population figures that the Postcodes.io wrapper does not provide.

   How does the ValidPostcode rule differ from a simple regex format check?ValidPostcode::unit() makes a live API call to confirm the postcode actually exists in the dataset, not just that it matches the expected format. Values with an invalid shape are rejected locally without an API request. You can enable strict mode to also reject format-valid postcodes when the API call fails.

   How can I test code that uses the Postcodes facade without making real API calls?Call Postcodes::fake() with a map of URL patterns to fixture responses. The fake client records every request so you can assert which endpoints were called using $fake-&gt;assertSent().

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleLaravel 14 Adds a defaults() Method to Eloquent Models](https://www.msaied.com/public/articles/laravel-14-adds-a-defaults-method-to-eloquent-models) [Next articleLaravel AI SDK: Tool-Calling Agents and Conversation Persistence](https://www.msaied.com/public/articles/laravel-ai-sdk-tool-calling-agents-and-conversation-persistence-4)  

   On this page
-------------

1. [What Is Postcodes for Laravel?](#what-is-postcodes-for-laravel)
2. [Installation](#installation)
3. [Looking Up a Postcode](#looking-up-a-postcode)
4. [Validating a Postcode in a Form](#validating-a-postcode-in-a-form)
5. [Proximity and Boundary Searches](#proximity-and-boundary-searches)
6. [Testing with Fakes](#testing-with-fakes)
7. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
