Parcels App Tracking API
Create tracking requests and read results
Create tracking requests and read results
openapi: 3.0.3
info:
title: Parcels Account Tracking API
version: 1.0.0
description: 'Track packages and shipments worldwide through the Parcels API. Tracking is asynchronous: create a tracking request, then poll by UUID until the result is complete. Use the Mock API server in this documentation to try the flow without an API key or account limits.'
contact:
name: Parcels
url: https://parcelsapp.com
email: hello@parcelsapp.com
servers:
- url: https://parcelsapp.com/api/v3
description: Live API
tags:
- name: Tracking
description: Create tracking requests and read results
paths:
/shipments/tracking:
post:
operationId: createTrackingRequest
summary: Create tracking request
description: 'Creates an asynchronous tracking request. The response usually contains a temporary `uuid`; use that UUID with `GET /shipments/tracking` to read results, or pass `webhookUrl` to receive callbacks.
Cached results can be returned immediately in the `shipments` array:
- If every requested shipment is already cached, the API returns `done: true`, `fromCache: true`, and populated `shipments` immediately. In this case there may be no `uuid`, because no new tracking request is needed.
- If only some shipments are cached, the API returns a `uuid`, `fromCache: true`, and the cached subset in `shipments`. Continue polling by `uuid` or wait for webhook callbacks for the remaining shipments.
- If nothing is cached yet, the API returns a `uuid` and an empty `shipments` array while tracking continues in the background.'
tags:
- Tracking
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TrackingRequest'
examples:
usps:
summary: USPS demo shipment
value:
apiKey: <YOUR_API_KEY>
language: en
shipments:
- trackingId: '9400111206213785678901'
destinationCountry: United States
webhook:
summary: Tracking request with webhook
value:
apiKey: <YOUR_API_KEY>
language: en
webhookUrl: https://example.com/parcels-webhook
shipments:
- trackingId: '9400111206213785678901'
destinationCountry: United States
description: Parcels will send webhook events to `webhookUrl` as shipments finish and when the full batch is complete.
responses:
'200':
description: Tracking request, cached tracking result, or API error. Business errors are returned as JSON with an `error` field.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/TrackingResult'
- $ref: '#/components/schemas/ErrorResponse'
examples:
created:
summary: Request created
value:
uuid: demo_usps_delivered
shipments: []
cached:
summary: Completed from cache
value:
done: true
fromCache: true
shipments:
- trackingId: '9400111206213785678901'
status: delivered
origin: United States
destination: United States
originCode: US
destinationCode: US
states:
- state: Delivered, In/At Mailbox
location: Austin, TX, United States
date: '2026-06-25T18:42:00.000Z'
carrier: 0
services:
- slug: usps
name: USPS
detectedCarrier:
slug: usps
name: USPS
description: All requested shipments were cached, so the response is already complete and no polling is needed.
unconfirmedAccount:
summary: Account not confirmed
value:
error: UNCONFIRMED_ACCOUNT
description: Account email is not confirmed.
confirmationUrl: https://parcelsapp.com/api/v3/account/confirm/user%40example.com/0123456789abcdef
confirmationExpiresAt: '2026-07-08T12:00:00.000Z'
invalidWebhookUrl:
summary: Invalid webhook URL
value:
error: INVALID_WEBHOOK_URL
description: HTTPS required for webhook URLs in production
partialCached:
summary: Partially completed from cache
description: One or more shipments were returned immediately from cache; use `uuid` to read or receive the remaining results.
value:
uuid: demo_mixed_cache
fromCache: true
shipments:
- trackingId: '9400111206213785678901'
status: delivered
origin: United States
destination: United States
originCode: US
destinationCode: US
states:
- state: Delivered, In/At Mailbox
location: Austin, TX, United States
date: '2026-06-25T18:42:00.000Z'
carrier: 0
- state: Arrived at Post Office
location: Austin, TX, United States
date: '2026-06-25T13:17:00.000Z'
carrier: 0
services:
- slug: usps
name: USPS
detectedCarrier:
slug: usps
name: USPS
x-codeSamples:
- lang: curl
label: cURL
source: "curl -X POST \"https://parcelsapp.com/api/v3/shipments/tracking\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"apiKey\":\"<YOUR_API_KEY>\",\"language\":\"en\",\"shipments\":[{\"trackingId\":\"9400111206213785678901\",\"destinationCountry\":\"United States\"}]}'"
- lang: JavaScript
label: JavaScript
source: "const response = await fetch('https://parcelsapp.com/api/v3/shipments/tracking', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n apiKey,\n language: 'en',\n shipments: [{ trackingId: '9400111206213785678901', destinationCountry: 'United States' }]\n })\n});\n\nconsole.log(await response.json());"
- lang: Python
label: Python
source: "import requests\n\nresponse = requests.post('https://parcelsapp.com/api/v3/shipments/tracking', json={\n 'apiKey': api_key,\n 'language': 'en',\n 'shipments': [{'trackingId': '9400111206213785678901', 'destinationCountry': 'United States'}],\n})\nprint(response.json())"
- lang: PHP
label: PHP
source: "<?php\n$payload = json_encode([\n 'apiKey' => $apiKey,\n 'language' => 'en',\n 'shipments' => [[\n 'trackingId' => '9400111206213785678901',\n 'destinationCountry' => 'United States'\n ]]\n]);\n\n$context = stream_context_create([\n 'http' => [\n 'method' => 'POST',\n 'header' => \"Content-Type: application/json\\r\\n\",\n 'content' => $payload\n ]\n]);\n\n$response = file_get_contents('https://parcelsapp.com/api/v3/shipments/tracking', false, $context);\nprint_r(json_decode($response, true));\n?>"
- lang: curl
label: cURL with webhook
source: "curl -X POST \"https://parcelsapp.com/api/v3/shipments/tracking\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\"apiKey\":\"<YOUR_API_KEY>\",\"language\":\"en\",\"webhookUrl\":\"https://example.com/parcels-webhook\",\"shipments\":[{\"trackingId\":\"9400111206213785678901\",\"destinationCountry\":\"United States\"}]}'"
- lang: JavaScript
label: JavaScript with webhook
source: "const response = await fetch('https://parcelsapp.com/api/v3/shipments/tracking', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n apiKey,\n language: 'en',\n webhookUrl: 'https://example.com/parcels-webhook',\n shipments: [{ trackingId: '9400111206213785678901', destinationCountry: 'United States' }]\n })\n});\n\nconst result = await response.json();\nif (result.done) {\n console.log('Complete from cache', result.shipments);\n} else {\n console.log('Tracking request UUID', result.uuid, 'cached results', result.shipments);\n}"
get:
operationId: readTrackingResults
summary: Read tracking results
description: Polls a tracking request by UUID. Keep polling every few seconds until `done` is `true`. Do not pass a tracking number to this endpoint; use only the UUID returned by `POST /shipments/tracking`.
tags:
- Tracking
parameters:
- name: uuid
in: query
required: true
description: Temporary tracking request UUID returned by create tracking request.
schema:
type: string
example: demo_usps_delivered
- name: apiKey
in: query
required: true
description: API key from the Parcels dashboard. Not required on the Mock API server.
schema:
type: string
example: pk_live_your_api_key
responses:
'200':
description: Tracking result or API error.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/TrackingResult'
- $ref: '#/components/schemas/ErrorResponse'
examples:
complete:
summary: Completed tracking result
value:
uuid: demo_usps_delivered
done: true
shipments:
- trackingId: '9400111206213785678901'
status: delivered
origin: United States
destination: United States
originCode: US
destinationCode: US
states:
- state: Delivered, In/At Mailbox
location: Austin, TX, United States
date: '2026-06-25T18:42:00.000Z'
carrier: 0
services:
- slug: usps
name: USPS
detectedCarrier:
slug: usps
name: USPS
pending:
summary: Still running
value:
uuid: demo_usps_delivered
done: false
shipments: []
missingUuid:
summary: Missing UUID
value:
error: MISSING_UUID
description: No .uuid found
notFound:
summary: Request not found
value:
uuid: expired_uuid
parcels: []
error: NO_REQUEST_FOUND
x-codeSamples:
- lang: curl
label: cURL
source: curl "https://parcelsapp.com/api/v3/shipments/tracking?uuid=<UUID>&apiKey=<YOUR_API_KEY>"
- lang: JavaScript
label: JavaScript
source: 'const response = await fetch(`https://parcelsapp.com/api/v3/shipments/tracking?uuid=${encodeURIComponent(uuid)}&apiKey=${encodeURIComponent(apiKey)}`);
console.log(await response.json());'
- lang: Python
label: Python
source: "import requests\n\nresponse = requests.get('https://parcelsapp.com/api/v3/shipments/tracking', params={\n 'uuid': uuid,\n 'apiKey': api_key,\n})\nprint(response.json())"
- lang: PHP
label: PHP
source: '<?php
$url = ''https://parcelsapp.com/api/v3/shipments/tracking?uuid='' . urlencode($uuid) . ''&apiKey='' . urlencode($apiKey);
$response = file_get_contents($url);
print_r(json_decode($response, true));
?>'
components:
schemas:
Attribute:
type: object
properties:
l:
type: string
description: Attribute label.
example: origin
n:
type: string
description: Optional display name.
example: Weight
val:
type: string
description: Attribute value.
example: United States
code:
type: string
description: Optional code value.
example: US
OutgoingLink:
type: object
properties:
slug:
type: string
example: usps
url:
type: string
format: uri
example: https://tools.usps.com/go/TrackConfirmAction?tLabels=9400111206213785678901
trackingId:
type: string
example: '9400111206213785678901'
method:
type: string
enum:
- GET
- POST
example: GET
Carrier:
type: object
properties:
slug:
type: string
description: Carrier identifier.
example: usps
name:
type: string
description: Carrier display name.
example: USPS
Shipment:
type: object
properties:
trackingId:
type: string
description: Tracking number.
example: '9400111206213785678901'
status:
type: string
description: Current normalized shipment status.
enum:
- transit
- arrived
- pickup
- delivered
- returned
- archive
example: delivered
origin:
type: string
description: Localized origin country.
example: United States
destination:
type: string
description: Localized destination country.
example: United States
originCode:
type: string
description: Two-letter origin country code.
example: US
destinationCode:
type: string
description: Two-letter destination country code.
example: US
states:
type: array
description: Tracking events in reverse chronological order.
items:
$ref: '#/components/schemas/Event'
services:
type: array
description: Carriers queried for this tracking number.
items:
$ref: '#/components/schemas/Carrier'
detectedCarrier:
$ref: '#/components/schemas/Carrier'
detected:
type: array
description: Indexes into `services` where tracking events were found.
items:
type: integer
attributes:
type: array
description: Additional carrier metadata such as origin, destination, weight, or references.
items:
$ref: '#/components/schemas/Attribute'
externalTracking:
type: array
description: Direct carrier tracking links.
items:
$ref: '#/components/schemas/OutgoingLink'
ErrorResponse:
type: object
required:
- error
properties:
error:
type: string
description: Stable error code.
enum:
- MISSING_API_KEY
- INVALID_API_KEY
- UNCONFIRMED_ACCOUNT
- SUBSCRIPTION_NOT_FOUND
- SUBSCRIPTION_INACTIVE
- SUBSCRIPTION_LIMIT_REACHED
- INVALID_SUBSCRIPTION_STATE
- INVALID_PARAMS
- NO_SHIPMENTS
- BUSY
- INVALID_WEBHOOK_URL
- MISSING_UUID
- TIMEDOUT
- NO_REQUEST_FOUND
- SERVER_ERROR
- FORBIDDEN
example: INVALID_API_KEY
description:
type: string
description: Human-readable error details when available.
example: No .apiKey found
uuid:
type: string
description: Tracking request UUID, when relevant.
example: demo_usps_delivered
confirmationUrl:
type: string
format: uri
description: One-time account confirmation URL returned with `UNCONFIRMED_ACCOUNT`.
example: https://parcelsapp.com/api/v3/account/confirm/user%40example.com/0123456789abcdef
confirmationExpiresAt:
type: string
format: date-time
description: Expiration time for `confirmationUrl`.
example: '2026-07-08T12:00:00.000Z'
TrackingResult:
type: object
properties:
uuid:
type: string
description: Temporary tracking request UUID. It can be absent when the create response is fully served from cache and `done` is `true`.
example: demo_usps_delivered
done:
type: boolean
description: True when all shipments in the request have finished tracking.
example: true
fromCache:
type: boolean
description: 'True when the response includes cached tracking data. A create response can include both `uuid` and `fromCache: true` when only part of the request was cached.'
example: true
shipments:
type: array
description: Finished shipment results. On create, this can contain immediately available cached results; use `uuid` or webhooks for any remaining shipments.
items:
$ref: '#/components/schemas/Shipment'
TrackingRequest:
type: object
required:
- apiKey
- shipments
properties:
apiKey:
type: string
description: API key from the Parcels dashboard. Not required on the Mock API server.
example: pk_live_your_api_key
language:
type: string
description: Two-letter language code for localized countries and events. Defaults to `en`.
example: en
shipments:
type: array
minItems: 1
description: Shipments to track.
items:
$ref: '#/components/schemas/TrackingItem'
webhookUrl:
type: string
format: uri
description: Optional public HTTPS endpoint that receives tracking callbacks. In production it must use HTTPS and cannot point to localhost or private networks. Parcels sends `POST` requests with a JSON `WebhookPayload` body.
example: https://example.com/parcels-webhook
TrackingItem:
type: object
required:
- trackingId
properties:
trackingId:
type: string
description: Carrier tracking number.
example: '9400111206213785678901'
destinationCountry:
type: string
description: Full English destination country name. Required for most non-AWB parcel numbers.
example: United States
country:
type: string
description: Alias for `destinationCountry`.
example: United States
zipcode:
type: string
description: Postal code, if a carrier requires it.
example: '78701'
slugs:
type: array
description: Optional carrier slugs to force instead of auto-detection.
items:
type: string
example:
- usps
Event:
type: object
properties:
state:
type: string
description: Human-readable tracking event text.
example: Delivered, In/At Mailbox
location:
type: string
description: Event location.
example: Austin, TX, United States
date:
type: string
format: date-time
description: UTC event timestamp.
example: '2026-06-25T18:42:00.000Z'
carrier:
type: integer
description: Index of the reporting carrier in the `services` array.
example: 0
x-tagGroups:
- name: Guide
tags:
- Account
- Tracking
- Webhooks