---
title: Subscribing to webhooks
description: Your app must respond to mandatory webhook topics.
api_version: v1
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.

## /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.

## /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

[authenticate.webhook](https://shopify.dev/docs/api/shopify-app-remix/v1/authenticate/webhook)

***
