--- 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). api_version: v1 api_name: shopify-app-remix source_url: html: https://shopify.dev/docs/api/shopify-app-remix/v1/guide-webhooks md: https://shopify.dev/docs/api/shopify-app-remix/v1/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). *** ## Configuring webhooks To set up webhooks first we need to configure `shopifyApp` with 2 pieces: 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. 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 * #### /app/shopify.server.ts ##### /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}) => { shopify.registerWebhooks({session}); }, }, }); export const authenticate = shopify.authenticate; ``` ## Set up your endpoints Legitimate webhook requests are always `POST`s signed by Shopify, so you must authenticate them before taking any action. For each `callbackUrl` in your configuration, 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 * #### /app/routes/webhooks.tsx ##### /app/routes/webhooks.tsx ```tsx import {ActionFunction} from '@remix-run/node'; import db from '../db.server'; import {authenticate} from '~/shopify.server'; export const action: ActionFunction = async ({request}) => { const {topic, shop, session} = await authenticate.webhook(request); switch (topic) { case 'APP_UNINSTALLED': 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)