PHPackages                             crakter/bringapi - 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. crakter/bringapi

ActiveLibrary[API Development](/categories/api)

crakter/bringapi
================

BringApi is a fully functional library to help contact Bring API

3.0.3(1y ago)56.1k4MITPHPPHP &gt;=8.2.0CI passing

Since Jun 21Pushed 2w ago1 watchersCompare

[ Source](https://github.com/crakter/bringapi)[ Packagist](https://packagist.org/packages/crakter/bringapi)[ RSS](/packages/crakter-bringapi/feed)WikiDiscussions master Synced 3w ago

READMEChangelog (9)Dependencies (4)Versions (13)Used By (0)

Bring API PHP
=============

[](#bring-api-php)

[![CI](https://github.com/crakter/bringapi/actions/workflows/ci.yml/badge.svg)](https://github.com/crakter/bringapi/actions/workflows/ci.yml)

A PHP client library for [Bring's developer APIs](https://developer.bring.com/api/): Shipping Guide, Booking, Tracking, Reports, Postal Code, the new Address API, Pickup Point, Modify Delivery, and Order Management (REST).

Used in production by a large Norwegian wholesaler.

Install
-------

[](#install)

```
composer require crakter/bringapi
```

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

[](#requirements)

- PHP **8.2** or newer
- A PSR-18 HTTP client (Guzzle 7 is the suggested default)
- `simplexml` extension (built-in on most distributions)
- `phpoffice/phpspreadsheet` *only* if you call Reports endpoints that return XLS

Supported APIs
--------------

[](#supported-apis)

APICoverageBring docsShipping Guide (v2)price / delivery time / products[link](https://developer.bring.com/api/shipping-guide/)Bookingbook, pickup order, customers[link](https://developer.bring.com/api/booking/)Trackingtrack, signature image[link](https://developer.bring.com/api/tracking/)Reportslist, generate, status, download, invoices[link](https://developer.bring.com/api/reports/)Postal Code (legacy)single lookup[link](https://developer.bring.com/api/postal-code/)**Address (new)**postal-code lookup, suggestions, mailbox-delivery dates[link](https://developer.bring.com/api/postal-code/)**Pickup Point**all / by id / by postal code / by location (NO/SE/DK/FI only)[link](https://developer.bring.com/api/pickup-point/)**Modify Delivery**stop, change address, update contact (NO/SE/DK only)[link](https://developer.bring.com/api/modify-delivery/)**Order Management (REST)**get order, packaging list[link](https://developer.bring.com/api/order-management/)The SOAP variant of Order Management is intentionally out of scope.

Quick start
-----------

[](#quick-start)

```
use Bring\Api\ApiClient;
use Bring\Api\Auth\Credentials;
use Bring\Api\Enum\Country;

$bring = ApiClient::withCredentials(new Credentials(
    uid: 'me@example.com',
    apiKey: getenv('BRING_API_KEY'),
    clientUrl: 'https://example.com',
));

// Modern address lookup
$result = $bring->address()->postalCode(Country::NO, '0150');
echo $result->city; // "OSLO"

// Pickup points near a postal code
foreach ($bring->pickupPoint()->byPostalCode(Country::NO, '0150')->pickupPoints as $pp) {
    echo "{$pp->name} — {$pp->address}\n";
}

// Tracking
$tracking = $bring->tracking()->track('TESTPACKAGE-AT-PICKUPPOINT');
echo $tracking->latestEvent()?->description;
```

Test mode
---------

[](#test-mode)

Calls that support `X-Bring-Test-Indicator` (Booking, Modify Delivery) are toggled at the facade:

```
$bring = ApiClient::withCredentials($creds)->withTestMode(true);
// Every request now carries X-Bring-Test-Indicator: true
```

Booking a shipment
------------------

[](#booking-a-shipment)

```
use Bring\Api\Dto\{Address, Contact, Dimensions, Package};
use Bring\Api\Endpoint\Booking\BookingRequest;
use Bring\Api\Enum\{Country, Product};

$request = BookingRequest::single(
    schemaVersion: '1',
    customerNumber: 'PARCELS_NORWAY-10001234567',
    product: Product::HOME_DELIVERY_PARCEL,
    sender: new Address(
        name: 'Acme AS', addressLine: 'Sandakerveien 24c', addressLine2: null,
        postalCode: '0473', city: 'Oslo', countryCode: Country::NO,
        contact: new Contact(name: 'Pickup Person', phoneNumber: '+4799999999'),
    ),
    recipient: new Address(
        name: 'John Doe', addressLine: 'Storgata 1', addressLine2: null,
        postalCode: '5003', city: 'Bergen', countryCode: Country::NO,
    ),
    packages: [new Package(
        weightInKg: 2,
        dimensions: new Dimensions(lengthInCm: 30, widthInCm: 20, heightInCm: 15),
    )],
);

$resp = $bring->booking()->book($request);
foreach ($resp->consignments as $c) {
    echo "Consignment {$c->confirmation}\n";
}
```

Credentials and logging
-----------------------

[](#credentials-and-logging)

`Credentials` wraps the API key behind `#[\SensitiveParameter]` (PHP 8.2+ scrubs it from stack traces) and masks it in `print_r` / `var_dump` output — debug dumps only show a SHA-256 fingerprint.

Pass any PSR-3 logger to `ApiClient::withCredentials()` and it is automatically wrapped in a `RedactingLogger` that strips `X-Mybring-*` headers and the raw API key from every log line:

```
$bring = ApiClient::withCredentials($creds, logger: $monolog);
```

`BringApiException` never embeds the raw response body in `getMessage()` — Bring occasionally echoes credentials in error envelopes. Callers that want the response body can call `BringApiException::getResponse()` explicitly.

Error handling
--------------

[](#error-handling)

```
use Bring\Api\Exception\{BringApiException, BringTransportException, BringException};

try {
    $bring->shippingGuide()->price($request);
} catch (BringApiException $e) {
    // Bring returned 4xx/5xx — parsed error codes in $e->getErrors()
    error_log("Bring rejected request (HTTP {$e->getStatusCode()})");
    foreach ($e->getErrors() as $err) {
        error_log("  {$err->code}: {$err->message}");
    }
} catch (BringTransportException $e) {
    // PSR-18 network failure (DNS, TLS, timeout); $e->getPrevious() has the cause
} catch (BringException $e) {
    // Catch-all for anything this library throws
}
```

v3 → v4 migration
-----------------

[](#v3--v4-migration)

See [UPGRADE-4.0.md](UPGRADE-4.0.md) for the full mapping. v3 classes (`Crakter\BringApi\*`) still ship and still work — they are marked `@deprecated` and will be removed in 5.0.

Examples
--------

[](#examples)

Set credentials in your environment first:

```
export BRING_UID="me@example.com"
export BRING_API_KEY="1234abc-abcd-1234-5678-abcd1234abcd"
export BRING_CUSTOMER_NUMBER="PARCELS_NORWAY-10001123123"
```

Then run any example from the project root:

```
php examples/v4_PostalCode.php 0150
php examples/v4_PickupPoint.php 0150
php examples/v4_Tracking.php TESTPACKAGE-AT-PICKUPPOINT
php examples/v4_ShippingGuidePrice.php 0150 5003
php examples/v4_BookAndPickup.php   # uses test mode, no labels generated
```

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

[](#development)

```
composer install
composer qa                                     # full gate: cs + phpstan + psalm + phpunit
composer test                                   # all tests (legacy + v4)
composer test-coverage                          # coverage in coverage/ + coverage.xml
composer phpstan                                # PHPStan level 8 on v4
composer psalm                                  # Psalm errorLevel 4 on v4
composer cs                                     # php-cs-fixer dry run
composer docs                                   # build API docs into docs/build
```

API documentation
-----------------

[](#api-documentation)

Generated with [phpDocumentor 3](https://phpdoc.org/) (the abandoned Sami generator was dropped in 4.0). `bin/build-docs` downloads the official phar into `tools/phpdoc.phar` on first run — we deliberately do NOT require phpDocumentor through Composer because its transitive dependency tree conflicts with most application stacks.

```
composer docs              # build into docs/build
composer docs-clean        # wipe + rebuild
bin/build-docs --force     # any extra phpdoc flags pass through
```

Open `docs/build/index.html` in a browser, or let CI publish it: `.github/workflows/docs.yml` builds on every push to `master`/`main` and deploys to GitHub Pages (enable Pages in repo settings → Pages → Source = GitHub Actions to activate). Every workflow run also uploads the rendered docs as an artifact named `api-docs`.

Project documents
-----------------

[](#project-documents)

- [CHANGELOG.md](CHANGELOG.md) — release history (Keep a Changelog format)
- [UPGRADE-4.0.md](UPGRADE-4.0.md) — v3 → v4 migration guide
- [SECURITY.md](SECURITY.md) — vulnerability reporting
- [CONTRIBUTING.md](CONTRIBUTING.md) — coding standards and PR process

License
-------

[](#license)

MIT

###  Health Score

52

—

FairBetter than 96% of packages

Maintenance68

Regular maintenance activity

Popularity28

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity83

Battle-tested with a long release history

 Bus Factor1

Top contributor holds 61.5% 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 ~373 days

Recently: every ~432 days

Total

8

Last Release

677d ago

Major Versions

1.0.2 → 2.0.02019-11-22

2.0.0 → 3.0.02024-07-29

PHP version history (2 changes)1.0.0PHP &gt;=7.0.0

3.0.0PHP &gt;=8.2.0

### Community

Maintainers

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

---

Top Contributors

[![crakter](https://avatars.githubusercontent.com/u/24833502?v=4)](https://github.com/crakter "crakter (59 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (23 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (7 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (7 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisRector

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/crakter-bringapi/health.svg)

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

###  Alternatives

[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.2M46](/packages/tencentcloud-tencentcloud-sdk-php)[neuron-core/neuron-ai

The PHP Agentic Framework.

2.0k496.1k33](/packages/neuron-core-neuron-ai)[avalara/avataxclient

Client library for Avalara's AvaTax suite of business tax calculation and processing services. Uses the REST v2 API.

528.3M7](/packages/avalara-avataxclient)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

252.5k](/packages/eslazarev-wildberries-sdk)[files.com/files-php-sdk

Files.com PHP SDK

2478.1k](/packages/filescom-files-php-sdk)[aimeos/prisma

A powerful PHP package for integrating media related Large Language Models (LLMs) into your applications

1772.4k4](/packages/aimeos-prisma)

PHPackages © 2026

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