budgetlens / intrapost
Fluent PHP client for the Intrapost API (mail, parcels, track & trace)
Requires
- php: ^8.2
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- orchestra/testbench: ^9.0
- pestphp/pest: ^3.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-08-28 09:56:41 UTC
README
Fluent PHP client for the Intrapost API: create shipments, generate labels, track parcels, and manage daily mail orders for PostNL, DHL, and GLS.
Requirements
Installation
composer require budgetlens/intrapost
Configuration
Standalone PHP
use Budgetlens\Intrapost\IntrapostClient; $client = new IntrapostClient( apiKey: 'your-api-key', accountNumber: 'your-account-number', );
Laravel
The package includes auto-discovery, so the service provider and facade are registered automatically.
Publish the config file:
php artisan vendor:publish --tag=intrapost-config
Add to your .env:
INTRAPOST_API_KEY=your-api-key INTRAPOST_ACCOUNT_NUMBER=your-account-number INTRAPOST_BASE_URL=https://api.intrapost.nl INTRAPOST_TIMEOUT=30
Use via dependency injection or facade:
use Budgetlens\Intrapost\IntrapostClient; use Budgetlens\Intrapost\Laravel\Facades\Intrapost; // Dependency injection public function __construct(private IntrapostClient $client) {} // Facade Intrapost::mailPiece()->create()-> ...
Which API do you use when?
The Intrapost API is split into four resources. Below is a guide on when to use which one.
Mail Piece vs. Track & Trace
This is the most important distinction:
| Mail Piece | Track & Trace | |
|---|---|---|
| What | Letters and unregistered mail items | Parcels with track & trace |
| When | Sending regular mail (letters, cards, small mail items up to 2kg) | Sending parcels that need to be tracked |
| Tracking | No full track & trace, only registration and a label | Full track & trace with VZ code and tracking link |
| Weight | In grams (1-2000g) | In kilograms |
| Products | Standard, FixedDays | 12 product types (standard, insured, registered, mailbox parcel, evening delivery, etc.) |
| Extra options | Limited (dimensions, project code) | Extensive (dimensions, pickup point, customs, signature, age check, etc.) |
Rule of thumb: sending a letter or unregistered mail item? Use mailPiece(). Sending a parcel that needs to be tracked? Use trackTrace().
Overview of all calls
| Method | Use when... |
|---|---|
| Mail Piece | |
mailPiece()->create() |
You want to register a new mail piece and generate a label |
mailPiece()->order() |
You want to retrieve the daily order of registered mail pieces (collective order) |
mailPiece()->getLabel() |
You want to retrieve the label of a previously created mail piece again |
| Track & Trace | |
trackTrace()->create() |
You want to register a new parcel with track & trace (the most used call) |
trackTrace()->createMailboxParcel() |
You specifically want to create a mailbox parcel with a ZPL label |
trackTrace()->createLabels() |
You want to generate labels for multiple shipments in a single file |
trackTrace()->getRetourLabel() |
You want to create a return label for an existing shipment |
trackTrace()->cancel() |
You want to cancel a shipment (before it has been processed) |
trackTrace()->search() |
You want to search shipments by date, zipcode, reference, etc. |
trackTrace()->getFromId() |
You want to retrieve shipments by their Piece ID (max. 50 at a time) |
trackTrace()->getFromVz() |
You want to retrieve shipments by their VZ code (max. 50 at a time) |
| Order (Daily Mail) | |
order()->createDailyMailOption1() |
Create a daily mail order (option 1) |
order()->createDailyMailOption2() |
Create a daily mail order (option 2) |
order()->createDailyMailOption3() |
Create a daily mail order (option 3) |
| Utility | |
utility()->lookupAddress() |
You want to validate/look up an address by zipcode + house number |
utility()->productCodes() |
You want to request which product codes are available for your account |
utility()->pickupPointsForAddress() |
You want to search pickup points near an address (for ParcelViaPickupLocation) |
utility()->dropoffPointsForInternationalAddress() |
You want to search drop-off points for international shipments |
Typical flow
1. [Optional] utility()->lookupAddress() : validate the delivery address
2. [Optional] utility()->pickupPointsForAddress() : find a pickup point (if the customer wants one)
3. trackTrace()->create() or mailPiece()->create() : create the shipment, receive the label
4. [Optional] trackTrace()->search() : search/track shipments
5. [Optional] trackTrace()->getRetourLabel() : generate a return label if needed
6. [Optional] trackTrace()->cancel() : cancel if needed
Usage
Mail Pieces
Create a mail piece:
use Budgetlens\Intrapost\Enums\MailPieceProduct; $response = $client->mailPiece()->create() ->product(MailPieceProduct::Standard) ->weight(250) ->reference('ORDER-001') ->to('John Doe', '1234AB', '10', 'NL') ->send(); $response->shipmentId; // "SHP-..." $response->vzCode; // Track & trace code $response->labelData; // Base64 label PDF
Shorthand product methods:
$client->mailPiece()->create()->standard()-> ... // MailPieceProduct::Standard $client->mailPiece()->create()->fixedDays()-> ... // MailPieceProduct::FixedDays
Order mail pieces:
$response = $client->mailPiece()->order('ORDER-001');
Get a label:
$response = $client->mailPiece()->getLabel('SHP-123'); $response->labelData; // Base64 encoded label
Track & Trace Parcels
Create a shipment:
use Budgetlens\Intrapost\Enums\TrackTraceProduct; $response = $client->trackTrace()->create() ->standardParcel() ->weight(2.5) ->reference('REF-001') ->to('Jane Doe', '5678CD', '25', 'NL') ->dimensions(30, 20, 15) ->sendMailToRecipient() ->send();
Available product shorthand methods:
->standardParcel() // StandardParcel ->insuredParcel() // InsuredParcel ->registeredParcel() // RegisteredParcel ->mailboxParcel() // MailboxParcel ->eveningDelivery() // StandardParcelWithEveningDelivery ->withAgeCheck() // StandardParcelWithAgeCheck ->withSignature() // StandardParcelSignature ->pickupLocation() // ParcelViaPickupLocation
Create a mailbox parcel:
$response = $client->trackTrace()->createMailboxParcel() ->weight(0.8) ->to('Jane Doe', '5678CD', '25', 'NL') ->send();
Generate labels:
use Budgetlens\Intrapost\Enums\LabelFormatType; $response = $client->trackTrace()->createLabels( shipmentIds: ['SHP-001', 'SHP-002'], format: LabelFormatType::Pdf150x100, );
Get a return label:
$response = $client->trackTrace()->getRetourLabel() ->shipmentId('SHP-123') ->send();
Cancel a shipment:
$response = $client->trackTrace()->cancel('SHP-123');
Search shipments:
$response = $client->trackTrace()->search() ->dateRange('2025-01-01', '2025-01-31') ->zipcode('1234AB') ->includeHistory() ->get(); foreach ($response->shipments as $shipment) { $shipment->shipmentId; $shipment->status; $shipment->vzCode; }
Look up by ID or VZ code:
$response = $client->trackTrace()->getFromId(['PIECE-001'], includeHistory: true); $response = $client->trackTrace()->getFromVz(['3STEST123456789'], includeHistory: true);
Pickup at a Service Point
use Budgetlens\Intrapost\Enums\CarrierType; $response = $client->trackTrace()->create() ->pickupLocation() ->pickupAt(CarrierType::PostNL, 'LOCATION-ID', 'NL') ->to('Jane Doe', '5678CD', '25', 'NL') ->send();
International Shipments with Customs
use Budgetlens\Intrapost\DTOs\CustomsInfo; use Budgetlens\Intrapost\DTOs\CustomsProduct; $customs = new CustomsInfo( invoiceNumber: 'INV-2025-001', products: [ new CustomsProduct( description: 'T-shirt', quantity: 2, weight: 0.3, value: 29.95, hsCode: '6109100010', countryOfOrigin: 'NL', ), ], ); $response = $client->trackTrace()->create() ->standardParcel() ->to('John Smith', '10001', '100', 'US', city: 'New York') ->customsInfo($customs) ->send();
Daily Mail Orders
$response = $client->order()->createDailyMailOption1() // ... configure order ->send();
Utilities
Address lookup:
$response = $client->utility()->lookupAddress('1234AB', 10); $response->street; $response->city;
Product codes:
$response = $client->utility()->productCodes();
Pickup & drop-off points:
$points = $client->utility()->pickupPointsForAddress() ->zipcode('1234AB') ->countryCode('NL') ->get(); $points = $client->utility()->dropoffPointsForInternationalAddress() ->zipcode('1234AB') ->countryCode('NL') ->get();
Supported Carriers
| Carrier | Enum |
|---|---|
| PostNL | CarrierType::PostNL |
| DHL | CarrierType::DHL |
| GLS | CarrierType::GLS |
Label Formats
| Format | Enum |
|---|---|
| ZPL Zebra 150x100mm | LabelFormatType::ZplZebra150x100 |
| PDF 150x100mm | LabelFormatType::Pdf150x100 |
Error Handling
The client throws specific exceptions for different error scenarios:
use Budgetlens\Intrapost\Exceptions\IntrapostAuthenticationException; use Budgetlens\Intrapost\Exceptions\IntrapostApiException; use Budgetlens\Intrapost\Exceptions\IntrapostException; try { $response = $client->trackTrace()->create() ->standardParcel() ->to('Jane Doe', '5678CD', '25', 'NL') ->send(); } catch (IntrapostAuthenticationException $e) { // Invalid API key (401/403) } catch (IntrapostApiException $e) { // API returned validation errors $e->getErrors(); // array of error messages } catch (IntrapostException $e) { // Network or other errors }
Testing
composer test
Code Style
# Check for violations composer lint # Auto-fix composer fix
License
MIT License. See LICENSE for details.