--- title: Webhooks delivery structure description: >- The structure of each delivery: JSON payload, HTTP headers, and how to customize what you receive with include_fields. source_url: html: 'https://shopify.dev/docs/apps/build/webhooks/delivery-structure' md: 'https://shopify.dev/docs/apps/build/webhooks/delivery-structure.md' --- # Webhooks delivery structure Each qualifying change sends a delivery to your `uri` as an HTTP POST with a JSON body and a set of headers. By default, the body is the full REST resource payload for the topic. Add `include_fields` to receive only the specific fields your app needs. ![Modify payloads](https://shopify.dev/assets/assets/images/apps/webhooks/customize/modify_payloads-ByCGW8QH.png) *** ## Payload Every delivery includes a JSON body containing the full REST resource for the subscribed topic. The shape and fields depend on the topic. See the [Webhooks reference](https://shopify.dev/docs/api/webhooks) for the payload structure of each topic. ## Example payload (products/update) ```json { "id": 9554194432293, "title": "T-Shirt", "status": "active", "vendor": "My Store", "product_type": "Shirts", "updated_at": "2025-04-22T14:30:00-05:00", "variants": [ { "id": 123456789, "title": "Default Title", "price": "29.99", "sku": "TSHIRT-001", "taxable": true, "updated_at": "2025-04-22T14:30:00-05:00" } ], "tags": "cotton, comfortable" } ``` *** ## Headers Every delivery includes the following headers. Treat header names as case-insensitive in your code, as HTTP/2 often lowercases them. | Header | Description | | - | - | | `X-Shopify-Topic` | The topic name (for example, `products/update`). | | `X-Shopify-Hmac-Sha256` | Base64-encoded HMAC signature for verifying the delivery came from Shopify. HTTPS only. | | `X-Shopify-Shop-Domain` | The `myshopify.com` domain of the store that triggered the event. | | `X-Shopify-API-Version` | The API version used to serialize the payload. | | `X-Shopify-Webhook-Id` | A unique composite key per delivery. Use to identify and deduplicate individual deliveries. | | `X-Shopify-Triggered-At` | Timestamp of when Shopify triggered the delivery. | | `X-Shopify-Event-Id` | A unique ID shared across all deliveries produced by the same merchant action. | | `X-Shopify-Name` (optional) | Developer-supplied subscription name, set via the `name` field in your subscription. | *** ## `include_fields` `include_fields` is an optional array of field paths on a webhook subscription. When set, the delivery payload includes only the specified fields instead of the full resource. Without `include_fields`, every delivery includes the complete resource payload: ## Without include\_fields ##### shopify.app.toml ```toml [webhooks] api_version = "2026-04" [[webhooks.subscriptions]] topics = ["products/update"] uri = "https://your-app.example.com/webhooks/products" ``` ##### {} Response ```json { "id": 9554194432293, "title": "T-Shirt", "status": "active", "vendor": "My Store", "product_type": "Shirts", "updated_at": "2025-04-22T14:30:00-05:00", "variants": [ { "id": 123456789, "title": "Default Title", "price": "29.99", "sku": "TSHIRT-001", "taxable": true, "updated_at": "2025-04-22T14:30:00-05:00" } ], "tags": "cotton, comfortable" } ``` Adding `include_fields` narrows the payload to only the specified fields. You denote nested fields using a period (for example, `variants.price`). You can also set `include_fields` using the `includeFields` input in the [`webhookSubscriptionCreate`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/webhookSubscriptionCreate) mutation. ## With include\_fields ##### shopify.app.toml ```toml [webhooks] api_version = "2026-04" [[webhooks.subscriptions]] topics = ["products/update"] uri = "https://your-app.example.com/webhooks/products" include_fields = ["id", "variants.id", "variants.price", "updated_at"] ``` ##### {} Response ```json { "id": 9554194432293, "variants": [ { "id": 123456789, "price": "29.99" } ], "updated_at": "2025-04-22T14:30:00-05:00" } ``` ### Debouncing When `include_fields` reduces the payload to a small set of fields, multiple qualifying events might produce identical payloads. Shopify debounces deliveries with identical payloads that arrive within a short time window, dropping the later one. For example, a subscription to `orders/updated` with `include_fields = ["id", "line_items.title"]` would debounce consecutive price changes, since neither the order ID nor line item titles change between them. To prevent debouncing, include a field that always has a unique value. For example, `updated_at` changes with every update, ensuring no two consecutive deliveries are identical. ### Combining with `filter` When both `filter` and `include_fields` are set, all fields referenced in the `filter` expression must also appear in `include_fields`. ## shopify.app.toml ```toml [webhooks] api_version = "2026-04" [[webhooks.subscriptions]] topics = ["products/update"] uri = "https://example.com/webhooks" include_fields = ["id", "status", "product_type", "variants.taxable", "variants.price", "variants.title", "updated_at"] filter = "id:* AND status:active AND (product_type:Music OR product_type:Movies) AND variants.taxable:true AND variants.price:>=100 AND variants.title:'The Miseducation of'" ``` See [Delivery filtering](https://shopify.dev/docs/apps/build/webhooks/delivery-filtering) for filter syntax and examples. *** ## Example Suppose you want deliveries only when an active product in the Music or Movies category has a variant priced above $100. The following subscription combines `include_fields` to narrow the payload and `filter` to gate delivery: ## Active high-price music or movies product ##### shopify.app.toml ```toml [webhooks] api_version = "2026-04" [[webhooks.subscriptions]] topics = ["products/update"] uri = "https://your-app.example.com/webhooks/products" include_fields = ["id", "status", "product_type", "variants.id", "variants.price", "updated_at"] filter = "status:active AND (product_type:Music OR product_type:Movies) AND variants.price:>=100" ``` ##### {} Response ```json { "id": 9554194432293, "status": "active", "product_type": "Music", "variants": [ { "id": 123456789, "price": "129.99" } ], "updated_at": "2025-04-22T15:00:00-05:00" } ``` *** ## Next steps * [Delivery filtering](https://shopify.dev/docs/apps/build/webhooks/delivery-filtering): Gate deliveries with `filter` expressions. * [Verify deliveries](https://shopify.dev/docs/apps/build/webhooks/verify-deliveries): HMAC verification and deduplication. ***