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

# Setup a webhook

> Start receiving event payloads

<Tip>
  Webhooks are available to
  [Entreprise](https://brandfetch.com/developers/pricing) customers, if you're
  interested [contact us](https://brandfetch.com/developers/contact/sales).
</Tip>

## Summary

To start receiving webhook events in your integration, create and register a webhook endpoint by following the steps below:

1. Create a webhook endpoint handler to receive event data POST requests.
2. Register your endpoint with Brandfetch via an API request.
3. Secure your webhook endpoint.

You can register and create one endpoint to handle several different event types at once, or set up individual endpoints for specific events.

[Setup a webhook and subscribe to brand updates](/guides/subscribe-to-webhook-updates)

## Create a handler

See the [events reference](/webhooks/event-types) to identify the event types your webhook handler needs to process.

Set an HTTPS endpoint function that can accept webhook requests with a POST method.

Set up your endpoint function so that it:

1. Handles POST requests with a JSON payload consisting of an event object.
2. Quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout.

### Example endpoint

This code snippet is a webhook function configured to check that the event type was received, to handle the event, and return a 200 response.

Example code for `hasVerifiedPayload()` is available [here](/webhooks/best-practices#example-code-for-handling-signature-and-timing-verification).

```javascript theme={null}
const express = require("express");
const app = express();

// Verify the signature by comparing the signature
// provided in the signature header with one we
// compute ourselves with the shared secret.
// If the signatures don't match, we return an error
function verifyWebhook(request, response, rawBodyBuffer, encoding) {
  if (!rawBodyBuffer || !rawBodyBuffer.length) {
    return response.status(400).json({ message: "Request body missing" });
  }

  const payload = rawBodyBuffer.toString(encoding || "utf8");
  const headers = request.headers;

  if (
    !hasVerifiedPayload({
      sharedWebhookSecret: process.env.SHARED_WEBHOOK_SECRET,
      headers,
      rawRequestBody: payload,
    })
  ) {
    return response.status(400).json({
      message: "Signature does not match.",
    });
  }
}

app.post(
  "/webhook",
  express.json({ type: "application/json", verify: verifyWebhook }),
  (request, response) => {
    const event = request.body;

    switch (event.type) {
      case "brand.updated":
        const brand = event.data.brand;
        const changes = event.data.delta;

        // Then define and call a method to handle the brand updated event.
        handleBrandUpdated(brand, changes);

        break;
      case "brand.verified":
        const brand = event.data.brand;

        // Then define and call a method to handle the brand verified event.
        handleBrandVerified(brand);

        break;
      // ... handle other event types
      default:
        console.log(`Unhandled event type ${event.type}`);
    }

    // Return a response to acknowledge receipt of the event
    response.json({ received: true });
  }
);

app.listen(8000, () => console.log("Running on port 8000"));
```

## Register your endpoint

Once your handler is deployed on the web and ready to go, register your endpoint with Brandfetch by creating a webhook using the GraphQL APIs `createWebhook` [mutation](/guides/access-graphql-api).

<Note>
  Registered webhook endpoint URLs must be publicly accessible HTTPS URLs.
</Note>

<CodeGroup>
  ```cURL cURL theme={null}
  curl --request POST \
      --header 'content-type: application/json' \
      --header 'authorization: Bearer YOUR_API_KEY_HERE' \
      --url 'https://graphql.brandfetch.io' \
      --data '{"query":"mutation CreateWebhook($input: CreateWebhookInput!) {\n  createWebhook(input: $input) {\n    code\n    message\n    success\n    webhook {\n      urn\n      enabled\n    }\n  }\n}","variables":{"input":{"description":"My new Webhoook","events":["brand.updated","brand.verified"],"url":"https://httpbin.org/status/200"}}}'
  ```

  ```GraphQL GraphQL theme={null}
  mutation CreateWebhook($input: CreateWebhookInput!) {
    createWebhook(input: $input) {
      code
      message
      success
      webhook {
        urn
      }
    }
  }

  # Example Variables: { "input": { "description": "Get updates when a brand's logo changes", "events": ["brand.updated"], "url": "https://httpbin.org/status/200"}}
  ```
</CodeGroup>

## Subscribe to objects using their URNs

The final step is to subscribe to the objects (like brands) for which you want to receive events. You can subscribe to a few objects, or many thousands—one at a time, or in batches.

For example, perhaps you want to receive events for the Brandfetch brand. The URN for this brand is `urn:brandfetch:brand:idL0iThUh6which` means we would subscribe to that URN.

To add a subscription we need two things: The URN for the webhook we created (`$webhookUrn: URN!`) and the URN for the object to which we want to subscribe to (`$subscriptions: [URN!]!`).

<CodeGroup>
  ```cURL cURL theme={null}
  curl --request POST \
      --header 'content-type: application/json' \
      --header 'authorization: Bearer YOUR_API_KEY_HERE' \
      --url 'https://graphql.brandfetch.io' \
      --data '{"query":"mutation AddWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) {\n  addWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) {\n    code\n    message\n    success\n    webhook {\n      urn\n    }\n  }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:5678","subscriptions":["urn:brandfetch:brand:idL0iThUh6"]}}'
  ```

  ```GraphQL GraphQL theme={null}
  mutation AddWebhookSubscriptions($webhookUrn: URN!, $subscriptions: [URN!]!) {
    addWebhookSubscriptions(webhook: $webhookUrn, subscriptions: $subscriptions) {
      code
      message
      success
      webhook {
        urn
      }
    }
  }

  # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234", "subscriptions": ["urn:brandfetch:brand:id123456"] }
  ```
</CodeGroup>

## Debugging delivery issues

To help debug your endpoint, or to later retrieve failed event deliveries when your endpoint has a long duration outage, you can review all of the events Brandfetch attempted to deliver to your webhook endpoint using the GraphQL API.

Performing the following GraphQL query on the Webhooks API will return a list of all attempted webhook deliveries, responses from your endpoint, and the respective HTTP status codes we received. Delivery history is kept for 30 days after which time it is irreversibly deleted.

<CodeGroup>
  ```cURL cURL theme={null}
  curl --request POST \
      --header 'content-type: application/json' \
      --header 'authorization: Bearer YOUR_API_KEY_HERE' \
      --url 'https://graphql.brandfetch.io' \
      --data '{"query":"query RetrieveWebhookDeliveries($webhookUrn: URN!) {\n  webhook(urn: $webhookUrn) {\n    url\n    urn\n    description\n    enabled\n    deliveries {\n      totalCount\n      edges {\n        node {\n          createdAt\n          deliveredAt\n          status\n          result {\n            body\n            headers {\n              name\n              value\n            }\n            message\n            statusCode\n          }\n        }\n      }\n    }\n  }\n}","variables":{"webhookUrn":"urn:brandfetch:organization:1234:webhook:1234"}}'
  ```

  ```GraphQL GraphQL theme={null}
  query RetrieveWebhookDeliveries($webhookUrn: URN!) {
    webhook(webhook: $webhookUrn) {
      url
      urn
      description
      enabled
      deliveries {
        totalCount
        edges {
          node {
            createdAt
            deliveredAt
            status
            result {
              body
              headers {
                name
                value
              }
              message
              statusCode
            }
          }
        }
      }
    }
  }

  # Example Variables: { "webhookUrn": "urn:brandfetch:organization:1234:webhook:1234" }
  ```
</CodeGroup>
