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

# Webhook Event Types: Real-Time Gift Lifecycle

> Reference for Snappy webhook events - gift claimed, order fulfilled, address validated, and more. Payload examples included.

## Event Structure

Every payload received at your endpoint follows this standard structure:

| **Field**     | **Type** | **Description**                                                                  |
| :------------ | :------- | :------------------------------------------------------------------------------- |
| `webhookData` | Object   | Metadata about the webhook delivery (ID, type, timestamp).                       |
| `eventData`   | Object   | The core payload containing entity-specific information (Gift ID, Status, etc.). |

<Tip>
  Use these example payloads to build and test your webhook listener locally before receiving real events. Tools like [Ngrok](https://ngrok.com) or [Webhook.site](http://Webhook.site) let you simulate incoming webhook calls by sending these payloads directly to your local endpoint - no real gift sends required.
</Tip>

***

## Webhooks and Events Types

Snappy currently supports the following:

### Gift Status Events

These events track the core lifecycle of a gift.

| **Event Name**        | **Description**                                                         |
| :-------------------- | :---------------------------------------------------------------------- |
| `gift-status-changed` | Triggered whenever a gift moves to a new stage in the recipient journey |

**Optional statuses:**

| **Status**  | **Description**                                                             |
| :---------- | :-------------------------------------------------------------------------- |
| `unopened`  | The gift has been sent but the recipient has not clicked the link.          |
| `unwrapped` | The recipient has clicked the link but has not yet viewed the gift options. |
| `opened`    | The recipient has viewed the available gift options.                        |
| `claimed`   | The recipient has selected a gift and provided their details.               |
| `expired`   | The gift reached its expiration date without being claimed.                 |

**Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "gift-status-changed",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-15T14:44:00Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "giftId": "gft_12345",
    "status": "claimed",
    "metadata": {
      "internalReferenceId": "REF-ABC-123"
    }
  }
}
```

***

### Order Lifecycle Events

These events expose the order behind a claimed gift using the **v3 Orders** vocabulary. Use them when you integrate at the order level rather than the recipient-facing gift level.

| **Event Name**                  | **Description**                                                      |
| :------------------------------ | :------------------------------------------------------------------- |
| `order-status-changed`          | Triggered when an order's status changes (e.g. placed or cancelled). |
| `order-delivery-status-changed` | Triggered as an order moves through the full delivery lifecycle.     |

**`order-status-changed` statuses:**

| **Field**           | **Values**                 |
| :------------------ | :------------------------- |
| `status`            | `active`, `cancelled`      |
| `fulfillmentStatus` | `unfulfilled`, `cancelled` |

**`order-delivery-status-changed` statuses:**

| **Delivery Status** | **Description**                             |
| :------------------ | :------------------------------------------ |
| `confirmed`         | The fulfillment request has been received.  |
| `processing`        | The item is being prepared for shipment.    |
| `in_transit`        | The item has been picked up by the carrier. |
| `out_for_delivery`  | The item is expected to be delivered today. |
| `delivered`         | The item has reached its final destination. |

<Note>
  Order delivery statuses use the public v3 `snake_case` vocabulary, whereas the `gift-delivery-status-changed` event (under **Delivery & Fulfillment Events**) reports the recipient-facing `camelCase` milestones.
</Note>

**`order-status-changed` Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "order-status-changed",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-16T12:50:40.313Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "orderId": "ord_12345",
    "status": "active",
    "fulfillmentStatus": "unfulfilled",
    "metadata": {
      "internalReferenceId": "REF-ABC-123"
    }
  }
}
```

**`order-delivery-status-changed` Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "order-delivery-status-changed",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-16T12:50:40.313Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "orderId": "ord_12345",
    "deliveryStatus": "out_for_delivery",
    "triggerEvent": "updated",
    "outForDeliveryDate": "2025-01-16T08:00:00.000Z",
    "estimatedDeliveryDate": "2025-01-17T00:00:00.000Z"
  }
}
```

***

### Delivery & Fulfillment Events

These events track the physical movement of a gift after it has been claimed.

| **Event Name**                 | **Description**                                                    |
| :----------------------------- | :----------------------------------------------------------------- |
| `gift-delivery-status-changed` | Triggered as the gift moves through the physical shipping process. |

**Delivery statuses:**

| **Delivery Status** | **Description**                             |
| :------------------ | :------------------------------------------ |
| `inTransit`         | The item has been picked up by the carrier. |
| `outForDelivery`    | The item is expected to be delivered today. |
| `delivered`         | The item has reached its final destination. |

<Note>
  This event only fires for the `inTransit`, `outForDelivery`, and `delivered` milestones. For the full order-level delivery lifecycle (including `confirmed` and `processing`), use the `order-delivery-status-changed` event under **Order Lifecycle Events** instead.
</Note>

**Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "gift-delivery-status-changed",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-16T12:50:40.313Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "giftId": "gft_12345",
    "deliveryStatus": "outForDelivery",
    "triggerEvent": "updated",
    "outForDeliveryDate": "2025-01-16T08:00:00.000Z",
    "estimatedDeliveryDate": "2025-01-17T00:00:00.000Z"
  }
}
```

<Note>
  `deliveredAt` is included when `deliveryStatus` is `delivered`; `outForDeliveryDate` when `outForDelivery`. `triggerEvent` is `created` for the first tracking update and `updated` for subsequent ones.
</Note>

***

### Recipient Notification Events

Use these events to track the communications Snappy sends to your recipients.

| **Event Name**                 | **Description**                                                           |
| :----------------------------- | :------------------------------------------------------------------------ |
| `gift-notification-initial`    | The first gift notification was sent.                                     |
| `gift-notification-reminder`   | An automated reminder was sent to a recipient who hasn't claimed yet.     |
| `gift-notification-resend`     | A notification was manually resent via the dashboard or API.              |
| `gift-notification-expiration` | The final "last chance" notification was sent before the gift expiration. |

**Event Data fields:**

| **Field**        | **Type** | **Notes**                                                                                                                      |
| :--------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `companyId`      | string   | The company that owns the gift.                                                                                                |
| `giftId`         | string   | The gift the notification relates to.                                                                                          |
| `sendingChannel` | string   | The channel used to deliver the notification (e.g. `email`, `sms`).                                                            |
| `giftLink`       | string   | The recipient-facing link included in the notification.                                                                        |
| `reminderType`   | string   | The reminder variant. Present on `gift-notification-reminder` only.                                                            |
| `cadence`        | number   | Sequence number of the reminder/expiration notice. Present on `gift-notification-reminder` and `gift-notification-expiration`. |
| `metadata`       | object   | Any custom metadata attached at gift creation.                                                                                 |

**Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "gift-notification-reminder",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-19T10:30:00.000Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "giftId": "gft_12345",
    "cadence": 1,
    "sendingChannel": "email",
    "reminderType": "first-reminder",
    "giftLink": "https://gift.snappy.com/g/abc123",
    "metadata": {
      "internalReferenceId": "REF123456",
      "customCategory": "employee-recognition",
      "recipientContext": "anniversary-gift"
    }
  }
}
```

***

### Catalog & Stock Events

Use these events to keep your local catalog in sync.

| **Event Name**               | **Description**                                                                                                |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------- |
| `stock-availability-updates` | Triggered when a product's inventory status changes. This is essential for keeping your local catalog in sync. |

**Optional statuses:**

| Inventory **Status** | **Description**                                                |
| :------------------- | :------------------------------------------------------------- |
| `in_stock`           | The product is available for ordering.                         |
| `stocked_on_demand`  | The product is available but may require additional lead time. |
| `discontinued`       | The product is no longer available and will not be restocked.  |
| `out_of_stock`       | The product is temporarily unavailable.                        |

**Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "string",
    "eventType": "stock-availability-updates",
    "target": "string",
    "triggeredAt": "2025-01-22T11:45:00.000Z"
  },
  "eventData": {
    "id": "string",
    "title": "Premium Wireless Headphones",
    "description": "High-quality wireless headphones with noise cancellation",
    "category": "Electronics / Audio / Headphones / Wireless",
    "status": "in_stock",
    "brand": {
      "id": "string",
      "name": "Brand Name"
    },
    "types": [
      {
        "type": "physicalGift"
      }
    ]
  }
}
```

***

### Recipient Engagement Events

Triggered when a recipient interacts with the platform after claiming their gift, such as sending a message to the gift sender.

| **Event Name**                 | **Description**                                            |
| :----------------------------- | :--------------------------------------------------------- |
| `gift-thank-you-note-received` | The recipient has written a thank-you note for the sender. |

**Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "gift-thank-you-note-received",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-18T10:30:00.000Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "giftId": "gft_12345",
    "thankYouNote": "Thank you so much for the thoughtful gift!"
  }
}
```

### Exceptions & Operational Events

Use these events to track **critical edge cases** in your integration.

| **Event Name**       | **Description**                                                                                                                                  |
| :------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| `order-canceled`     | Triggered if an order is canceled by the sender, the system, or due to a fulfillment issue.                                                      |
| `order-out-of-stock` | Triggered if a selected product becomes unavailable before fulfillment. This allows you to proactively notify the sender or offer a replacement. |

<Note>
  The `eventData` for operational events always contains the relevant `orderId` and `companyId` so you can map the failure back to the specific order and recipient.
</Note>

**`order-canceled` Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "order-canceled",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-20T15:00:00.000Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "orderId": "ord_12345",
    "cancellationReason": "customer_requested"
  }
}
```

**`order-out-of-stock` Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "order-out-of-stock",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-20T15:00:00.000Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "orderId": "ord_12345"
  }
}
```

***

### Billing Events

Use these events to react to invoicing changes.

| **Event Name**      | **Description**                              |
| :------------------ | :------------------------------------------- |
| `gift-invoice-sent` | Triggered when a gift invoice has been sent. |

**`gift-invoice-sent` Example Payload:**

```json theme={null}
{
  "webhookData": {
    "id": "wh_12345",
    "eventType": "gift-invoice-sent",
    "target": "https://your-domain.com/webhooks",
    "triggeredAt": "2025-01-21T09:15:00.000Z"
  },
  "eventData": {
    "companyId": "com_12345",
    "invoiceId": "inv_12345"
  }
}
```

***

## Metadata in Webhooks

As discussed in the **API Standards** section, any `metadata` you attach during gift creation is echoed back in the `eventData` of the gift-lifecycle, notification, and shipping events - specifically `gift-status-changed`, `order-status-changed`, the `gift-notification-*` events, `gift-delivery-status-changed`, and `order-delivery-status-changed`. This ensures you can always map a Snappy event back to your internal IDs (e.g., `internalReferenceId`).

<Note>
  Billing, catalog, and operational events (such as `order-canceled` and `order-out-of-stock`) do **not** carry gift `metadata`. Map these back to your records using the `orderId` or `companyId` included in the payload.
</Note>

<Tip>
  **Proactive Support:** By listening for `order-out-of-stock` or `expired` events, your system can automatically trigger follow-up actions, ensuring a high-quality experience even when things don't go as planned.
</Tip>
