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

# Webhooks

> Reference for all 13 webhook topics the app handles: orders, refunds, products, inventory, app lifecycle, and the mandatory privacy webhooks.

Every webhook route authenticates the delivery with the Shopify app library,
which verifies the `X-Shopify-Hmac-Sha256` header (base64 HMAC over the raw
body) before the payload is read. Handlers always respond with a success
response and log their own failures internally, so Shopify is never prompted
into retry storms; the background order sync (see
[Background jobs](https://topten.mintlify.site/architecture/background-jobs.md)) acts as the safety net for
missed deliveries.

## Handled topics

| Topic | What the handler does |
| - | - |
| `orders/create` | Upserts the order (line items, totals, test/cancelled flags) and runs cart-token attribution |
| `orders/updated` | Re-upserts the order: refreshes totals and cancellation state, re-merging any refund history already applied |
| `orders/cancelled` | Marks the order cancelled — it then drops out of every order, revenue, and conversion metric |
| `refunds/create` | Prorates the refund per unit onto the matching line items and updates refunded amounts; ignored if the order has not arrived yet |
| `products/update` | Refreshes the single product and its variants in the catalog cache — titles, images, and stock feed the Products pages and inventory-aware insights |
| `products/delete` | Removes the product and its variants from the catalog cache |
| `inventory_levels/update` | Maps the inventory item back to its product through the variant cache and refreshes the product, keeping cached stock fresh in near-real time for stock columns and inventory-aware insights |
| `app/uninstalled` | Deletes the shop's auth session and wipes all of the shop's analytics data (see the deletion matrix in [Data model](https://topten.mintlify.site/architecture/data-model.md)) |
| `app/scopes_update` | Updates the stored session record with the shop's current granted scopes |
| `customers/data_request` | Mandatory privacy webhook. Acknowledges the request — the app stores no customer personal data to export |
| `customers/redact` | Mandatory privacy webhook. Deletes the stored order records for the listed order ids (order rows contain no customer fields) |
| `shop/redact` | Mandatory privacy webhook. Deletes every shop-scoped row across all store tables |

Subscriptions are declared in the app configuration with per-topic callback
URIs. Order and refund webhooks require the `read_orders` scope, and their
payloads follow the API version declared in the app configuration.

## Ordering and delivery guarantees

> [!WARNING]
>
> Webhook delivery order is not guaranteed. An `orders/updated` can arrive
> before `orders/create`, and a refund can precede its order. The handlers are
> written for this: order upserts are idempotent, refunds that arrive early are
> skipped and re-applied when the order catches up, and the background order
> sync reconciles anything the webhook stream missed.

## Attribution coupling

`orders/create` and `orders/updated` are the only paths that can produce
**attributed** metrics. Attribution works exclusively from the order's cart
token:

1. The token is matched against the cart-token-to-session map the storefront
   tracker built during add-to-cart events.
2. Products the same session added to its cart inside the attribution window
   (default 7 days, configurable 1–30) are marked as attributed on the order's
   line items.

Orders ingested by the Admin API catch-up sync carry no cart token, so they
count as orders but remain **not attributable**. The admin UI labels this
honestly — see [Measurement](https://topten.mintlify.site/measurement.md) for the full attribution contract.

## Data minimization in practice

Order rows store what the metrics need — line items, prices, discounts,
refunds, test and cancellation flags, attribution state — and no customer
names, emails, or addresses. That is why `customers/data_request` can be
answered with a confirmation that there is nothing personal to export, and
`customers/redact` only needs to remove the listed order rows. See
[Privacy](https://topten.mintlify.site/privacy.md) for the merchant-facing summary.


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