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

# Webhook events

> Every event a webhook can be sent for

An endpoint is sent the events you tick for it, or every event when it takes all of them. A new event is never sent to an endpoint that did not ask for it, unless it takes all of them.

## Orders

`data`: The order, as [Get an order](/api-reference/orders/get-an-order.md) answers it, with `payments`, every payment opened for it, and `invoice` where the store raised it as one.

| Event | When it is sent |
| - | - |
| `order.created` | An order was made: a buyer started a checkout, or the store raised an invoice. |
| `order.payment_started` | The buyer pressed Pay and a payment was opened with a payment method. |
| `order.paid` | An order was paid for and is complete. |
| `order.delivered` | What an order bought was handed over: license keys, files, a dynamic delivery's answer. |
| `order.redelivered` | An order was delivered again with fresh license keys. |
| `order.email_failed` | An order's delivery email could not be sent. |
| `order.cancelled` | An order was cancelled: by its buyer, by the store (a custom payment rejected among them), or because nobody paid it in time. |
| `order.refunded` | An order was refunded. |
| `order.disputed` | A buyer disputed an order's payment with their bank or payment provider. |
| `order.chargeback` | A dispute was lost and the order's money went back. |
| `order.payment_submitted` | The buyer said they paid with one of the store's custom payment methods, and the order waits for the store to approve or reject it. Approved, it is `order.paid`; rejected, `order.cancelled`. |
| `order.rerouted` | Payment Routing moved an order to another of the store's card processors, after a decline or after the buyer gave up on a provider's page. |

## Reviews

`data`: `orderId`, `productId`, `email`, and `review` with its `rating`, `message`, `automatic` and `dateCreated`. `review.removed` and `review.flag_declined` add `reviewId` and `flag`, the flag as [List reviews](/api-reference/reviews/list-reviews.md) answers it, with Shoply's `answer`.

| Event | When it is sent |
| - | - |
| `review.created` | A review was left on an order, by its buyer or by itself after seven days. |
| `review.removed` | A review the store flagged was removed by Shoply. It is no longer anywhere, and its order can be given no other. |
| `review.flag_declined` | A review the store flagged was kept by Shoply, with the reason why. |

## Stock

`data`: `productId`, `productName`, `variantId`, `variantName`, `available` (what is left) and `threshold` (the store's low stock number).

| Event | When it is sent |
| - | - |
| `stock.low` | A sale left a variant that counts its stock with few, at or under the store's low stock number. |
| `stock.out` | A sale took the last of a variant that counts its stock. |

## Catalogue

`data`: The product, as [Get a product](/api-reference/products/get-a-product.md) answers it. `product.deleted` has only its `id` and `name`.

| Event | When it is sent |
| - | - |
| `product.created` | A product was added. |
| `product.updated` | A product, its variants or its pictures were changed. |
| `product.deleted` | A product was deleted. |

## Customers

`data`: `id`, `emailAddress`, `balance`, `tags` and `dateCreated`. `customer.tagged` and `customer.untagged` add `tag`, the one put on or taken off: `id`, `name`, `tone` and `automatic` (Shoply's own two are `vip` and `disputed`).

| Event | When it is sent |
| - | - |
| `customer.created` | An email address became a customer of the store. |
| `customer.balance_changed` | A customer's store balance changed: it was spent, credited, refunded to or set. |
| `customer.tagged` | A tag was put on a customer: one of the store's own, by hand or by a key; VIP, by the sale that made them one; or Disputed Before, by their first dispute. |
| `customer.untagged` | One of the store's own tags was taken off a customer, by hand or by a key. A tag deleted, and VIP ending because its period moved on, are not sent. |

## Affiliates

`data`: The affiliate: `id`, `customerId`, `emailAddress`, `code`, `commission`, `discount`, `balance`, `active`, `source` and `dateCreated`. The two `affiliate.payout_` events have the payout request, as [List payout requests](/api-reference/affiliates/list-payout-requests.md) answers it.

| Event | When it is sent |
| - | - |
| `affiliate.created` | A customer became an affiliate, added by the store or by joining. |
| `affiliate.payout_requested` | An affiliate asked for a payout. |
| `affiliate.payout_answered` | A payout request was marked as paid or declined. |
| `affiliate.balance_changed` | An affiliate's balance changed: commission earned or taken back by a refund, a payout asked for or given back, a move to store balance, or set by hand. |

## Subscriptions

`data`: The subscription, as [Get a subscription](/api-reference/subscriptions/get-a-subscription.md) answers it.

| Event | When it is sent |
| - | - |
| `subscription.started` | A subscription's first order was paid and the subscription began. |
| `subscription.renewed` | A subscription's renewal was paid and it runs another period. |
| `subscription.cancelled` | A subscription was cancelled, by its buyer or the store. It may run to the end of what was paid for. |
| `subscription.ended` | A subscription ended: cancelled, or its renewal was not paid. Where the store takes access back, it was. |
| `subscription.paused` | A subscription was paused, by its buyer or the store. Nothing renews until it resumes, and where the store takes access back, it was. |
| `subscription.resumed` | A paused subscription is running again, by itself on its day or when asked. Access is given back. |
| `subscription.charge_failed` | Charging a subscription's renewal to its kept card was declined. It is tried again once a day while the store's tries last, and its buyer can pay by the renewal's link meanwhile. |

## Cart Recovery

`data`: The checkout that was left, as [List carts](/api-reference/cart-recovery/list-carts.md) answers it: `state` says which email it last had, and `recoveredOrderId` the order that paid.

| Event | When it is sent |
| - | - |
| `cart.email_sent` | Cart Recovery emailed a buyer about a checkout they left: the first email, the declined card email or the second. |
| `cart.recovered` | A checkout Cart Recovery emailed about was paid, or the checkout its email's button opened was. |
| `cart.unsubscribed` | A buyer unsubscribed from the store's Cart Recovery emails. Their receipts still go. |

## Win-Back

`data`: The buyer, as [List Win-Back buyers](/api-reference/email-marketing/list-win-back-buyers.md) answers it: `state` says which email they last had, and `wonOrderId` the order that brought them back.

| Event | When it is sent |
| - | - |
| `winback.email_sent` | Win-Back emailed a subscriber who has not ordered in a while: the first email or the second. |
| `winback.won_back` | A buyer Win-Back emailed placed an order within 14 days of the email, and it was paid. |

## Subscribers

`data`: The subscriber, as [List subscribers](/api-reference/email-marketing/list-subscribers.md) answers it: `email`, `customerId`, `subscribed`, `subscribedAt`, `source`, `orderId` (the order whose box was ticked), `unsubscribedAt` and `unsubscribedBy`.

| Event | When it is sent |
| - | - |
| `subscriber.subscribed` | A buyer who ticked the store's box at checkout, "Email me news and offers", paid that order, and is a subscriber. |
| `subscriber.unsubscribed` | A subscriber is one no longer: they unsubscribed from a Win-Back or Cart Recovery email, or the store or a key took them off. |

## Payment Routing

`data`: `provider`, `name`, `paused`, `pausedAt` and `pausedReason`, the processor as it stands after the change.

| Event | When it is sent |
| - | - |
| `routing.processor_paused` | Payment Routing stopped giving checkouts to one of the store's card processors: its keys stopped working, or too many of its last payments were declined. |
| `routing.processor_resumed` | A paused processor was put back into the split. |

## Disputes

`data`: The dispute, as [List disputes](/api-reference/disputes/list-disputes.md) answers it: `status` is how it reads on the dashboard, `providerStatus` what the provider last said, `dueAt` when it stops taking an answer.

| Event | When it is sent |
| - | - |
| `dispute.opened` | A payment provider told Shoply of a dispute on one of the store's orders: a chargeback, an inquiry from the buyer's bank, or a PayPal claim. |
| `dispute.updated` | A dispute changed while still open: its status, its stage or its deadline, or its answer was submitted, accepted or marked as answered. |
| `dispute.won` | A dispute ended in the store's favour. The money stays with the store. |
| `dispute.lost` | A dispute ended in the buyer's favour, or the store accepted it. The order is a chargeback, and `order.chargeback` is sent too. |
| `dispute.closed` | A dispute ended with no chargeback: an inquiry the bank closed, or one settled before it became a chargeback. |

## Apps

`data`: `id` (the connection), `appId`, `name`, `maker`, `website`, `scopes` (what the owner approved), `connectedAt`, and for `app.disconnected` `disconnectedAt` and `reason`: `seller`, `app`, `deleted`, or `code_reused` (the app's approval was offered twice, so its token was ended).

| Event | When it is sent |
| - | - |
| `app.connected` | The store's owner approved an app, and the app's server swapped the approval for its token. An app approved again is connected again, and its old token stops working. |
| `app.disconnected` | An app stopped reaching the store: the owner disconnected it, the app gave its token up, or its developer deleted it. The endpoints it made are removed with it. |

## Support Tickets

`data`: The ticket, as [Get a support ticket](/api-reference/support-tickets/get-a-support-ticket.md) answers it without its conversation: `status` is `open` (the buyer wrote last), `answered` or `resolved`, and `resolvedBy` says who resolved it (`store`, `buyer` or `auto`). `ticket.message` adds `message`: its `id`, `from` (`buyer` or `store`), `body`, `pictures` (each one's `name`, read with a key) and `createdAt`.

| Event | When it is sent |
| - | - |
| `ticket.opened` | A buyer opened a support ticket from the customer panel, or the store's own site through the customer API. |
| `ticket.message` | A message was written on a ticket, by the buyer or the store. Not sent for the message a ticket is opened with: that is `ticket.opened`. |
| `ticket.resolved` | A ticket was marked resolved: by the store, by the buyer, or by itself 48 hours after the store's reply with no word from the buyer. |
| `ticket.reopened` | A resolved ticket was opened again: the buyer wrote on it within 30 days, or the store reopened it. |

## Fraud protection

`data`: The event, as [List fraud events](/api-reference/fraud-protection/list-fraud-events.md) answers it.

| Event | When it is sent |
| - | - |
| `fraud.checkout_blocked` | A checkout was turned away by the blacklist, a blocked country, the VPN rule or the limit on unpaid orders. The same buyer turned away again for the same reason within ten minutes is not sent again. |

## Testing

| Event | When it is sent |
| - | - |
| `webhook.test` | When you press **Send a test** on an endpoint. It is sent to that endpoint whatever it subscribes to. |


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