# Webhooks

> Get a message on your own URL as soon as a shipment is booked.

`POST https://services.parcelparcel.com/partners-api/v1/hooks/subscribe`

With a webhook we send the details of a shipment to your own URL as soon as it is booked at the carrier, with the tracking number. You don't have to keep asking the API whether something changed.

## Events

| Event | When |
| :--- | :--- |
| `shipment_booked` | A shipment on your account is booked at the carrier and has a tracking number. This includes shipments booked in MyParcelParcel, not only the ones you book through the API. |

Shipments booked with your [sandbox key](https://www.parcelparcel.com/api-docs/authentication/#test-with-your-sandbox-key) are never sent to the carrier, so they don't trigger a webhook. Use the [example payloads](#get-example-payloads) to build and test your receiver.

## Subscribe

Send your URL as `hookUrl`. You get the `id` of the webhook back; keep it if you want to unsubscribe later.

| Name | Value | Required | Comments |
| :--- | :--- | :--- | :--- |
| hookUrl | (string) | true | The URL we send the webhook to, for example `https://example.com/parcelparcel/webhook`. |

### Response

```json
{
  "id": 123
}
```

The status code is `201 Created`.

## Unsubscribe

Send a `DELETE` to `/partners-api/v1/hooks/{id}` with the `id` you got when you subscribed. You get `200 OK` back, or `404 Not Found` when there is no webhook with that id on your account.

## Get example payloads

`GET /partners-api/v1/hooks/examples` returns what we would send: the payloads of up to 5 of your most recent booked shipments, or a fixed example when you haven't booked anything yet. Handy to build your receiver before the first real shipment.

## The payload

We send a `POST` with `Content-Type: application/json` to your URL, once per booked shipment. If your URL is down, we don't try again. Use [List your shipments](https://www.parcelparcel.com/api-docs/list-shipments/) to catch up on anything you missed.

| Name | Value | Comments |
| :--- | :--- | :--- |
| Shipment ID | (number) | The same `id` you got when you [created the shipment](https://www.parcelparcel.com/api-docs/create-shipment/). |
| Pickup date | (object or string) | The pickup date and time, or `"No pickup"` if no pickup was scheduled. |
| Reference | (string) | Your own reference. |
| Pick-up Country | (string) | Country name, for example `Netherlands`. |
| Destination Country | (string) | Country name, for example `United States`. |
| Carrier | (string) | Carrier ID, for example `FEDEX`, `DHL` or `UPS`. |
| Product | (string) | The service, for example `FedEx Economy`. |
| Shipping costs (ex. VAT) | (number) | The price in euros, without VAT. |
| Tracking number | (string) | The carrier's tracking number. |
| Tracking number url | (string) | A link to track the shipment. |
| Import/Export | (string) | `Import` or `Export`. |
| Draft Shipment | (bool) | Always `false` for a booked shipment. |
| Incoterms | (string) | `DAP`, `DDP`, or `-` if none was set. |
| Dimensions | (string) | One line per parcel: length × width × height in cm, weight in kg and the number of parcels, for example `84 X 74 X 10 cm + 9.6 kg (1)`. |
| dutiable | (string) | `yes` if the shipment goes through customs with a proforma invoice, otherwise `no`. |
| description | (string) | The description of the contents. |

### Example payload

```json
{
  "Shipment ID": 1588448,
  "Pickup date": {
    "date": "2026-11-05 12:00:00.000000",
    "timezone_type": 3,
    "timezone": "Europe/Amsterdam"
  },
  "Reference": "#123126",
  "Pick-up Country": "Netherlands",
  "Destination Country": "United States",
  "Carrier": "FEDEX",
  "Product": "FedEx Economy",
  "Shipping costs (ex. VAT)": 86.41,
  "Tracking number": "6516516533",
  "Tracking number url": "https://www.fedex.com/apps/fedextrack/?action=track&trackingnumber=6516516533&cntry_code=nl&locale=nl_NL",
  "Import/Export": "Export",
  "Draft Shipment": false,
  "Incoterms": "DAP",
  "Dimensions": "84 X 74 X 10 cm + 9.6 kg (1)",
  "dutiable": "yes",
  "description": "Awesome Product"
}
```

## Examples

### Request example - Subscribe to booked shipments

```bash cURL
curl --location --request POST 'https://services.parcelparcel.com/partners-api/v1/hooks/subscribe' \
--header 'X-PP-API: {YourAPIKey}@{YourAPISecret}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "hookUrl": "https://example.com/parcelparcel/webhook"
}'
```
```http HTTP
POST /partners-api/v1/hooks/subscribe HTTP/1.1
Host: services.parcelparcel.com
X-PP-API: {YourAPIKey}@{YourAPISecret}
Content-Type: application/json

{
  "hookUrl": "https://example.com/parcelparcel/webhook"
}
```

### Request example - Get example payloads

```bash cURL
curl --location --request GET 'https://services.parcelparcel.com/partners-api/v1/hooks/examples' \
--header 'X-PP-API: {YourAPIKey}@{YourAPISecret}' \
--header 'Content-Type: application/json'
```
```http HTTP
GET /partners-api/v1/hooks/examples HTTP/1.1
Host: services.parcelparcel.com
X-PP-API: {YourAPIKey}@{YourAPISecret}
Content-Type: application/json
```

### Request example - Unsubscribe webhook 123

```bash cURL
curl --location --request DELETE 'https://services.parcelparcel.com/partners-api/v1/hooks/123' \
--header 'X-PP-API: {YourAPIKey}@{YourAPISecret}' \
--header 'Content-Type: application/json'
```
```http HTTP
DELETE /partners-api/v1/hooks/123 HTTP/1.1
Host: services.parcelparcel.com
X-PP-API: {YourAPIKey}@{YourAPISecret}
Content-Type: application/json
```

Questions about webhooks? Email [integrations@italogistics.com](mailto:integrations@italogistics.com).
