--- title: Subscribing to webhooks description: |- Your app must respond to [mandatory webhook topics](/docs/apps/webhooks/configuration/mandatory-webhooks). In addition, your app can register [optional webhook topics](/docs/api/admin-rest/current/resources/webhook#event-topics). There are app-specific and shop-specific webhooks. We recommend app-specific webhooks for most apps, but there are reasons to register shop-specific webhooks. For more information, please read [App-specific vs shop-specific webhooks](https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions). api_version: v3 api_name: shopify-app-remix source_url: html: https://shopify.dev/docs/api/shopify-app-remix/v3/guide-webhooks md: https://shopify.dev/docs/api/shopify-app-remix/v3/guide-webhooks.md --- # Subscribing to webhooks Your app must respond to [mandatory webhook topics](https://shopify.dev/docs/apps/webhooks/configuration/mandatory-webhooks). In addition, your app can register [optional webhook topics](https://shopify.dev/docs/api/admin-rest/current/resources/webhook#event-topics). There are app-specific and shop-specific webhooks. We recommend app-specific webhooks for most apps, but there are reasons to register shop-specific webhooks. For more information, please read [App-specific vs shop-specific webhooks](https://shopify.dev/docs/apps/build/webhooks/subscribe#app-specific-vs-shop-specific-subscriptions). *** ## App-specific webhooks (recommended) The easiest way to configure webhooks is to use app-specific webhooks in `shopify.app.toml`. You can find more info in the [webhooks documentation](https://shopify.dev/docs/apps/webhooks/getting-started-declarative). To set up a simple HTTPS webhook subscription, you can follow these steps: 1. Add the topic to subscribe to in `shopify.app.toml`. In this example we subscribe to the `APP_UNINSTALLED` topic. 2. Review the required scopes for the webhook topics, and update your [app scopes](https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes) as necessary. 3. Run `shopify app deploy` from the CLI to save your webhooks configuration. ### Examples * #### Configure app-specific webhooks ##### shopify.app.toml ```tsx [webhooks] api_version = "2024-04" [[webhooks.subscriptions]] topics = [ "app/uninstalled" ] uri = "/webhooks" compliance_topics = [ "customers/data_request", "customers/redact", "shop/redact" ] ``` ## Shop-specific webhooks Shop-specific webhooks are useful when you need to subscribe to different webhook topics for different shops, or when a topic is not supported by app-specific webhooks.Configure `shopifyApp` and to setup shop-specific webhook subscriptions with the following steps: 1. The webhooks you want to subscribe to. In this example we subscribe to the `APP_UNINSTALLED` topic. 2. The code to register the `APP_UNINSTALLED` topic after a merchant installs you app. Here `shopifyApp` provides an `afterAuth` hook. 3. Review the required scopes for the webhook topics, and update your [app scopes](https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes) as necessary. Note You can't register mandatory topics using this package, you must [configure those in the Partner Dashboard](https://shopify.dev/docs/apps/webhooks/configuration/mandatory-webhooks) instead. ### Examples * #### Configure shop-specific webhooks ##### /app/shopify.server.ts ```tsx import {shopifyApp, DeliveryMethod} from '@shopify/shopify-app-remix/server'; const shopify = shopifyApp({ apiKey: 'abcde1234567890', // ...etc webhooks: { APP_UNINSTALLED: { deliveryMethod: DeliveryMethod.Http, callbackUrl: '/webhooks', }, }, hooks: { afterAuth: async ({session}) => { // Register webhooks for the shop // In this example, every shop will have these webhooks // You could wrap this in some custom shop specific conditional logic if needed shopify.registerWebhooks({session}); }, }, }); export const authenticate = shopify.authenticate; ``` ## Set up your endpoints Create a route in your app to handle incoming webhook requests for each `callbackUrl` you set in your configuration.Legitimate webhook requests are always `POST` requests signed by Shopify, so you must authenticate them before taking any action. To do this you must set up an `action` that uses the `authenticate.webhook` function to authenticate the request. Please keep in mind that webhook endpoints should respond as quickly as possible. If you need to run a long-running job, then consider using background tasks. Caution Webhook endpoints **must** respond with an `HTTP 200` code, or Shopify will retry. ### Examples * #### Receive webhook requests ##### /app/routes/webhooks.tsx ```tsx import {ActionFunctionArgs} from '@remix-run/node'; import db from '../db.server'; import {authenticate} from '~/shopify.server'; export const action = async ({request}: ActionFunctionArgs) => { const {topic, shop, session} = await authenticate.webhook(request); switch (topic) { case 'APP_UNINSTALLED': // Webhook requests can trigger after an app is uninstalled // If the app is already uninstalled, the session may be undefined. if (session) { await db.session.deleteMany({where: {shop}}); } break; case 'CUSTOMERS_DATA_REQUEST': case 'CUSTOMERS_REDACT': case 'SHOP_REDACT': default: throw new Response('Unhandled webhook topic', {status: 404}); } throw new Response(); }; ``` ## Resources [![](https://shopify.dev/images/icons/32/pickaxe-1.png)![](https://shopify.dev/images/icons/32/pickaxe-1-dark.png)](https://shopify.dev/docs/api/shopify-app-remix/authenticate/webhook) [authenticate.webhook](https://shopify.dev/docs/api/shopify-app-remix/authenticate/webhook)