offer.* events to your webhook endpoints the moment a change is detected.
Use product subscriptions to power back-in-stock alerts, deal finders, “this offer is gone” UX, and price-drop notifications — without polling.
Product subscriptions supersede price-tracking subscriptions, which are
deprecated for new integrations: the Price Tracking
API sends a single
price.changed event, while
product subscriptions offer four event types narrowed by merchant domain or
variant. Both deliver to the same webhook endpoints. Price
history is not part of this
deprecation — it has no product-subscriptions equivalent and remains
supported.At a glance
How it works
- Register an endpoint in the Channel3 dashboard (see Managing endpoints). This is where you get your signing secret.
- Create a subscription with
POST /v1/product-subscriptions, choosing the event types and an optional scope. - Receive events as HTTP POSTs at every endpoint that has the matching event types enabled. Verify the signature and respond
2xxwithin 15 seconds.
Create and manage subscriptions
Four endpoints, with full request and response schemas in the API reference:- Create a subscription —
POST /v1/product-subscriptions. Creating is idempotent per scope: if an identical active subscription (same events, domains, and selection) already exists, it is returned instead of a duplicate being created. Product IDs from/v1/lookupare canonicalized automatically; while the lookup is still processing, the call returns409— retry with the same ID once it resolves. - List subscriptions — filter by
status, paginate withcursorandlimit. - Get a subscription — fetch one subscription by ID.
- Cancel a subscription — returns the subscription with
status: "cancelled". No events are sent for a subscription after its cancel call returns.
domains) or pinned to one variant configuration (selection).
Event types
Every event is a JSON object with an envelope plus adata payload:
Events fire only for changes visible in your subscription’s scope: the domains you restricted to, in the subscription’s locale (currently
en-US / USD for all subscriptions).
For the interactive schemas, see our webhook event catalog.
offer.price.changed
The offer’s price changed. Any price field changing fires this event, including compare_at_price (e.g. a strikethrough price removed).
offer.availability.changed
The offer’s availability flipped between InStock and OutOfStock. For subscriptions with a selection, this is the pinned configuration’s availability; otherwise it’s the listing’s. Use it for back-in-stock and sold-out UX.
offer.created
An offer entered the subscription’s view — for example a merchant started selling the product, or an offer appeared on one of your domains. data.offer is the current state of the offer.
offer.deleted
An offer left the subscription’s view — the merchant delisted it, the page 404s, or it’s otherwise no longer available from that merchant. This is the event to listen for if you need to remove or tombstone offers in your own UI. data.offer is the last known state of the offer.
url is a Channel3 buy URL that redirects to the merchant’s offer page. offer.created has the same shape, with the current (rather than last known) state.
Delivery, retries, and deduplication
Channel3 delivers webhooks through Svix, a dedicated webhook provider. Respond2xx within 15 seconds. Any other status code — including 3xx redirects — or a slower response counts as a failed attempt. Process events asynchronously if your handler does heavy work.
Retries. Failed deliveries are retried automatically on this schedule: immediately, then after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, and twice more at 10-hour intervals. To tell Channel3 to stop retrying a specific message (for example, one your system can’t process), include the header webhook-delivery: abort-message in your response. You can also replay or recover messages manually from the webhook portal at any time. An endpoint whose deliveries keep failing for days is disabled automatically; re-enable it from the portal.
Deduplication. Delivery is at-least-once: retries and manual replays can deliver the same event more than once. Every redelivery carries the same event id, which is also registered with Svix as the message’s event ID. Keep a short-lived store of recently processed IDs and skip duplicates.
Ordering. Use the envelope timestamp (when the change was committed) rather than arrival order if you need to sequence events.
Verifying signatures
Every webhook request is signed so you can verify it genuinely came from Channel3. The scheme is HMAC-SHA256 in the Standard Webhooks format — not a rawsha256=<hex> digest of the body. Each endpoint you register gets its own signing secret, shown in the portal, starting with whsec_.
Each request includes three headers:
The signed content is
{svix-id}.{svix-timestamp}.{raw request body}, HMAC-SHA256’d with the base64-decoded secret (the part after whsec_), then base64-encoded. Signatures must be compared in constant time, and timestamps more than five minutes old (or in the future) must be rejected to prevent replay attacks.
The easiest way to get all of this right is the official Svix SDK:
Managing endpoints
Endpoints are configured once per account — not per subscription — in the Channel3 dashboard, which embeds a webhook portal (powered by Svix). From the portal you can:- Add, pause, or remove endpoints, and rotate each endpoint’s signing secret.
- Choose which event types each endpoint receives.
- Inspect delivery attempts and payloads, send test events, and replay or recover failed messages.
User-Agent and allowlisting
Webhook requests are sent with aUser-Agent of the form Svix-Webhooks/<version>. Per Svix’s documentation, the exact string can vary by plan and configuration (self-hosted senders use Webhooks/<version>), so match on the Svix-Webhooks/ prefix rather than the full string. Requests from Svix’s hosted service also carry the marker sender-9YMgn — note this marker is shared by every company on Svix’s hosted service, so a User-Agent rule alone does not identify Channel3; treat it as a coarse filter and rely on signature verification to authenticate the sender.
If your firewall or Cloudflare configuration allows it, the more robust option is allowlisting by source IP: Svix publishes the static sender IPs for each region at docs.svix.com/receiving/source-ips.
Limits
- Up to 25 merchant domains per subscription.
- Up to 100 subscriptions per page when listing.
- There is currently no cap on the number of subscriptions per account.
- Subscribing to a product schedules a priority refresh of that product once per day; events fire when refreshes (or other catalog activity) detect changes.
- API calls to
/v1/product-subscriptionscount against the standard rate limits for your plan.
Price Tracking Webhooks
Payload reference for the Price Tracking API’s
price.changed event.