Packy is a high-performance RESTful shipment tracking API and multicarrier tracking API designed to normalize delivery data across 1385+ carriers globally. Built for developers, e-commerce platforms, and logistics providers, it functions as a comprehensive package tracking API and parcel tracking API in a single integration. Packy Tracking API offers a generous free tier (free package) for developers to start testing and tracking immediately with no credit card required. Key features include carrier auto-detection, realtime updates via high-frequency webhooks, and unified delivery tracking API endpoints. Automate your post-purchase experience, reduce WISMO (Where Is My Order) tickets, and get normalized JSON status updates for any courier worldwide using our free plan or scalable commercial tiers.
Returns a paginated list of the account's trackings.
| page | integer >= 1 Default: 1 Page number. |
| limit | integer >= 1 Default: 20 Page size. |
{- "data": [
- {
- "id": "2f8b1c4d5e6f7a8b9c0d1e2f3a4b5c6d",
- "tracking_number": "9400111899562537683144",
- "courier_code": "usps",
- "delivery_status": "in_transit",
- "updated_at": "2026-05-26T14:30:00Z"
}
], - "meta": {
- "page": 1,
- "limit": 20,
- "total": 1
}
}Creates one or more trackings. The body is either a single object or an array of objects. Up to 40 trackings can be created per request.
Specifying the courier is optional: if courier_code is omitted, the
courier is detected automatically from the tracking number.
This operation consumes account credits.
Behavior depends on ?async:
async=true (default) — trackings are created and refreshed in the
background; the response contains the created trackings without events
yet.async=false — the response is enriched with the latest events for
each tracking (events array).The response is a {data, errors} envelope:
201 Created — all items were created;207 Multi-Status — partial success (both data and errors present);422 Unprocessable Entity — nothing was created, only errors.| async | boolean Default: true Return immediately (true) or wait for enriched events (false). |
| tracking_number required | string |
| courier_code | string Courier code; if omitted, it is detected automatically. |
{- "tracking_number": "9400111899562537683144",
- "courier_code": "usps"
}{- "data": [
- {
- "id": "2f8b1c4d5e6f7a8b9c0d1e2f3a4b5c6d",
- "tracking_number": "9400111899562537683144",
- "courier_code": "usps",
- "delivery_status": "in_transit",
- "updated_at": "2026-05-26T14:30:00Z",
- "events": [
- {
- "occurred_at": "2026-05-25T14:30:00Z",
- "location": "New York, NY",
- "description": "Accepted at USPS facility"
}
]
}
], - "errors": [
- {
- "tracking_number": "788702674979",
- "code": "already_exists",
- "message": "Tracking already exists"
}
]
}Returns a single tracking with its events.
| id required | string Tracking identifier. |
{- "id": "2f8b1c4d5e6f7a8b9c0d1e2f3a4b5c6d",
- "tracking_number": "9400111899562537683144",
- "courier_code": "usps",
- "delivery_status": "in_transit",
- "updated_at": "2026-05-26T14:30:00Z",
- "events": [
- {
- "occurred_at": "2026-05-25T14:30:00Z",
- "location": "New York, NY",
- "description": "Accepted at USPS facility"
}
]
}Returns the list of possible couriers for the given tracking number.
| tracking_number required | string |
{- "tracking_number": "MGRAE0003506539YQ"
}[- {
- "id": 5,
- "code": "meest",
- "name": "Meest",
- "type": "parcel",
- "country": "ua",
- "required_fields": [
- {
- "name": "meest.zip",
- "example": "01001",
- "mask": "^[0-9]{5}$",
- "length": 5
}
]
}
]Creates a webhook subscription. url must be https. secret is never
returned — its presence is surfaced via the has_secret field.
| url required | string <uri> Must use |
| secret | string Secret used to sign deliveries (never returned in responses). |
| enabled | boolean Default: true |
{- "secret": "s3cr3t",
- "enabled": true
}{- "id": 1,
- "has_secret": true,
- "enabled": true,
- "created_at": "2026-05-26T14:30:00Z",
- "updated_at": "2026-05-26T14:30:00Z"
}Partial update. Only the fields to be changed are sent. An empty
secret clears the secret (has_secret=false).
| id required | integer <int64> Subscription identifier. |
| url | string <uri> |
| secret | string An empty string clears the secret. |
| enabled | boolean |
{- "enabled": false
}{- "id": 1,
- "has_secret": true,
- "enabled": true,
- "created_at": "2026-05-26T14:30:00Z",
- "updated_at": "2026-05-26T14:30:00Z"
}