PHPackages                             e164-com/e164-php-sdk - 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. e164-com/e164-php-sdk

ActiveLibrary[API Development](/categories/api)

e164-com/e164-php-sdk
=====================

A PHP SDK for interacting with the e164.com API.

4.0.0(2w ago)149MITPHPPHP ^8.1CI passing

Since Apr 17Pushed 2w ago1 watchersCompare

[ Source](https://github.com/e164-com/e164-php-sdk)[ Packagist](https://packagist.org/packages/e164-com/e164-php-sdk)[ Docs](https://github.com/e164-com/e164-php-sdk)[ RSS](/packages/e164-com-e164-php-sdk/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (4)Dependencies (12)Versions (6)Used By (0)

E164 PHP SDK
============

[](#e164-php-sdk)

[![Tests](https://github.com/e164-com/e164-php-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/e164-com/e164-php-sdk/actions/workflows/ci.yml)[![Latest Version](https://camo.githubusercontent.com/9c08e975f6542935488c9b2f54b2cbea8272bfac6b7f4968e026d337c740726a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f653136342d636f6d2f653136342d7068702d73646b2e737667)](https://packagist.org/packages/e164-com/e164-php-sdk)[![PHPStan](https://camo.githubusercontent.com/d18b9a987aa81e64470a11caecf72caa66597c9ebd6b307bd1c2cb7a752b0dff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c25323031302d627269676874677265656e2e737667)](https://phpstan.org/)[![PHP](https://camo.githubusercontent.com/7535257ca228724c93658bd52583d4e47a9bab02c356abf6e54c1d575f2151e6/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e312532422d626c75652e737667)](https://www.php.net/)[![License](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

The official PHP SDK for the [E164 API](https://e164.com) — phone number validation and network lookup.

Requirements
------------

[](#requirements)

- PHP 8.1+
- ext-json
- Any [PSR-18](https://www.php-fig.org/psr/psr-18/) HTTP client (Guzzle is installed by default)

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

[](#installation)

```
composer require e164-com/e164-php-sdk
```

Quick Start
-----------

[](#quick-start)

```
use E164\E164;

$e164 = new E164();
$result = $e164->lookup('441133910781');

echo $result->getType();            // "GEOGRAPHIC"
echo $result->getCallingCode();     // 44
echo $result->getIso3();            // "GBR"
echo $result->getOperatorBrand();   // "BT"
```

Authentication (Optional)
-------------------------

[](#authentication-optional)

The E164 API works without authentication, but if you have an API key you can pass it as the second argument:

```
$e164 = new E164(null, 'your-api-key');
```

The key is sent as an `X-API-Key` header on every request, including when you supply your own HTTP client.

Working with Results
--------------------

[](#working-with-results)

`lookup()` returns an immutable `E164\LookupResult`:

```
$result = $e164->lookup('441133910781');

// Number identification
$result->getPrefix();          // "44113391"
$result->getCallingCode();     // 44 (int)
$result->getIso3();            // "GBR"
$result->getType();            // "GEOGRAPHIC"
$result->getLocation();        // Location if available, else null

// Network details
$result->getTadig();           // TADIG code, e.g. "GBRJT" for a mobile number
$result->getMccmnc();          // e.g. "23450" for a mobile number
$result->getOperatorBrand();   // "BT"
$result->getOperatorCompany(); // "BT"

// Number length constraints (integers)
$result->getTotalLengthMin();  // 12
$result->getTotalLengthMax();  // 12

// Metadata
$result->getWeight();          // 11
$result->getSource();          // "e164"
```

Any field the API omits reads as `null`, so guard on the ones you depend on. Landline lookups typically have no `tadig` or `mccmnc`; mobile lookups do.

### Multiple matches

[](#multiple-matches)

A number can match more than one record. `lookup()` returns the best match; use `lookupAll()` when you want them all, ordered best match first:

```
foreach ($e164->lookupAll('12124567890') as $match) {
    echo $match->getPrefix() . ' ' . $match->getOperatorBrand() . PHP_EOL;
}
```

`lookupAll()` never returns an empty array — like `lookup()`, it throws `NumberNotFoundException` when the API holds no record for the number.

### Raw payload access

[](#raw-payload-access)

The decoded API record stays reachable, so fields added to the API after this SDK was released are never lost:

```
$result->toArray();              // the whole record as received
$result->get('total_length_min'); // 12 — the exact JSON value, uncoerced
$result->has('tadig');           // true even when the value is null
json_encode($result);            // re-encodes to the original payload
```

Input Format
------------

[](#input-format)

Everything that is not a digit is stripped, so all of these are equivalent:

```
$e164->lookup('441133910781');
$e164->lookup('+441133910781');
$e164->lookup('+44-113-391-0781');
$e164->lookup('+44 (113) 391 0781');
```

Input with no digits at all, or with more than the 15 digits E.164 permits, is rejected without an API call.

So is a number beginning with `0`. Country calling codes run from 1 to 999 and never start with one, so a number still carrying a national trunk prefix or an international access code is not in E.164 form — strip it before calling:

```
$e164->lookup('00441133910781');  // InvalidPhoneNumberException
$e164->lookup('+441133910781');   // correct
```

Custom HTTP Client
------------------

[](#custom-http-client)

Any PSR-18 client works. The SDK builds absolute URLs and sets its own headers, so an injected client needs no particular configuration — no `base_uri` required:

```
use GuzzleHttp\Client;
use E164\E164;

$e164 = new E164(new Client(['timeout' => 5]));
```

The default client applies a 10-second request timeout and a 5-second connect timeout. When you inject your own client, its timeouts are yours to set.

You can also supply a PSR-17 request factory and override the base URL:

```
$e164 = new E164(
    client: new Client(),
    apiKey: 'your-api-key',
    requestFactory: new GuzzleHttp\Psr7\HttpFactory(),
    baseUrl: 'https://staging.e164.com',
);
```

Error Handling
--------------

[](#error-handling)

```
use E164\Exception\ApiException;
use E164\Exception\AuthenticationException;
use E164\Exception\InvalidPhoneNumberException;
use E164\Exception\NumberNotFoundException;
use E164\Exception\RateLimitException;

try {
    $result = $e164->lookup('441133910781');
} catch (NumberNotFoundException $e) {
    // Well-formed number, but the API holds no record for it.
    // $e->getPhoneNumber() returns the normalised digits that were looked up.
} catch (InvalidPhoneNumberException $e) {
    // Not a usable number: no digits, over 15 digits, or starts with 0.
} catch (AuthenticationException $e) {
    // API key missing or rejected (HTTP 401/403).
} catch (RateLimitException $e) {
    sleep($e->getRetryAfter() ?? 60);
} catch (ApiException $e) {
    // Any other API or transport failure.
    $e->getStatusCode(); // HTTP status, or null if the request never got a response
}
```

Order matters: `NumberNotFoundException` extends `InvalidPhoneNumberException`, so it must be caught first if you want to treat the two differently. Catching only `InvalidPhoneNumberException` still covers both — which is what 3.0 did, when a missing record and malformed input were the same exception.

`AuthenticationException` and `RateLimitException` both extend `ApiException`, so catching `ApiException` alone covers every API-side failure. Every exception the SDK throws implements `E164\Exception\E164Exception` and extends `RuntimeException`:

```
use E164\Exception\E164Exception;

try {
    $result = $e164->lookup($number);
} catch (E164Exception $e) {
    // Anything this SDK can throw.
}
```

Use `getStatusCode()` to tell a server-side error from a transport failure: it returns the HTTP status for the former and `null` for the latter (DNS failure, connection refused, timeout).

Upgrading from 2.x
------------------

[](#upgrading-from-2x)

3.0 renamed the placeholder `Vendor\E164` namespace. For most projects the upgrade is a find-and-replace:

```
-use Vendor\E164\E164;
-use Vendor\E164\Response;
+use E164\E164;
+use E164\LookupResult;
```

Then note these behaviour changes:

- `Response` is now `LookupResult`, immutable, and built via `LookupResult::fromArray()` instead of setters.
- `getCallingCode()`, `getTotalLengthMin()`, `getTotalLengthMax()` and `getWeight()` return `?int` instead of `?string`.
- A custom HTTP client is now typed as PSR-18 rather than `GuzzleHttp\ClientInterface`. Guzzle's own `Client` satisfies both, so injecting one still works.
- Numbers over 15 digits are now rejected rather than sent to the API.

See [CHANGELOG.md](CHANGELOG.md) for the full list.

Development
-----------

[](#development)

```
composer install
composer check   # PHPStan, then the test suite
composer test    # tests only
composer stan    # static analysis only
```

Contributing
------------

[](#contributing)

Fork the repository and submit a pull request. Please include tests for any new features or bug fixes.

License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance97

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity51

Maturing project, gaining track record

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 ~117 days

Total

5

Last Release

17d ago

Major Versions

1.0 → 2.02026-03-20

2.1 → 3.0.02026-07-30

3.0.0 → 4.0.02026-07-31

PHP version history (2 changes)1.0PHP ^7.4 || ^8.0

2.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/d805b7ed843e1f94763d7f2e352d3bb39a51b4a580b95cb1024268afe7279dd3?d=identicon)[cata](/maintainers/cata)

---

Tags

Api WrapperE164phone number validatione164 SDKphone number validation SDK

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/e164-com-e164-php-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/e164-com-e164-php-sdk/health.svg)](https://phpackages.com/packages/e164-com-e164-php-sdk)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

86337.5k](/packages/flow-php-flow)[typo3/cms

TYPO3 CMS is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.

1.2k1.9M122](/packages/typo3-cms)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

265.2k](/packages/aedart-athenaeum)[typo3/cms-core

TYPO3 CMS Core

3313.6M5.6k](/packages/typo3-cms-core)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.8M672](/packages/shopware-core)

PHPackages © 2026

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