This library allows you to quickly and easily use the AfterShip Tracking API via PHP.
For updates to this library, see our GitHub release page.
If you need support using AfterShip products, please contact support@aftership.com.
Before you begin to integrate:
- Create an AfterShip account.
- Create an API key.
- Install PHP version 8.1 or later.
- SDK Version: 16.0.0
- API Version: 2026-07
composer require aftership/tracking-sdkCreate AfterShip instance with options
| Name | Type | Required | Description |
|---|---|---|---|
| api_key | string | ✔ | Your AfterShip API key |
| auth_type | enum | Default value: AuthType.API_KEY AES authentication: AuthType.AES RSA authentication: AuthType.RSA |
|
| api_secret | string | Required if the authentication type is AuthType.AES or AuthType.RSA |
|
| domain | string | AfterShip API domain. Default value: https://api.aftership.com | |
| user_agent | string | User-defined user-agent string, please follow RFC9110 format standard. | |
| proxy | string | HTTP proxy URL to use for requests. Default value: null Example: http://192.168.0.100:8888 |
|
| max_retry | number | Number of retries for each request. Default value: 2. Min is 0, Max is 10. | |
| timeout | number | Timeout for each request in milliseconds. |
<?php
require_once __DIR__ . '/vendor/autoload.php';
$client = new \Tracking\Client([
'apiKey' => 'YOUR_API_KEY',
'authenticationType' => \Tracking\Config::AUTHENTICATION_TYPE_API_KEY,
]);
try {
$query = new \Tracking\Model\GetTrackingByIdQuery();
$response = $client->tracking->getTrackingById(
'valid_value',
$query
);
var_dump($response);
} catch (\Tracking\Exception\AfterShipError $e) {
// Handle the error
var_dump($e->getErrorCode());
var_dump($e->getStatusCode());
}See the Rate Limit to understand the AfterShip rate limit policy.
The API returns its current rate limit status in the headers of every response, and the SDK exposes these headers on both successful responses and rate-limited errors, so you can monitor your consumption proactively instead of waiting for 429 errors.
| Header | Description |
|---|---|
X-RateLimit-Limit |
The rate limit ceiling for the current endpoint per second |
X-RateLimit-Remaining |
The number of requests left for the 1-second window |
X-RateLimit-Reset |
The Unix timestamp when the rate limit will be reset |
Every successful response exposes getResponseHeader() (an array<string, string[]>) alongside getData(). Header names are case-insensitive per the HTTP spec, so normalize when looking up. Taking the Quick Start example above:
$headers = array_change_key_case($response->getResponseHeader(), CASE_LOWER);
$remaining = (int) ($headers['x-ratelimit-remaining'][0] ?? -1);
$resetAt = (int) ($headers['x-ratelimit-reset'][0] ?? 0);
if ($remaining >= 0 && $remaining <= 1) {
// Throttle or defer lower-priority requests until $resetAt
}When the rate limit is exceeded, the request fails with a 429 error that carries the same headers — see Error Handling.
The SDK will return an error object when there is any error during the request, with the following specification:
| Name | Type | Description |
|---|---|---|
| message | string | Detail message of the error |
| code | enum | Error code enum for API Error. |
| meta_code | number | API response meta code. |
| status_code | number | HTTP status code. |
| response_body | string | API response body. |
| response_header | object | API response header. |
The AfterShip instance has the following properties which are exactly the same as the API endpoints:
- tracking
- Get trackings
- Create a tracking
- Get a tracking by ID
- Update a tracking by ID
- Delete a tracking by ID
- Retrack an expired tracking by ID
- Mark tracking as completed by ID
- courier
- Get couriers
- Detect courier
- courier_connection
- Get courier connections
- Create courier connections
- Get courier connection by id
- Update courier connection by id
- Delete courier connection by id
- estimated_delivery_date
- Prediction for the Estimated Delivery Date
- Batch prediction for the Estimated Delivery Date
GET /trackings
$query = new \Tracking\Model\GetTrackingsQuery();
$response = $client->tracking->getTrackings(
$query
);
var_dump($response);POST /trackings
$payload = new \Tracking\Model\CreateTrackingRequest();
$payload->tracking_number = 'valid_value';
$response = $client->tracking->createTracking(
$payload
);
var_dump($response);GET /trackings/{id}
$query = new \Tracking\Model\GetTrackingByIdQuery();
$response = $client->tracking->getTrackingById(
'valid_value',
$query
);
var_dump($response);PUT /trackings/{id}
$payload = new \Tracking\Model\UpdateTrackingByIdRequest();
$response = $client->tracking->updateTrackingById(
'valid_value',
$payload
);
var_dump($response);DELETE /trackings/{id}
$response = $client->tracking->deleteTrackingById(
'valid_value'
);
var_dump($response);POST /trackings/{id}/retrack
$response = $client->tracking->retrackTrackingById(
'valid_value'
);
var_dump($response);POST /trackings/{id}/mark-as-completed
$payload = new \Tracking\Model\MarkTrackingCompletedByIdRequest();
$response = $client->tracking->markTrackingCompletedById(
'valid_value',
$payload
);
var_dump($response);GET /couriers
$query = new \Tracking\Model\GetCouriersQuery();
$response = $client->courier->getCouriers(
$query
);
var_dump($response);POST /couriers/detect
$payload = new \Tracking\Model\DetectCourierRequest();
$payload->tracking_number = 'valid_value';
$response = $client->courier->detectCourier(
$payload
);
var_dump($response);GET /courier-connections
$query = new \Tracking\Model\GetCourierConnectionsQuery();
$response = $client->courier_connection->getCourierConnections(
$query
);
var_dump($response);POST /courier-connections
$payload = new \Tracking\Model\PostCourierConnectionsRequest();
$payload->courier_slug = 'valid_value';
$payload->credentials = [];
$response = $client->courier_connection->postCourierConnections(
$payload
);
var_dump($response);GET /courier-connections/{id}
$response = $client->courier_connection->getCourierConnectionsById(
'valid_value'
);
var_dump($response);PATCH /courier-connections/{id}
$payload = new \Tracking\Model\PutCourierConnectionsByIdRequest();
$payload->credentials = [];
$response = $client->courier_connection->putCourierConnectionsById(
'valid_value',
$payload
);
var_dump($response);DELETE /courier-connections/{id}
$response = $client->courier_connection->deleteCourierConnectionsById(
'valid_value'
);
var_dump($response);POST /estimated-delivery-date/predict
$payload = new \Tracking\Model\EstimatedDeliveryDateRequest();
$payload->slug = 'valid_value';
$originAddress = new \Tracking\Model\EstimatedDeliveryDateRequestOriginAddress();
$payload->origin_address = $originAddress;
$destinationAddress = new \Tracking\Model\EstimatedDeliveryDateRequestDestinationAddress();
$payload->destination_address = $destinationAddress;
$response = $client->estimated_delivery_date->predict(
$payload
);
var_dump($response);POST /estimated-delivery-date/predict-batch
$payload = new \Tracking\Model\PredictBatchRequest();
$response = $client->estimated_delivery_date->predictBatch(
$payload
);
var_dump($response);If you get stuck, we're here to help:
- Issue Tracker for questions, feature requests, bug reports and general discussion related to this package. Try searching before you create a new issue.
- Contact AfterShip official support via support@aftership.com
Copyright (c) 2025 AfterShip
Licensed under the MIT license.
