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

# Setup

Want to track the price of a product, or know when it's back in stock? We provide webhooks that let you do just that.

**1. Register an endpoint**

Add an endpoint in the [dashboard](https://channel3.ai/dashboard/webhooks) and copy its signing secret. Each endpoint receives events from every subscription on the account, for the event types you enable on it. Add another when you want a separate URL, such as QA alongside production.

![Endpoint configuration in the Channel3 dashboard, with the Endpoints tab selected and an Add Endpoint button](https://mintcdn.com/channel3/scb96LOSZ3OwWVZa/public/guides/webhooks/endpoint-configuration.jpg?fit=max\&auto=format\&n=scb96LOSZ3OwWVZa\&q=85\&s=bf9821bda4ac81a43ca84d08b01fb9d6)

Add an endpoint from the Endpoints tab.

Respond `2xx` within 15 seconds. [Verify the signature](/docs/product-subscription-webhooks.md#verifying-signatures) before you act on the body.

**2. Create a subscription**

Pass a product ID from search or lookup, and the event types you want.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -X POST https://api.trychannel3.com/v1/product-subscriptions \
  -H "x-api-key: $CHANNEL3_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": "2yh8WH5",
    "events": [
      "offer.price.changed",
      "offer.availability.changed",
      "offer.created",
      "offer.deleted"
    ]
  }'
```

Sending the same scope again (the same events, domains, and selection) returns the existing subscription.

`domains` limits events to those merchants. Pass up to 25 bare domains.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "product_id": "2yh8WH5",
  "events": [
    "offer.price.changed",
    "offer.availability.changed",
    "offer.created",
    "offer.deleted"
  ],
  "domains": ["nike.com", "footlocker.com"]
}
```

`selection` pins a variant. Copy `{ "name", "label" }` from `variants.selected` on the product, one entry per dimension.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "product_id": "2yh8WH5",
  "events": [
    "offer.price.changed",
    "offer.availability.changed",
    "offer.created",
    "offer.deleted"
  ],
  "selection": [
    { "name": "Color", "label": "Midnight Blue" },
    { "name": "Size", "label": "M" }
  ]
}
```

Some values, usually colors, are a [separate product](/docs/variants#navigating-across-products) with their own `product_id` in `variants.options`. Selecting one subscribes you to that product, so the `product_id` in the response and in events can differ from the one you sent.

Every subscription reads the product in English, US, USD.

[Create](/docs/api-reference/product-subscriptions/create-subscription.md), [list](/docs/api-reference/product-subscriptions/list-subscriptions.md), [get](/docs/api-reference/product-subscriptions/get-subscription.md), and [cancel](/docs/api-reference/product-subscriptions/cancel-subscription.md) from the API. Cancelling stops events for that subscription as soon as the call returns.

**3. What arrives**

Every body has `id`, `timestamp`, `type`, and `data`. `data.subscription_id` is your subscription. `data.subject` names the offer: `product_id`, merchant `domain`, `locale`, and `selection` (`null` when you subscribed to the offer as a whole). The `id` stays the same when a delivery is retried, so skip any you have already handled.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "3b7f1c2d4e5a6b8c9d0e1f2a3b4c5d6e7f8a9b0c",
  "timestamp": "2026-10-25T14:03:11.592000+00:00",
  "type": "offer.price.changed",
  "data": {
    "subscription_id": "01JZK3V1M0T4QF3Y3Z0E5T6V7W",
    "subject": {
      "product_id": "2yh8WH5",
      "domain": "nike.com",
      "locale": { "language": "en", "country": "US", "currency": "USD" },
      "selection": [
        { "name": "Color", "label": "Midnight Blue" },
        { "name": "Size", "label": "M" }
      ]
    },
    "previous": { "price": 189.99, "compare_at_price": null, "currency": "USD" },
    "current": { "price": 149.99, "compare_at_price": 189.99, "currency": "USD" }
  }
}
```

`subject.domain` is the merchant this offer came from. `subject.selection` is the variant you pinned. Leave `selection` off the subscription and it arrives as `null`.

> [card] [Price updates](/docs/guides/webhooks/price.md)
>
> `offer.price.changed` when a price moves.

> [card] [Availability updates](/docs/guides/webhooks/availability.md)
>
> `offer.availability.changed` when stock flips.

> [card] [New and removed offers](/docs/guides/webhooks/offers.md)
>
> `offer.created` and `offer.deleted` when a new merchant starts selling
> the product, or one stops.

> [card] [Product Subscription Webhooks](/docs/product-subscription-webhooks.md)
>
> Signatures, retries, endpoints, and the full payload reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.