> ## Documentation Index
> Fetch the complete documentation index at: https://docs.primefreight.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Receive a signed callback when a tracked shipment or container changes.

Register an HTTPS endpoint and PrimeFreight posts a JSON notification whenever a tracked shipment or container has a significant change. Webhooks fire on the same changes that appear in the event timeline, so the two stay consistent.

## Event types

| Event                              | Fires when                                                 |
| ---------------------------------- | ---------------------------------------------------------- |
| `shipment.status_changed`          | The shipment's journey status moves to a new value         |
| `shipment.customs_status_changed`  | The customs status changes                                 |
| `shipment.delivery_status_changed` | The delivery status changes                                |
| `shipment.eta_changed`             | The revised ETA at destination moves by more than 24 hours |
| `container.hold_changed`           | A customs, line, or other hold is placed or released       |
| `container.last_free_day_changed`  | A last free day is set or changes                          |
| `container.milestone_recorded`     | An operational milestone date is set for the first time    |

<Note>
  You'll only be notified once a change has settled, so you won't receive intermediate carrier location updates, corrections, or reversals — just the confirmed new value.
</Note>

## Payload

| Field                   | Type   | Description                                                         |
| ----------------------- | ------ | ------------------------------------------------------------------- |
| `id`                    | string | Unique delivery ID. Deduplicate on this — delivery is at-least-once |
| `type`                  | string | The event type from the table above                                 |
| `created_at`            | string | When the change was recorded (ISO 8601). Order events by this field |
| `data.shipment_id`      | string | Affected shipment                                                   |
| `data.file_number`      | string | Shipment file number                                                |
| `data.container_id`     | string | Affected container                                                  |
| `data.container_number` | string | Container number                                                    |
| `data.field`            | string | The field that changed                                              |
| `data.previous`         | string | Value before the change                                             |
| `data.current`          | string | Value after the change                                              |

<ResponseExample>
  ```json shipment.status_changed theme={null}
  {
    "id": "whn_9f31c2",
    "type": "shipment.status_changed",
    "created_at": "2026-07-09T05:39:36-04:00",
    "data": {
      "shipment_id": "shp_100001",
      "file_number": "R00001",
      "container_id": "cnt_100001",
      "container_number": "ABCU1234567",
      "field": "status",
      "previous": "Arrived Not Yet Discharged",
      "current": "Departed Discharge Terminal"
    }
  }
  ```
</ResponseExample>

## Delivery and security

| Aspect    | Behavior                                                             |
| --------- | -------------------------------------------------------------------- |
| Method    | `POST` to your registered HTTPS URL                                  |
| Success   | Respond `2xx` within 10 seconds                                      |
| Retries   | Up to 6 attempts with exponential backoff over \~24 hours            |
| Guarantee | At-least-once — deduplicate on `id`                                  |
| Ordering  | Order by `created_at`, not receipt time                              |
| Signature | HMAC-SHA256 of the raw body in the `X-PrimeFreight-Signature` header |

<Info>
  Verify every request by recomputing the HMAC-SHA256 of the raw request body with your signing secret and comparing it to `X-PrimeFreight-Signature`. Reject the request if they don't match.
</Info>
