Download the PHP package sonnenglas/mydhl-php-sdk without Composer

On this page you can find all versions of the php package sonnenglas/mydhl-php-sdk. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package mydhl-php-sdk

mydhl-php-sdk

Unofficial PHP SDK for the DHL Express MyDHL REST API (currently aligned with spec 3.3.1, June 2026). That version is sent verbatim in the x-version header, which DHL requires on every call.

Status: CircleCI

Note: Only the modern REST API is supported. The legacy SOAP API is not.

Requirements

Installation

Supported services

Service Supported
RATING
Retrieve Rates for a one-piece Shipment ✅
Retrieve Rates for Multi-piece Shipments ✅
Landed Cost ✅
PRODUCT
Retrieve DHL Express products ✅
SHIPMENT
Create Shipment ✅
Customs / international shipments (export declaration) ✅
Re-download archived shipment documents ✅
Electronic Proof of Delivery ✅
Add pieces to an existing shipment ✅
Upload updated customs docs for shipment ✅
Upload Commercial Invoice Data for shipment ✅
TRACKING
Track a single DHL Express Shipment ✅
Track multiple DHL Express Shipments (batch) ✅
PICKUP
Create a DHL Express pickup booking request ✅
Cancel a DHL Express pickup booking request ✅
Update pickup information ✅
Check whether a pickup was actually collected (via tracking) ✅
IDENTIFIER
Allocate identifiers upfront ✅
ADDRESS
Validate DHL Express pickup/delivery capability ✅
INVOICE
Upload Commercial Invoice data ✅
SERVICE POINTS / REFERENCE DATA
Look up servicepoints / reference data ✅
EARLY SHIPMENT SCREENING
Screen break-bulk baby shipments ✅

Design

The SDK splits responsibilities between value objects (immutable, validated request payloads) and services (thin transport that talk to DHL):

Every required field is a constructor parameter, so missing data fails at request-build time, not somewhere inside the API call.

Every getXService() call hands back the same instance for the lifetime of the MyDHL object, so getLastRawResponse() still returns the payload of the call you just made.

Error handling

HTTP and transport failures surface as Sonnenglas\MyDHL\Exceptions\ClientException — Guzzle exceptions never leak out of the SDK:

getMessage() carries the method, the URI and the response body, truncated at 2 000 characters so it stays loggable — reach for getResponseBody() when you need the whole payload. Credentials are sent as an Authorization header and never appear in the message.

Quick start

The base URLs are baked in:

Environment URL
Sandbox https://express.api.dhl.com/mydhlapi/test/
Production https://express.api.dhl.com/mydhlapi/

Sandbox is rate-limited to 500 calls/day per credential set.

Usage

Retrieve rates

Multi-piece rates

For shipments with more than one package, use the POST variant:

Landed cost

Estimate duties, taxes and fees for an international shipment before creating it:

LandedCostResult::$products holds one LandedCost per DHL product; $warnings collects anything DHL flagged about the quote.

Available products

Like /rates, but without the full price breakdown — useful for showing which DHL products serve a lane:

Validate an address

Allocate identifiers upfront

IdentifierService::TYPES lists the codes DHL accepts: SID (shipment), PID (piece), ASID3 / ASID6 / ASID12 / ASID24 (alternative shipment identifiers) and HUID (handling unit). Anything else throws InvalidArgumentException before the call is made.

Create a domestic shipment

description (1–70 characters) and incoterm are required on every shipment, domestic ones included — not just customs-declarable ones. Both are validated in the ShipmentRequest constructor, so an omitted value fails locally instead of coming back as a 422.

Customs / international shipments

International shipments need declaredValue, an ExportDeclaration with line items, and (recommended) a tax RegistrationNumber:

The incoterm sits on the ShipmentRequest here. When the same goods are sent to upload-invoice-data, DHL expects it inside the declaration instead — that endpoint uses a different schema.

Track a shipment

track() asks DHL for the GMT offset of every scan, so TrackingEvent::getOccurredAt() returns a correctly zoned timestamp. The batch endpoint has no such option — its events carry no offset, so use track() when event times matter.

Check whether a pickup actually happened

MyDHL has no read endpoint for pickups — /pickups only accepts POST, PATCH and DELETE. A dispatch confirmation number therefore proves that the booking was accepted, not that a courier ever showed up. The scans are the only evidence:

NotCollected is the one worth alerting on: a booked pickup with no scan hours later means the parcel is still sitting in the warehouse. The same answer is available on the shipment itself, together with the scan behind it:

Piece-level scans count too — DHL does not always mirror them onto the shipment.

Book / update / cancel a courier pickup separately

Use this when the shipment was created with Pickup::notRequested() and the pickup needs to be booked (or cancelled) independently — typical when an order is cancelled hours before pickup time.

Moving a booking to another slot does not need a cancel + re-book — update() keeps the confirmation number. DHL replaces the booking with what you send, so pass a complete PickupRequest plus the account the pickup was originally booked with:

plannedPickupDateAndTime must be in the future and at most 10 days ahead — DHL rejects anything outside that window.

Re-download archived documents (waybill, customs invoice)

/get-image does not return the transport label. The label is returned inline only at createShipment time. Save Shipment::getLabelPdf() then.

Modify an existing shipment (add pieces, upload customs docs / invoice data)

All three operations target a shipment that already exists; DHL enables them per customer:

The standalone variant (before the shipment exists) lives on InvoiceService:

The invoice-upload declaration is not the shipment declaration

DHL uses two different schemas for exportDeclaration, and both reject unknown fields. An ExportDeclaration built for createShipment is therefore not reusable here: uploading invoice data additionally requires an incoterm on the declaration and a function on the invoice, while the invoice's signatureName, signatureTitle, totalNetWeight and totalGrossWeight are only accepted by createShipment.

The SDK keeps both shapes in one pair of value objects and picks the right serialization per endpoint, so you only have to supply the extra fields:

Both extra arguments are optional on the constructor (so shipment declarations stay unchanged) but validated when the upload request is built, which means a missing one fails locally instead of coming back as a 422.

Service points

search(ServicePointRequest) exposes the full query surface (geo radius, capabilities, opening hours, …).

Reference data

getDataset() returns null when DHL has no rows for the dataset; use get() instead when you want the full ReferenceDataResult wrapper. ReferenceDataService::ALLOWED_DATASETS lists every dataset DHL publishes (countries, currencies, service codes, …). Rows are returned as raw associative arrays because each dataset has its own schema.

Early shipment screening

Pre-screen break-bulk baby shipments before tendering them:

Proof of Delivery

Full examples:

Development

Integration tests against the DHL sandbox

Copy tests/Integration/.env.example and export your sandbox credentials, then:

Without these env vars the integration suite auto-skips, so contributor laptops and CI without secrets stay green. Each integration run consumes one or two of the daily 500 sandbox calls — keep them deliberate.

Upgrading

Credits

Built and maintained by Przemek Peron.

License

MIT


All versions of mydhl-php-sdk with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
ext-json Version *
guzzlehttp/guzzle Version ^7.12.1
ramsey/uuid Version ^4.7
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package sonnenglas/mydhl-php-sdk contains the following files

Loading the files please wait ...