{
  "openapi": "3.0.3",
  "info": {
    "title": "Parcels 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": "/api-docs/mock/v3",
      "description": "Mock API"
    },
    {
      "url": "https://parcelsapp.com/api/v3",
      "description": "Live API"
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Subscription usage and account limits"
    },
    {
      "name": "Tracking",
      "description": "Create tracking requests and read results"
    },
    {
      "name": "Webhooks",
      "description": "Callbacks sent to your `webhookUrl` when tracking progresses or completes. Pass `webhookUrl` in `POST /shipments/tracking`; Parcels sends JSON `POST` requests to that URL."
    }
  ],
  "paths": {
    "/account": {
      "get": {
        "operationId": "getAccountUsage",
        "summary": "Check account usage",
        "description": "Returns the current subscription plan, shipment limit, usage counter, and reset date. On the Mock API server this endpoint returns a fixed demo account and does not require `apiKey`.",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "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": "Account information or API error.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AccountInfo"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorResponse"
                    }
                  ]
                },
                "examples": {
                  "success": {
                    "summary": "Account usage",
                    "value": {
                      "plan": "Pro",
                      "limit": 3000,
                      "current": 142,
                      "resetDate": "2026-08-01T00:00:00.000Z"
                    }
                  },
                  "missingApiKey": {
                    "summary": "Missing API key",
                    "value": {
                      "error": "MISSING_API_KEY",
                      "description": "No .apiKey found"
                    }
                  },
                  "invalidApiKey": {
                    "summary": "Invalid API key",
                    "value": {
                      "error": "INVALID_API_KEY"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl \"https://parcelsapp.com/api/v3/account?apiKey=<YOUR_API_KEY>\""
          },
          {
            "lang": "JavaScript",
            "label": "JavaScript",
            "source": "const response = await fetch('https://parcelsapp.com/api/v3/account?apiKey=' + encodeURIComponent(apiKey));\nconsole.log(await response.json());"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.get('https://parcelsapp.com/api/v3/account', params={'apiKey': api_key})\nprint(response.json())"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$response = file_get_contents('https://parcelsapp.com/api/v3/account?apiKey=' . urlencode($apiKey));\nprint_r(json_decode($response, true));\n?>"
          }
        ]
      }
    },
    "/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.\n\nCached results can be returned immediately in the `shipments` array:\n- 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.\n- 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.\n- 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)}`);\nconsole.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\n$url = 'https://parcelsapp.com/api/v3/shipments/tracking?uuid=' . urlencode($uuid) . '&apiKey=' . urlencode($apiKey);\n$response = file_get_contents($url);\nprint_r(json_decode($response, true));\n?>"
          }
        ]
      }
    },
    "/parcels-webhook": {
      "post": {
        "operationId": "receiveTrackingWebhook",
        "summary": "Receive tracking webhook",
        "description": "This is the endpoint that you host, not a Parcels API endpoint. Provide its URL as `webhookUrl` when creating a tracking request.\n\nParcels sends `POST` requests with `Content-Type: application/json`. Return any 2xx response quickly after accepting the payload. Network errors, timeouts, and HTTP 4xx/5xx responses are treated as failed deliveries and may be retried.\n\nTypical flow: create tracking with `webhookUrl`, save the returned `uuid`, then match incoming webhook events by `uuid`. For batches, expect zero or more `shipment_completed` events followed by one `batch_completed` event when all non-cached shipments finish. If the create response included cached shipments, keep those from the create response; webhook payloads cover the newly tracked remainder.",
        "tags": [
          "Webhooks"
        ],
        "servers": [
          {
            "url": "https://example.com",
            "description": "Your application server"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              },
              "examples": {
                "shipmentCompleted": {
                  "summary": "Single shipment completed",
                  "value": {
                    "event": "shipment_completed",
                    "uuid": "demo_mixed_cache",
                    "timestamp": "2026-07-07T06:45:00.000Z",
                    "done": false,
                    "shipment": {
                      "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"
                      }
                    }
                  }
                },
                "batchCompleted": {
                  "summary": "Batch completed",
                  "value": {
                    "event": "batch_completed",
                    "uuid": "demo_mixed_cache",
                    "timestamp": "2026-07-07T06:46:10.000Z",
                    "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
                          },
                          {
                            "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"
                        }
                      }
                    ]
                  }
                },
                "trackingError": {
                  "summary": "Tracking workflow error",
                  "value": {
                    "event": "tracking_error",
                    "uuid": "demo_mixed_cache",
                    "timestamp": "2026-07-07T06:46:10.000Z",
                    "done": true,
                    "error": "TRACKING_ERROR",
                    "message": "Failed to save tracking result for 9400111206213785678901"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Return any 2xx status after accepting the webhook payload. The response body is ignored."
          }
        },
        "x-codeSamples": [
          {
            "lang": "JavaScript",
            "label": "Express",
            "source": "app.post('/parcels-webhook', express.json(), (req, res) => {\n  const event = req.body;\n\n  if (event.event === 'shipment_completed') {\n    console.log('Shipment finished', event.uuid, event.shipment.trackingId);\n  }\n\n  if (event.event === 'batch_completed') {\n    console.log('Batch finished', event.uuid, event.shipments.length);\n  }\n\n  res.sendStatus(204);\n});"
          },
          {
            "lang": "Python",
            "label": "Flask",
            "source": "from flask import Flask, request\n\napp = Flask(__name__)\n\n@app.post('/parcels-webhook')\ndef parcels_webhook():\n    event = request.get_json()\n    if event['event'] == 'shipment_completed':\n        print('Shipment finished', event['uuid'], event['shipment']['trackingId'])\n    if event['event'] == 'batch_completed':\n        print('Batch finished', event['uuid'], len(event.get('shipments', [])))\n    return ('', 204)"
          },
          {
            "lang": "PHP",
            "label": "PHP",
            "source": "<?php\n$event = json_decode(file_get_contents('php://input'), true);\n\nif ($event['event'] === 'shipment_completed') {\n  error_log('Shipment finished ' . $event['uuid'] . ' ' . $event['shipment']['trackingId']);\n}\n\nif ($event['event'] === 'batch_completed') {\n  error_log('Batch finished ' . $event['uuid'] . ' ' . count($event['shipments'] ?? []));\n}\n\nhttp_response_code(204);\n?>"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AccountInfo": {
        "type": "object",
        "required": [
          "plan",
          "limit",
          "current",
          "resetDate"
        ],
        "properties": {
          "plan": {
            "type": "string",
            "description": "Current subscription plan name.",
            "example": "Pro"
          },
          "limit": {
            "type": "integer",
            "description": "Shipment limit for the current period.",
            "example": 3000
          },
          "current": {
            "type": "integer",
            "description": "Shipments already used in the current period.",
            "example": 142
          },
          "resetDate": {
            "type": "string",
            "format": "date-time",
            "description": "UTC date when the usage counter resets.",
            "example": "2026-08-01T00:00:00.000Z"
          }
        }
      },
      "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"
            ]
          }
        }
      },
      "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"
            }
          }
        }
      },
      "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"
            }
          }
        }
      },
      "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
          }
        }
      },
      "Carrier": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Carrier identifier.",
            "example": "usps"
          },
          "name": {
            "type": "string",
            "description": "Carrier display name.",
            "example": "USPS"
          }
        }
      },
      "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"
          }
        }
      },
      "WebhookPayload": {
        "type": "object",
        "description": "JSON body Parcels sends to the `webhookUrl` from `POST /shipments/tracking`. A `shipment_completed` event contains `shipment`; a `batch_completed` event contains `shipments`; a `tracking_error` event contains `error` and `message`.",
        "properties": {
          "event": {
            "type": "string",
            "enum": [
              "shipment_completed",
              "batch_completed",
              "tracking_error"
            ],
            "example": "batch_completed",
            "description": "Webhook event type. `shipment_completed` means one newly tracked shipment finished. `batch_completed` means all newly tracked, non-cached shipments for the UUID finished."
          },
          "uuid": {
            "type": "string",
            "example": "demo_usps_delivered",
            "description": "Tracking request UUID returned by `POST /shipments/tracking`."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "example": "2026-06-25T18:43:00.000Z"
          },
          "done": {
            "type": "boolean",
            "example": true,
            "description": "`true` when the whole tracking request is complete. Individual shipment events usually have `done: false`; the final batch event has `done: true`."
          },
          "shipment": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Shipment"
              }
            ],
            "description": "Present on `shipment_completed`: the finished newly tracked shipment result."
          },
          "shipments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shipment"
            },
            "description": "Present on `batch_completed`: finished results for the newly tracked, non-cached shipments in this UUID. Cached shipments, if any, were already returned in the create response."
          },
          "error": {
            "type": "string",
            "example": "TRACKING_ERROR",
            "description": "Present on `tracking_error`: stable error type."
          },
          "message": {
            "type": "string",
            "example": "Failed to save tracking result",
            "description": "Present on `tracking_error`: human-readable error details."
          }
        }
      },
      "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"
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Guide",
      "tags": [
        "Account",
        "Tracking",
        "Webhooks"
      ]
    }
  ]
}
