Webhooks
Webhooks send a JSON POST to your server when something happens in a wishlist. Add endpoints in the app under Developers → Webhooks.
Events
| Event | When |
|---|---|
item.added | A shopper or staff member saved an item. |
item.removed | An item was removed from a list. |
list.created | A shopper created a list. |
list.shared | A shopper shared a list. |
back_in_stock.triggered | A back in stock alert was sent for a product. |
price_drop.triggered | A price drop alert was sent for a product. |
Payload
{
"id": "evt_…",
"event": "item.added",
"occurredAt": 1767225600000,
"shop": "example.myshopify.com",
"data": {
"productId": "123",
"variantId": "456",
"listId": "…"
}
}
Fields inside data by event:
| Event | data |
|---|---|
item.added | productId, variantId, listId, customerId, addedBy, locationId |
item.removed | productId, variantId, listId, customerId |
list.created | listId, name, kind, customerId |
list.shared | listId, customerId, itemCount |
back_in_stock.triggered | productId, variantId, quantity |
price_drop.triggered | productId, variantId, oldPrice, newPrice, currency |
customerId is null for guests. variantId is null for product-level items. Prices are decimal strings in the shop currency.
Use id to ignore duplicates: the same event can arrive more than once.
Verifying the signature
Each request has an X-Wishlist-Signature header. It is the hex-encoded HMAC-SHA256 of the raw request body, using your endpoint's signing secret. The secret is shown once, when you add the endpoint.
Always compute the HMAC over the raw bytes, before parsing JSON, and compare in constant time.
import crypto from "node:crypto";
export function verify(rawBody, signature, secret) {
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected, "hex");
const b = Buffer.from(signature ?? "", "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Responding and retries
- Respond with any
2xxstatus within 10 seconds. Redirects are not followed. - Other statuses, timeouts and network errors are retried up to 8 attempts in total, starting 30 seconds after the first try and doubling each time (about an hour in all).
- Every attempt is listed under Developers → Deliveries for 90 days.
Endpoint rules
- URLs must use
https://and be publicly reachable. Private IP ranges,localhostand link-local addresses are rejected. - Up to 10 endpoints per store.
- Pause an endpoint to stop deliveries without deleting it.