# Shipment events

Source: https://gokarla.io/docs/platform/events/shipments

# Shipment events

Shipment events are generated by carrier scans as a parcel moves through its
lifecycle, plus any custom events you emit yourself. Use the catalogue below
to find the event you care about, then wire the **event group** into your
notification flow.

## Key concepts

Four fields describe every shipment event. Understanding how they relate is
the fastest way to wire notifications correctly.

| Field         | What it is                                                                       | Example                        |
| ------------- | -------------------------------------------------------------------------------- | ------------------------------ |
| `event_name`  | The specific carrier scan. One per physical checkpoint; ~80 distinct values.     | `DEPARTURE_FROM_TRANSPORT_HUB` |
| `phase`       | The lifecycle stage the parcel is in. ~10 values; think of it as a progress bar. | `in_transit`                   |
| `event_group` | The notification bucket. This is what fires your Klaviyo/webhook/email flow.     | `shipment_in_transit`          |
| `direction`   | Whether the parcel is going to the customer or back to the merchant.             | `merchant_customer`            |

**How they combine**: one `event_name` always maps to exactly one `phase` and
(when notifying) to one `event_group`. The same `event_name` can belong to
different `event_group`s depending on `direction` — see below.

**Ref pattern**: `shipments/{phase}/{event_name}` — e.g.
`shipments/delivered/SUCCESSFULLY_DELIVERED`.

:::tip Wire notifications to groups, not names
Filter on `event_group` when subscribing to webhooks or building Klaviyo
flows — there are ~20 groups vs ~80 event names, and the groups already
bundle events that should trigger the same customer message.
:::

### Forward vs return direction

Every shipment has a `direction`:

- **`merchant_customer`** (forward) — the default; merchant ships to customer.
  Groups prefixed `shipment_*` apply.
- **`customer_merchant`** (return) — customer ships back to merchant. Karla
  collapses the forward groups into 5 `return_shipment_*` buckets so you can
  wire a separate template for _"your return is on its way"_ vs _"your order
  is on its way"_.

The underlying carrier events (`OUT_FOR_DELIVERY`, `SUCCESSFULLY_DELIVERED`,
etc.) are identical — only the group assignment differs.

:::info Draft vs fulfilled

- **Draft shipments** (no tracking number yet) only notify on
  `ORDER_PROCESSED` and `ORDER_CANCELLED`.
- **Fulfilled shipments** (tracking number attached) generate the full set
  of carrier tracking events below.
  :::

## Event catalogue

Browse every shipment event Karla emits. Toggle **Forward / Return** to
switch direction, and **By group / By event** to pivot between notification
buckets and individual event names. Use search to filter by any text.

<KarlaEventsDisplay />

## Shipment Events API

You can programmatically trigger events on shipments via the
[API reference](/docs/api-reference). This is useful for:

- Firing notification flows or webhooks for **draft shipments** that don't
  yet have carrier tracking.
- Injecting state from a logistics partner that doesn't integrate with
  Karla.
- Recording internal QA or pre-handoff milestones.

### Lookup by order number

```bash
curl -X POST "https://api.gokarla.io/v1/shop/{slug}/shipment-events?notify=true" \
  -u your-username:your-private-api-key \
  -H "Content-Type: application/json" \
  -d '{
    "id": "1001",
    "id_type": "order_number",
    "event_name": "ORDER_PROCESSED"
  }'
```

### Lookup by external order ID

```bash
curl -X POST "https://api.gokarla.io/v1/shop/{slug}/shipment-events?notify=true" \
  -u your-username:your-private-api-key \
  -H "Content-Type: application/json" \
  -d '{
    "id": "5512345678901",
    "id_type": "external_order_id",
    "event_name": "SUCCESSFULLY_DELIVERED"
  }'
```

:::warning Single-shipment orders only
When using `order_number` or `external_order_id` as `id_type`, the order
must have exactly one shipment. For multi-shipment orders, identify the
specific shipment via `shipment_uuid` or `tracking_number` instead.
:::

The `notify=true` query parameter triggers the event group notification
(webhook, email flow, etc.). Without it, the event is recorded silently.

## `event_data` shape

Variables inside `event_data` are what Karla exposes to native integration
templates (Klaviyo, Emarsys, Brevo, Braze, HubSpot, etc.) unless documented
otherwise.

```jsx title="Shipment event_data"
{
  ...
  "event_data": {
    "shipment_id": "abc65a96-0871-452a-a506-c644e2012123",
    "carrier_reference": "dhl",
    "event_name": "DEPARTURE_FROM_TRANSPORT_HUB",
    "phase": "in_transit",
    "tracking_number": "0123456789",
    "tracking_url": "https://example.com/tracking",
    "updated_at": "2024-01-29T14:48:47+00:00",
    "event_group": "shipment_in_transit",
    "order_number": "ORD-2024-001",

    // Optional fields present depending on event type or shop-provided data
    "order_name": "ORD-2024-001",
    "zip_code": "10115",
    "shipping_address": "123 Main St, Berlin, 10115, Germany",
    "total_order_value": 49.99,
    "order_currency": "EUR",
    "order_status_url": "https://shop.example.com/orders/status/123",
    "external_customer_id": "CUST-98765",
    "external_order_id": "shopify-order-123",
    "preferred_delivery_date": "15.01.2024",
    "customer_first_name": "John",
    "customer_last_name": "Doe",
    "customer_country": "Germany",

    // Optional fields for specific event groups
    "expected_delivery_date": "20.01.2024",
    "pick_up_address": "Parcel Shop, 456 Store St, Berlin",
    "pick_up_until": "25.01.2024",
    "neighbour_name": "Jane Smith",
    "requested_delivery_date": "30.01.2024",

    // Optional fields for multi-shipment orders (IN_TRANSIT events)
    "number_of_shipments": 3,
    "other_tracking_numbers": ["1234567890", "0987654321"]
  }
  ...
}
```

## Full payload example

A real shipment event as you'd receive it via webhook, including the
`context` block with the full order, customer, and shipment data:

```ts
{
  "source": "shipments",
  "ref": "shipments/in_transit/DEPARTURE_FROM_TRANSPORT_HUB",
  "version": 1,
  "triggered_at": "2024-01-29T14:48:47+00:00",
  "event_group": "shipment_in_transit",
  "event_data": {
    "shipment_id": "6be0ea64-fe5e-478e-aee5-f9f7bbc53804",
    "carrier_reference": "dhl",
    "event_name": "DEPARTURE_FROM_TRANSPORT_HUB",
    "phase": "in_transit",
    "tracking_number": "0123456789",
    "tracking_url": "https://example.com/tracking",
    "updated_at": "2024-01-29T14:48:47+00:00",
    "event_group": "shipment_in_transit"
  },
  "context": {
    "order": {
      "order_number": "0000001",
      "order_name": null,
      "order_placed_at": "2025-06-18T22:00:04.264555+00:00",
      "total_order_price": 123.456,
      "shipping_price": 4.99,
      "sub_total_price": 118.457,
      "discount_price": 30,
      "products": [
        {
          "title": "Delivery socks",
          "quantity": 2,
          "price": 1,
          "size": "S",
          "images": [
            {
              "src": "https://storage.googleapis.com/karla-merchants-metadata/gokarla/Karla_SINGLE_PRODUCT.png",
              "alt": "Delivery socks"
            }
          ],
          "sku": null,
          "weight": null,
          "tax_lines": [],
          "bundled_products": [],
          "shipment_id": null,
          "type": "product"
        }
      ],
      "discounts": [],
      "email_id": null,
      "address": {
        "address_line_1": "Gormannstr.",
        "address_line_2": "19a",
        "city": "Berlin",
        "country": "Germany",
        "country_code": null,
        "name": "John Doe",
        "phone": "123456789",
        "province": "Berlin",
        "province_code": null,
        "street": "Gormannstr. 19a",
        "zip_code": "01234",
        "company": null
      },
      "currency": "EUR",
      "segments": null,
      "weight": null,
      "external_customer_id": null,
      "order_status_url": null
    },
    "customer": {
      "external_id": null,
      "email": null,
      "first_name": null,
      "last_name": null,
      "full_name": "John Doe",
      "phone": "123456789"
    },
    "shipments": [
      {
        "uuid": "6be0ea64-fe5e-478e-aee5-f9f7bbc53804",
        "updated_at": "2024-01-29T14:48:47+00:00",
        "events": [
          {
            "event_key": "E23",
            "time": "2023-10-08T13:50:40+00:00",
            "timezone": "UTC",
            "location": null,
            "additional_info": null,
            "phase": "in_transit",
            "event_name": "DEPARTURE_FROM_TRANSPORT_HUB",
            "event_strings": {
              "event_status": "Moving on! Your parcel has left the transport hub.",
              "list_label": "Arriving 25.09",
              "header_headline": "IN TRANSIT",
              "header_title": "25.09",
              "header_subtitle": ""
            },
            "language": "en"
          },
          {
            "event_key": "A12",
            "time": "2023-10-07T12:01:10+00:00",
            "timezone": "UTC",
            "location": null,
            "additional_info": null,
            "phase": "order_processed",
            "event_name": "ORDER_PROCESSED",
            "event_strings": {
              "event_status": "Your parcel has been packed and is ready to be shipped.",
              "list_label": "packed",
              "header_headline": "PACKED",
              "header_title": "Your parcel has been packed",
              "header_subtitle": ""
            },
            "language": "en"
          },
          {
            "event_key": "A10",
            "time": "2023-10-06T18:58:15+00:00",
            "timezone": "UTC",
            "location": null,
            "additional_info": null,
            "phase": "order_created",
            "event_name": "ORDER_CREATED",
            "event_strings": {
              "event_status": "You've placed an online order.",
              "list_label": "Order placed",
              "header_headline": "ORDER PLACED",
              "header_title": "Thanks for shopping!",
              "header_subtitle": ""
            },
            "language": "en"
          }
        ],
        "estimated_arrival": {
          "start": "2023-09-23T12:00:00+00:00",
          "end": "2023-09-25T12:00:00+00:00",
          "time_prediction": "25.09",
          "language": "en"
        },
        "carrier": {
          "tracking_number": "0123456789",
          "carrier_reference": "dhl",
          "tracking_url": null
        },
        "flag": "normal",
        "pickup": null,
        "products": [
          {
            "title": "Delivery socks",
            "quantity": 2,
            "price": 1,
            "size": "S",
            "images": [
              {
                "src": "https://storage.googleapis.com/karla-merchants-metadata/gokarla/Karla_SINGLE_PRODUCT.png",
                "alt": "Delivery socks"
              }
            ],
            "sku": null,
            "weight": null,
            "tax_lines": [],
            "bundled_products": []
          }
        ]
      }
    ],
    "claims": []
  },
  "shop_slug": "gokarla",
  "shop_id": "7af5390b-1425-4af6-a00d-e5f5184a7b51"
}
```

## Related

- [Events overview](/docs/platform/events/overview) — hierarchy,
  envelope, and filtering syntax.
- [Claim events](/docs/platform/events/claims) — Resolve-side
  events.
- [Shipments](/docs/platform/shipments) — entity, state machine,
  and phases.
- [Webhooks](/docs/guides/notify/webhooks) — subscribe to shipment events.
- [Notify integrations](/docs/guides/notify/disable-carrier-emails) — wire
  events into Klaviyo, Brevo, HubSpot, etc.
