Webhooks

Register webhook (billable)

Register a webhook for parcel tracking. Supports 2 modes:

  • recurring: true — Continuous monitoring until delivery (subscription). Recommended for most integrations. Register once and receive push notifications whenever the tracking status changes. Ideal for keeping your database in sync with delivery progress.
  • recurring: false — Query once only (one-time, default). Useful for one-off lookups where you don't need ongoing updates.

Why use webhooks? Polling /v2/track repeatedly wastes your request quota. A single parcel typically has 5–10 status changes over its lifecycle. With webhooks, you receive only those 5–10 updates instead of making hundreds of polling requests.

Billable API, supports up to 100 items per registration.

What we POST to your endpoint. Content-Type is application/json; we expect a 2xx response within 10 seconds. Redirects are not followed.

{
  "event": "tracking.updated",
  "timestamp": "2026-08-21T04:15:22.184Z",
  "data": {
    "requestId": "req_abc123",
    "timestamp": "2026-08-21T04:15:22.100Z",
    "trackingItems": [
      {
        "carrier": { "code": "us.usps", "name": "USPS", "country": "US" },
        "trackingNumber": "9400111206206406260787",
        "status": "success",
        "currentStatus": "in_transit",
        "hasChange": true,
        "trackingData": { "deliveryStatus": "in_transit", "events": [] }
      }
    ],
    "isPeriodicUpdate": true,
    "hasChanges": true,
    "changedItemCount": 1,
    "queriedItemCount": 1,
    "deliveredItemCount": 0,
    "changeId": "chg_xyz789"
  }
}

Fields:

eventtracking.registered on the first lookup after you register, tracking.updated on every later poll.

data.requestId — the subscription id returned by this endpoint.

data.trackingItems[] — one entry per tracked parcel. carrier is an object (code, name, country), not a string. status is success or error. currentStatus is the standardized delivery status. trackingData holds the full result. hasChange marks items whose status changed in this cycle.

data.isPeriodicUpdate, hasChanges, changedItemCount, queriedItemCount, deliveredItemCount, changeId — present only on recurring updates, not on the first tracking.registered delivery.

Headers: X-WhereParcel-Event, X-WhereParcel-Timestamp, and X-WhereParcel-Signature — an HMAC-SHA256 hex digest of the exact raw JSON body, keyed with your endpoint secret. Verify it by recomputing the digest over the raw body before parsing.

If you register without webhookEndpointId, nothing is pushed to you. That is the pull mode: retrieve results with GET /v2/webhooks/subscriptions/{requestId} or POST /v2/webhooks/results. To receive the payload above, create an endpoint with POST /v2/webhook-endpoints and pass its id as webhookEndpointId.

post/v2/webhooks/register

Request body

recurringboolean

Tracking mode (optional, default: false)

  • false: Query once only (default, safe) → webhookEndpointId optional
  • true: Continuous monitoring (explicit request required) → webhookEndpointId required
webhookEndpointIdstring

Pre-registered Webhook Endpoint ID

  • Required when recurring: true (validated by middleware)
  • Optional when recurring: false
  • If provided, sends POST on completion; if omitted, no notification sent
  • Must register a Webhook Endpoint first

Response

Webhook registered successfully

OR

Changes