PHPackages                             academe/idealpostcodes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. academe/idealpostcodes

ActiveLibrary[API Development](/categories/api)

academe/idealpostcodes
======================

Access the Ideal Postcodes API

0.9.1(10y ago)35.4k[1 issues](https://github.com/academe/idealpostcodes/issues)MITPHPPHP &gt;=5.4.0

Since Jul 1Pushed 10y ago1 watchersCompare

[ Source](https://github.com/academe/idealpostcodes)[ Packagist](https://packagist.org/packages/academe/idealpostcodes)[ Docs](https://github.com/academe/idealpostcodes)[ RSS](/packages/academe-idealpostcodes/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

IdealPostcodes
==============

[](#idealpostcodes)

[![Latest Stable Version](https://camo.githubusercontent.com/2c02548fac645d7d4a6ad801c2f9a50116ace7d0659ce263b1bce3d6793aa01f/68747470733a2f2f706f7365722e707567782e6f72672f61636164656d652f696465616c706f7374636f6465732f76657273696f6e2e706e67)](https://packagist.org/packages/academe/idealpostcodes)[![Total Downloads](https://camo.githubusercontent.com/b838c32241b2dd8af4ba73ad34631cdadcb945b51d2e022c1d773403581a05e5/68747470733a2f2f706f7365722e707567782e6f72672f61636164656d652f696465616c706f7374636f6465732f642f746f74616c2e706e67)](https://packagist.org/packages/academe/idealpostcodes)

Library to access the [Ideal Postcodes](https://ideal-postcodes.co.uk/) API. The main documentation for the API is here:

Still much work-in-progress, but a working library. This package is not associated officially with *Ideal Postcodes*.

General Approach
----------------

[](#general-approach)

This is the general approach I have taken in developing this library. It was all initially written in one day to meet a need for a specific project, so may be a bit rushed, but I have tried to keep it as generic as possible. It does need extending out with more interfaces though, and perhaps make the most of a DI locator so classes can be extended as needed.

Communication with the remote API happens in the `Transport` object. Instantiate that with your API key and pass that into the other classes. This class uses curl to communicate, but you may want to create a guzzle version or use a different http client - just write an adapter and you should be good.

Each value class searves two purposes:

- To hold the value of a single, retrieved record from the API.
- To make requests on the API.

So if you want to find, for example, addresses for a postcode, instantiate the Postcode object then use its `getAddresses($postcode)` method to fetch a collection of Address objects for a postcode. The Postcode object will hold the summary of the interaction with the API (the result, any messages etc) while the `getAddresses()`method will return a collection.

The collections are provided by the `phpcollection/phpcollection` composer package. This is a new and largely untested package, but seemed to meet the needs here nicely. I intend to make the collections more generic in the future, so you are not tied down to just one collections implementation.

Examples
--------

[](#examples)

Example use, to fetch a list of addresses matching a postcode:

```
use Academe\IdealPostcodes\Postcode;
use Academe\IdealPostcodes\Transport;

// 'iddqd' is the shared developer API key, limited to 15 requests per day for each IP address.
$transport = new Transport('iddqd');
$postcode = new Postcode($transport);

$addresses = $postcode->getAddresses('ID1 1QD');

foreach($addresses as $address) {
    echo $address->line_1 . "";
}

echo "Number of addresses = " . count($addresses);
```

Get up to 20 postcodes in a 300m radius around a latitude/longitude location:

```
use Academe\IdealPostcodes\GeoLocation;
use Academe\IdealPostcodes\Transport;

$transport = new Transport('iddqd');
$geo = new GeoLocation($transport);

$postcodes = $geo->getPostcodes(-0.20864436, 51.48994883, 20, 300);

foreach($postcodes as $postcode) {
    echo $postcode->postcode . "";
    echo $postcode->northings . "";
    echo $postcode->eastings . "";
}

echo "Number of postcodes = " . count($postcodes);
```

Search for addresses:

```
use Academe\IdealPostcodes\Address;
use Academe\IdealPostcodes\Transport;

$transport = new Transport('iddqd');
$addr = new Address($transport);

$addresses = $addr->search('10 Downing Street');

foreach($addresses as $address) {
    echo $postcode->town . "";
}
```

Get a single address by its ID (UDPRN):

```
use Academe\IdealPostcodes\Address;
use Academe\IdealPostcodes\Transport;

$transport = new Transport('iddqd');
$addr = new Address($transport);

$address = $addr->get(0);

var_dump($address->toArray());
```

TODO
----

[](#todo)

- Keys API. This includes CSV download, which could be streamed to help with memory usage.
- More and better documnentation.
- Tests.
- Consider an adapter for the collection, so other collections can be used.
- The collections are not JSON serialisable; it would help if they are; use $collection-&gt;all() and serialise that for now
- More helper methods to interpret the API codes that are received, to make it easier to identify http errors, failure to find a match, and so on.
- Maybe consider putting all the request methods into a single class and returning Postcodes, Addresses and colletions of either from there. That way the records can be true value objects. The methods are spread over multiple classes just for history reasons, and is probably not an optimal approach.
- Support for query tags, which are available across all API methods.

###  Health Score

26

—

LowBetter than 43% of packages

Maintenance13

Infrequent updates — may be unmaintained

Popularity23

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

3974d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/395934?v=4)[Jason Judge](/maintainers/judgej)[@judgej](https://github.com/judgej)

---

Top Contributors

[![judgej](https://avatars.githubusercontent.com/u/395934?v=4)](https://github.com/judgej "judgej (18 commits)")

---

Tags

apiweb servicepostcodes

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/academe-idealpostcodes/health.svg)

```
[![Health](https://phpackages.com/badges/academe-idealpostcodes/health.svg)](https://phpackages.com/packages/academe-idealpostcodes)
```

###  Alternatives

[pdfcrowd/pdfcrowd

A client library for the Pdfcrowd API. It lets you convert between HTML, PDF and various image formats

631.1M1](/packages/pdfcrowd-pdfcrowd)[apigee/apigee-client-php

Client library for connecting to the Apigee Edge API.

27558.7k3](/packages/apigee-apigee-client-php)[m165437/laravel-blueprint-docs

API Blueprint Renderer for Laravel

22779.0k](/packages/m165437-laravel-blueprint-docs)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
