# Universal Parcel Tracking - Global Package Tracking

> Markdown mirror of DialtoneApp's public top-site detail page for `parcelsapp.com`.

URL: https://dialtoneapp.com/top-sites/parcelsapp.com/index.md
Canonical HTML: https://dialtoneapp.com/top-sites/parcelsapp.com

## Summary

- Domain: `parcelsapp.com`
- Website: https://parcelsapp.com
- Description: ai readable | score 14 | purchase read only
- Label: ai_readable
- Payment surface: Not available
- Purchase boundary: read_only
- Control boundary: unknown
- Rank: 18052

## robots

Not found.

## llms

~~~text
# 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.
~~~

## llms-full

Not found.