Machine Readiness
Stored receipt and evidence
14
45
0
0
0
Samples
No stored offer samples.
Samples
No stored action samples.
Samples
No stored product samples.
Document
Not stored for this site.
Document
# Parcels API
Track any package and shipment worldwide.
Base URL: https://parcelsapp.com/api/v3
Authentication: Pass `apiKey` as a body field (POST) or query parameter (GET).
Get your API key at: https://parcelsapp.com/dashboard
---
## How Tracking Works (Two-Step Flow)
Tracking is asynchronous. You must:
1. POST to create a tracking request → receive a `uuid`
2. GET with that `uuid` repeatedly until `done: true`
Do NOT supply the tracking number to the GET endpoint. Only use `uuid`.
UUIDs expire after 30 minutes.
If you POST a tracking number that is already being tracked, the API returns the existing request's UUID.
---
## Endpoints
### POST /shipments/tracking - Create Tracking Request
Creates a new tracking request. May return cached results immediately (fromCache: true).
Request body (JSON):
apiKey (string, required) - Your API key
shipments (array, required) - List of shipments to track (see Shipment Input below)
language (string, optional) - 2-letter ISO language code, e.g. "en", "de"
webhookUrl (string, optional) - HTTPS URL to receive a POST callback when tracking completes
Shipment Input object fields:
trackingId (string, required) - The tracking number
destinationCountry (string, optional) - Full English country name, e.g. "United States", "Germany"
zipcode (string, optional) - Postal code, required by some carriers
slugs (array, optional) - Carrier slugs to force-use instead of auto-detection
Response:
{
"uuid": "abc123",
"done": false,
"shipments": []
}
If results are cached, `done` may be true and `shipments` will be populated immediately.
---
### GET /shipments/tracking - Read Tracking Results
Poll this endpoint after creating a tracking request. Repeat every few seconds until done is true.
Query parameters:
uuid (required) - UUID returned from the POST call
apiKey (required) - Your API key
Response:
{
"uuid": "abc123",
"done": true,
"shipments": [ ... ]
}
When done is false, some shipments may still be tracking. Keep polling.
When done is true, all shipments have finished tracking.
---
### GET /account - Get Account Information
Returns subscription plan details and current usage.
Query parameters:
apiKey (required) - Your API key
Response:
{
"plan": "Pro",
"limit": 300,
"current": 142,
"resetDate": "2025-12-04T10:30:00.000Z"
}
Fields:
plan - Subscription plan name
limit - Max shipments allowed per billing period
current - Shipments tracked so far this period
resetDate - When the counter resets (UTC ISO 8601)
Error responses:
{ "error": "MISSING_API_KEY", "description": "No .apiKey found" }
{ "error": "INVALID_API_KEY" }
---
## Response Data Structures
### Shipment object (items in the `shipments` array)
trackingId - Tracking number
status - One of: transit | arrived | pickup | delivered | archive
origin - Origin country name (localized to requested language)
destination - Destination country name (localized)
originCode - Origin country 2-letter ISO code
destinationCode - Destination country 2-letter ISO code
states - Array of tracking events (see Event below)
services - Array of all carriers queried (see Carrier below)
detectedCarrier - Main carrier with the most events (see Carrier below)
detected - Array of indexes into `services` where events were found
attributes - Extra metadata: weight, dimensions, etc. (see Attribute below)
externalTracking - Direct tracking links per carrier (see OutgoingLink below)
### Event object (items in `states`)
state - Human-readable event description
location - Where the event occurred
date - ISO 8601 datetime in UTC
carrier - Index into `services` array indicating which carrier reported this event
### Carrier object
slug - Carrier identifier (e.g. "usps", "dhl", "fedex")
name - Carrier display name
### Attribute object
n - Attribute title/name
l - Attribute label
val - Attribute value (string)
### OutgoingLink object
slug - Carrier slug
url - Direct tracking URL on the carrier's website
trackingId - Tracking number used for this carrier
method - HTTP method: GET or POST
---
## Shipment Status Values
transit - Package is in transit between locations
arrived - Package arrived in the destination country
pickup - Package is ready for pickup at a location
delivered - Package was delivered to the recipient
archive - Old or inactive tracking, no recent updates
---
## Webhooks
Pass webhookUrl in the POST body to receive a callback instead of polling.
The webhook receives the same JSON payload as the GET polling response.
The webhook fires once when tracking is complete (done: true).
For local testing: webhook.site, ngrok, localtunnel, or Cloudflare Tunnel.
---
## Code Examples
### Python - full polling loop
import requests, time
API_KEY = "your_api_key"
URL = "https://parcelsapp.com/api/v3/shipments/tracking"
# Step 1: Create tracking request
resp = requests.post(URL, json={
"apiKey": API_KEY,
"language": "en",
"shipments": [
{"trackingId": "EE10021942088880001030003D0N", "destinationCountry": "Canada"}
]
})
uuid = resp.json()["uuid"]
# Step 2: Poll until done
while True:
resp = requests.get(URL, params={"apiKey": API_KEY, "uuid": uuid})
data = resp.json()
if data["done"]:
print(data["shipments"])
break
time.sleep(3)
### Node.js - full polling loop
const axios = require('axios');
const API_KEY = 'your_api_key';
const URL = 'https://parcelsapp.com/api/v3/shipments/tracking';
const { data: { uuid } } = await axios.post(URL, {
apiKey: API_KEY,
language: 'en',
shipments: [{ trackingId: 'EE10021942088880001030003D0N', destinationCountry: 'Canada' }]
});
const poll = async () => {
const { data } = await axios.get(URL, { params: { apiKey: API_KEY, uuid } });
if (data.done) return data.shipments;
await new Promise(r => setTimeout(r, 3000));
return poll();
};
const shipments = await poll();
console.log(shipments);
### cURL
# Step 1 - create tracking request
curl -X POST https://parcelsapp.com/api/v3/shipments/tracking \
-H 'Content-Type: application/json' \
-d '{"apiKey":"<KEY>","language":"en","shipments":[{"trackingId":"EE10021942088880001030003D0N","destinationCountry":"Canada"}]}'
# Step 2 - poll for results (replace UUID)
curl "https://parcelsapp.com/api/v3/shipments/tracking?apiKey=<KEY>&uuid=<UUID>"
### Node.js - webhook approach
const axios = require('axios');
axios.post('https://parcelsapp.com/api/v3/shipments/tracking', {
apiKey: 'your_api_key',
language: 'en',
webhookUrl: 'https://your-domain.com/webhook',
shipments: [{ trackingId: 'EE10021942088880001030003D0N', destinationCountry: 'Canada' }]
});
// Your webhook endpoint receives the full result payload when done:
// POST https://your-domain.com/webhook
// Body: { uuid, done: true, shipments: [ ... ] }
---
## Key Rules to Remember
1. Always create a tracking request (POST) before reading results (GET).
2. Poll GET every 2-5 seconds; stop when done is true.
3. Do not pass the tracking number to GET - only the uuid.
4. UUIDs are temporary and expire after 30 minutes.
5. destinationCountry is the full English country name, not a 2-letter code.
6. Multiple tracking numbers can be submitted in one request via the shipments array.
7. Use the slugs field to force a specific carrier if auto-detection picks the wrong one.
8. The carrier field inside each Event is an array index into services, not a carrier name.
Document
Not stored for this site.