Tracking API Guide
Overview
The Tracking API provides a normalized, real-time view of every package moving through the iDrive network. When a label is purchased through iDrive, a tracker is automatically created and associated with the shipment — no additional setup required on your end. For carriers that don't support automatic tracker creation, iDrive handles the setup manually. From there, iDrive receives carrier scan events on your behalf, normalizes them across carriers, and surfaces the latest shipment state through the Tracking API.
The Tracking API is read-only. Tracker records are created server-side as a side effect of label purchase. You do not need to call any endpoint to create or register a tracker.
Supported carriers include USPS, UPS, FedEx, DHL eCommerce, Amazon Shipping, GLS, OSM, ePost Global, DoorDash, and SpeedX. Scan event availability and depth vary by carrier.
Quickstart
The minimum path to your first tracker takes three steps.
1. Get an access token
Exchange your API client credentials for a short-lived access token using the machine-to-machine (M2M) token endpoint. You will pass the returned token in the Authorization header on every subsequent call. The token is scoped to the tenantId you include in the request body, so no separate tenant header is required on downstream calls.
curl -X POST 'https://api.idrivelogistics.com/api/v1/tokens/m2m' \
-H 'Content-Type: application/json' \
-d '{
"grantType": "clientCredentials",
"clientId": "YOUR_API_CLIENT_ID",
"clientSecret": "YOUR_API_CLIENT_SECRET",
"tenantId": "YOUR_TENANT_ID"
}'Confirm the exact response shape on idrivelogistics.readme.io. The important behaviors are: client credentials are exchanged for a short-lived bearer token, the token is scoped to the
tenantIdsupplied in the request, and the bearer token is required on every Tracking API call.
2. List recent trackers
Pass the access token as a bearer token. The example below returns trackers most recently created first.
curl 'https://api.idrivelogistics.com/api/v1/trackers?sort=createdAt:desc' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'3. Get a single tracker by ID
Once you know a tracker's ID — for example, from the list call above or from the tracker ID returned at label purchase time — fetch its full state directly.
curl 'https://api.idrivelogistics.com/api/v1/trackers/{trackerId}' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'Authentication
The Tracking API uses OAuth 2.0 client credentials (machine-to-machine) for authentication. API consumers exchange a client ID and client secret for a short-lived bearer token, then send that token on every API request.
Token endpoint. POST /api/v1/tokens/m2m
Request body.
{
"grantType": "clientCredentials",
"clientId": "YOUR_API_CLIENT_ID",
"clientSecret": "YOUR_API_CLIENT_SECRET",
"tenantId": "YOUR_TENANT_ID"
}The tenantId in the request body scopes the resulting token to a single tenant — typically your 3PL tenant or one of your brand tenants. Because the tenant is bound to the token, you do not send a separate tenant header on Tracking API requests. If you operate multiple tenants (for example, a 3PL parent with brand tenants underneath), mint a separate token per tenant and use the appropriate token for each request. A token minted for tenant A will return 403 Forbidden if used to read trackers under tenant B.
Authorization header. Pass the token returned by /api/v1/tokens/m2m as a bearer token on every Tracking API call.
Authorization: Bearer YOUR_ACCESS_TOKEN
Tokens are short-lived; refresh them by re-calling /api/v1/tokens/m2m when you receive a 401 Unauthorized response.
The
x-tenant-idheader is part of iDrive's human (Auth0) login flow and is not used by API consumers. M2M tokens carry the tenant internally — includingx-tenant-idon Tracking API requests is unnecessary.
Environments
| Environment | Base URL | Notes |
|---|---|---|
| Production | https://api.idrivelogistics.com | Live shipment and tracker data. |
| Sandbox | https://api.beta.idrivelogistics.com | For integration development. Tracker updates may be limited or simulated. |
| Sandbox accounts are issued on request and are pre-loaded with sample tenants and carrier accounts so you can exercise the full request/response shape without producing real labels. Contact your iDrive technical contact to request sandbox credentials. |
Test-mode labels (
mode: "TEST") generate trackers, but tracking events for test labels are limited compared to production. Expect a small number of synthetic events and not a full delivery lifecycle. The window is very short so we recommend trying to capture those tracking events right after you purchase a label in TEST mode. When you switch the mode to "LIVE", then you will be begin to see fully delivery lifecycle tracking updates.
The Tracker resource
A tracker represents a single package's tracking record. It carries the tracking number, the most recent status, the carrier, references back to the shipment and label, and metadata about origin and destination.
The fields below reflect the conceptual data model.
| Field | Type | Description |
|---|---|---|
id | string | iDrive's identifier for the tracker. Stable across updates. |
externalTrackerId | string | The provider-side identifier (for example, an EasyPost tracker ID) when applicable. |
trackingNumber | string | The carrier-issued tracking number. |
shipmentId | string | The iDrive shipment ID this tracker is attached to. |
packageId | string | The iDrive package ID. A multi-piece shipment will have one tracker per package. |
tenantId | string | Owning tenant. |
onBehalfOfId | string | Sub-tenant the package was shipped on behalf of (for 3PL → brand relationships). |
carrier | enum | Normalized carrier code — for example USPS, UPS, FEDEX, AMZN_US, DHL_ECOMMERCE, GLS, OSM, DOORDASH. |
serviceLevel | enum | Normalized service-level code — for example FEDEX_GROUND_HOME_DELIVERY, USPS_PRIORITY. |
currentStatus | enum | Normalized status. See Tracker statuses. |
lastLocation | string | Most recent scan location, formatted as City, State, Zip (US) or the carrier-supplied equivalent. |
trackingUrl | string | Carrier-hosted tracking page for this package and this URL is carrier-specific. EasyPost-hosted URLs are exposed in a separate field. |
provider | enum | The upstream tracking provider used by iDrive — for example, EASYPOST, AMAZON, EVS, UPS, FEDEX, DHL_ECOM, USPS, SPEEDX, GLS, DOORDASH UNKNOWN |
senderCountryCode | string | ISO-3166 country code of origin. |
senderPostalCode | string | Postal code of origin. |
recipientCountryCode | string | ISO-3166 country code of destination. |
recipientPostalCode | string | Postal code of destination. |
trackingDetails[] | array | Time-ordered scan events with eventDate, status, location, and description. |
createdAt | datetime | When iDrive first created the tracker (typically at label purchase). |
updatedAt | datetime | When iDrive last applied a tracking update. |
Lifecycle timestamps such as firstScanTime, pickupTime, outForDeliveryTime, deliveredTime, returnToSenderTime, and deliveryExceptionTime are populated as the corresponding events are received. Fields remain null until the carrier reports the matching event. |
Endpoints
List trackers
GET /api/v1/trackers
Returns trackers for the tenant bound to your access token. Supports filtering, sorting, and pagination.
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <access_token> |
| Query parameters | ||
| Parameter | Type | Description |
| :------------ | :------ | :----------------------------------------------------------------------------------------------------------- |
pageToken | string | A token to retrieve the next page of results. |
pageSize | number | The number of items to return per page |
inclueTotal | boolean | Whether to include the total number of items in the response |
filter | string | Filter expression. Multiple comparators supported. Example: filter=carrier==AMZN_US. |
sort | string | Sort expression in the form field:direction. Direction is asc or desc. Example: sort=createdAt:desc. |
| Example |
curl --request GET \
--url https://api.beta.idrivelogistics.com/api/v1/trackers \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response — 200 OK
{
"items": [
{
"id": "string",
"tenantId": "string",
"labelId": "string",
"shipmentId": "string",
"onBehalfOfId": "string",
"externalTrackerId": "string",
"provider": "EASYPOST",
"carrier": "USPS",
"serviceLevel": "string",
"senderCountryCode": "string",
"senderPostalCode": "string",
"recipientCountryCode": "string",
"recipientPostalCode": "string",
"carrierAccountId": "string",
"trackingNumber": "string",
"isInternal": true,
"status": "PRE_TRANSIT",
"events": [
{
"status": "PRE_TRANSIT",
"externalShipmentId": "string",
"previousStatus": "PRE_TRANSIT",
"providerStatus": "string",
"location": "string",
"city": "string",
"stateProvince": "string",
"postalCode": "string",
"country": "string",
"carrierMessage": "string",
"eventDate": "2026-05-14T19:35:40.788Z",
"id": "string",
"createdAt": "2026-05-14T19:35:40.788Z",
"updatedAt": "2026-05-14T19:35:40.788Z"
}
],
"createdAt": "2026-05-14T19:35:40.788Z",
"updatedAt": "2026-05-14T19:35:40.788Z"
}
],
"itemCount": 0,
"totalItems": 0,
"pageNumber": 0,
"nextPageToken": "string"
}Get a tracker by ID
GET /api/v1/trackers/{id}
Returns the full tracker record for a single ID. Use this when you already have the tracker ID in hand — for example, from the response to a label purchase.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id | string | iDrive tracker ID (the id field above). |
| Headers | ||
| Same as List trackers. | ||
| Example |
curl 'https://api.idrivelogistics.com/api/v1/trackers/trk_01HZX3ABCDEF' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'Response — 200 OK returns a single tracker object with the same shape as an item in the list response.
A 404 Not Found is returned if the tracker does not exist or if it exists under a tenant your token is not authorized to read.
Tracker statuses
iDrive normalizes carrier-specific status codes into a single set of values. Build your application logic against these normalized values rather than against carrier-specific strings, which vary across carriers and change without notice.
| Status | Meaning |
|---|---|
PRE_TRANSIT | Label created, but the carrier has not yet acknowledged or scanned the package. |
IN_TRANSIT | Package is moving through the carrier network. |
OUT_FOR_DELIVERY | Package is on the delivery vehicle for its final stop. |
DELIVERY_ATTEMPTED | Carrier attempted delivery and was unable to complete it (no one home, access issue, etc.). |
DELIVERED | Package was delivered. |
AVAILABLE_FOR_PICKUP | Package is held at a carrier location for the recipient to pick up. |
RETURN_TO_SENDER | Package is being returned to the shipper. |
FAILURE | Delivery failed in a way that does not fit the other categories. |
CANCELLED | Tracker was cancelled, typically because the label was voided before any scan occurred. |
ERROR | iDrive received an event that could not be processed for this tracker. |
LOST | Carrier reported the package as lost. |
DAMAGED | Carrier reported the package as damaged. |
UNKNOWN | Status could not be determined from the available data. |
Statuses are intentionally coarse. Use the per-event entries in trackingDetails[] if you need finer-grained narration (for example, "Departed regional facility" or "Held by customs"). |
Filtering, sorting, and pagination
The list endpoint accepts a familiar query-string convention.
Filtering. The filter parameter accepts an expression in the form field<comparator>value. Use == for equality. Example:
filter=carrier==AMZN_US
Confirm the full set of supported fields and comparators against the live spec; in practice, filtering by carrier, currentStatus, and time fields is the most common pattern.
Sorting. The sort parameter takes one or more field:direction clauses. Example:
sort=createdAt:desc
Pagination. The list endpoint returns a nextCursor value when more results are available. Pass it back as the cursor query parameter to retrieve the next page. Iterate until nextCursor is omitted from the response.
Errors and troubleshooting
The Tracking API uses standard HTTP status codes. Error bodies share a common envelope:
{
"message": "You do not have permission to access this connection",
"statusCode": 403,
"errors": [],
"correlationId": "5jBjAM+2TDWDjsnOJI/SsA/0000000975"
}When opening a support ticket, always include the correlationId from the failing response. It is the fastest way for the iDrive team to find the corresponding request in our logs.
Common status codes
| Code | Name | Typical cause and fix |
|---|---|---|
400 | Bad Request | A query parameter is malformed, or a filter references a field or comparator that is not supported. Validate filter and sort syntax against the spec. |
401 | Unauthorized | The access token is missing, malformed, or expired. Re-exchange your client credentials at /api/v1/tokens/m2m for a fresh token and retry. |
403 | Forbidden | The token is valid but is not authorized to read the resource. A token is bound to the tenantId supplied at mint time — a token minted for one tenant cannot read trackers under a different tenant. The error message commonly seen here is "You do not have permission to access this connection." |
404 | Not Found | The tracker ID does not exist, or it exists under a tenant your token is not authorized for. iDrive deliberately returns 404 (not 403) in the second case to avoid leaking the existence of cross-tenant resources. |
429 | Too Many Requests | You have exceeded the rate limit for your tenant. Back off and retry. If you consistently hit this ceiling, contact your iDrive technical contact about a higher limit. |
500 | Internal Server Error | Unexpected server-side failure, including upstream carrier API failures (we have observed this from Amazon Shipping, for example). Retry with exponential backoff. If the error persists, capture the correlationId and reach out. |
502 / 503 / 504 | Upstream / Gateway errors | Treat as transient. Retry with exponential backoff. |
Troubleshooting checklist
When a Tracking API call is not behaving as expected, work through this list before opening a ticket.
- Confirm the environment. Production uses
api.idrivelogistics.com. The sandbox usesapi.beta.idrivelogistics.com. Pointing a sandbox tenant ID at production (or vice versa) will return 403 or 404. - Confirm the token's tenant. A token is minted for a single tenant — the
tenantIdvalue you sent to/api/v1/tokens/m2m. A token minted for tenant A will not read trackers under tenant B. Multi-tenant 3PLs must mint a separate token per tenant and use the right token for each request. - Confirm tracking is enabled for the carrier account. If you create a label and never see tracker updates, verify with iDrive that tracking webhooks are enabled for the underlying carrier account. Test-mode labels in particular have limited tracking in sandbox.
- Allow time for the first event. A tracker created at the moment of label purchase will report
PRE_TRANSITuntil the carrier produces its first scan. The gap can be from minutes to over a day depending on carrier and pickup cadence. - Treat carrier strings as opaque. When parsing
lastLocation, prefer thetrackingDetails[*].locationfield on individual events rather than re-parsinglastLocation, which is a display string. If you must parse it, the convention for US scans isCity, State, Zip— a missing component is rendered asnull. - Use
correlationIdwhen escalating. The single most useful thing in a support ticket is the correlation ID from the failing response.
Need help?
- Live API reference and try-it-out: idrivelogistics.readme.io
- Sandbox access, rate-limit increases, or anything else: contact your iDrive contact.
Updated 2 months ago
