> Part of [WHCC Developer Documentation](https://www.whcc.com/developer/llms.txt)

**Legacy** This page is reference for integrations already built on the Order Submit API. It remains supported. New integrations use the [WHCC API](https://www.whcc.com/developer/docs/quick-start/index.html.md).

# Webhook Types

There are two types of webhook to expect, `Status` and `Event`. This page documents the **V2** (JSON) payload format. If your integration receives `application/x-www-form-urlencoded` bodies instead of JSON, you're on the legacy V1 format &mdash; see [V1 Webhook Format](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-v1-format/index.html.md).

> Every notification below can be sent more than once for the same order. Key on **(`ConfirmationId`, `SequenceNumber`, event type)** before acting on a notification &mdash; `ConfirmationId` alone is shared between the halves of a split order &mdash; and treat a repeat as a reconcile rather than a discard, because a later delivery can carry more data than the earlier one. See [Delivery, Retries & Idempotency](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-delivery/index.html.md).

## Identifying fields

Four fields appear on every notification below and together identify what the notification is about:

| Field | Meaning |
| --- | --- |
| `ConfirmationId` | The confirmation the notification belongs to. **Not unique per order** &mdash; when an order is split, the resulting orders share it. |
| `SequenceNumber` | Distinguishes orders that share a `ConfirmationId`. A split produces suffixed values such as `"1"` and `"1.2"`, each with its own `OrderNumber` and its own tracking. |
| `EntryId` | Your own reference for the order, echoed back as submitted. |
| `EventType` | **What happened**, as a single unambiguous name: `order.accepted`, `order.rejected`, `order.shipped` or `order.cancelled`. Always the **last** field in the body. |

### Branch on `EventType`, not on `Event`

`Event` alone does not name the event. An accepted order and a rejected one **both** arrive as `"Event": "Processed"`, and only `Status` separates them &mdash; so any code that switches on `Event` by itself treats a rejection as an acceptance. `EventType` is the single field that tells them apart, and it is the same vocabulary you use to [select events when subscribing](https://www.whcc.com/developer/docs/api/event-subscriptions/#event-types).

| `EventType` | Arrives as |
| --- | --- |
| `order.accepted` | `"Event": "Processed"` with `"Status": "Accepted"` |
| `order.rejected` | `"Event": "Processed"` with `"Status": "Rejected"` |
| `order.shipped` | `"Event": "Shipped"` |
| `order.cancelled` | `"Event": "Order Cancelled"` |

> **`EventType` is always last, and nothing else changed.** Every field before it keeps the same name, value and position it had before the field existed &mdash; nothing was removed, renamed, reordered or reformatted. The body is *not* byte-identical, because the property that used to be last now ends with a comma and the closing brace moved to the end; what is stable is the fields and their values.
>
> ⚠️ **Whether your integration keeps working depends on how it handles unknown fields.** A parser that ignores them is unaffected. A parser configured to reject them fails on *every* version 2 delivery &mdash; and some libraries reject by default, notably Jackson, whose `FAIL_ON_UNKNOWN_PROPERTIES` is on unless you turn it off. Configure yours to ignore unknown fields: more may be added the same way.
>
> **A V1 delivery never carries `EventType`.** The key does not appear at all. V1 has its own `EventId` field, and it is a *different* vocabulary &mdash; `order.received` there means `order.accepted` here. Do not match the two on the strength of them both having a dot in them. See [V1 Webhook Format](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-v1-format/index.html.md).

## Status

The status webhook lets you know if your order has been completely accepted or rejected. It is possible for an order to be rejected if there is an issue accessing the image assets included in the order request JSON.

### Accepted Example

```json
{
	"Status": "Accepted",
	"Errors": [],
	"OrderNumber": 99000341,
	"Event": "Processed",
	"ConfirmationId": "f245d035-0c0d-446c-81f4-dbe1e2802801",
	"EntryId": "1687452093",
	"Reference": "1298447712",
	"SequenceNumber": "0",
	"EventType": "order.accepted"
}
```

### Rejected Example

A rejected order has no `OrderNumber`, since one was never assigned.

```json
{
	"Status": "Rejected",
	"Errors": [{
		"ErrorCode": "400.01",
		"Error": "Image hash value doesn't match, order canceled.",
		"AssetPath": "https://images.example-partner.com/27aa22c4-4cf4-44c8-b80a-ad1f80540443.jpg"
	}],
	"Event": "Processed",
	"ConfirmationId": "da99f6f0-2ba7-4bee-a348-8f5ba59fed77",
	"EntryId": "c2496f39-849d-4017-a9bf-a43c646b7f88",
	"Reference": "EP-Q-c2496f39",
	"SequenceNumber": "1",
	"EventType": "order.rejected"
}
```

See [Errors](https://www.whcc.com/developer/docs/legacy/order-submit-api/errors/index.html.md) for the full list of `ErrorCode` values.

## Event

The event webhook lets you know about a change in production status of your order. The `Event` field tells you which one you received: `Shipped` or `Order Cancelled`. Look for a specific event value when processing this webhook type &mdash; more may be added in the future.

### Shipped

Sent when an order (or part of an order) ships. `ShippingInfo` is an array of tracking entries. A multi-package order can arrive either way: as a single `Shipped` webhook whose `ShippingInfo` array holds several entries, or as several separate `Shipped` webhooks, one per package. Expect **one or more `Shipped` webhooks per order**, and process every entry in `ShippingInfo` &mdash; each webhook carries the complete tracking list known at the moment it was sent. That list **grows**: a second `Shipped` webhook with the same key, sent moments later, routinely carries additional tracking numbers as more packages are scanned. Merge `ShippingInfo` on repeat rather than discarding it, as described in [Delivery, Retries & Idempotency](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-delivery/index.html.md).

```json
{
	"ShippingInfo": [{
		"Carrier": "FedEx",
		"ShipDate": "2026-05-08T16:59:59-05:00",
		"TrackingNumber": "9261200011223344556677",
		"TrackingUrl": "https://www.fedex.com/fedextrack/?trknbr=9261200011223344556677",
		"Weight": 1.0
	}],
	"OrderNumber": 99000918,
	"Event": "Shipped",
	"ConfirmationId": "a501c238-e91d-4766-853e-598dc6851338",
	"EntryId": "prspctr-Zq8mWkTn3XcRpLFB6-301488-1",
	"Reference": "ETSY_COM:5183660044-198372640551",
	"SequenceNumber": "1",
	"EventType": "order.shipped"
}
```

> `Weight` is a float. Whole-pound shipments are still serialized with a decimal, e.g. `1.0`, not `1`.

### Order Cancelled

Sent when an order is canceled. V2 integrations only &mdash; V1 integrations never receive this event.

```json
{
	"Event": "Order Cancelled",
	"OrderNumber": 99000201,
	"ConfirmationId": "f7889680-3aed-4dad-8942-090f6b3ce979",
	"EntryId": "prspctr-Xk2mQTn7YRbLpEFA9-452193-1",
	"Reference": "#1005-8091234567890",
	"SequenceNumber": "1",
	"EventType": "order.cancelled"
}
```

> ## What's Next
>
> [Delivery, Retries & Idempotency](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-delivery/index.html.md) covers the retry schedule, timeout, and why you must deduplicate.
>
> [Security and Signatures](https://www.whcc.com/developer/docs/legacy/order-submit-api/webhook-security/index.html.md) describes the process to validate the callback requests