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

# Overview

> Get notified of changes by receiving events at your webhook URL.

## Why use webhooks

When building Brandfetch integrations, you might want your applications to receive events as they occur for brands you're interested in, so that your backend systems can execute actions accordingly.

To enable webhook events, you need to [register webhook endpoints](/delivery-methods/webhooks/setup#register-your-endpoint). After you register them, Brandfetch can push real-time event data to your application’s webhook endpoint when things happen. Brandfetch sends each event to your endpoint as a JSON `POST` over HTTPS. Deliveries follow version 1 of the [Standard Webhooks](https://www.standardwebhooks.com) specification, so you can verify them with an [official library](/delivery-methods/webhooks/best-practices#verify-with-an-official-library).

Receiving webhook events is particularly useful for listening to asynchronous events such as when a brand’s logo changes, a company detail is updated, or when we index new data.

## Pricing and eligibility

Webhooks are available on every paid plan, with no contract and no sales call. They do require an active paid subscription, either a self-serve plan or a custom contract: without one, creating a webhook is declined with the code `NO_ACTIVE_SUBSCRIPTION` and the message "Webhooks require an active paid subscription."

Registering an endpoint costs nothing, and neither does receiving deliveries, however many events your brands generate. What consumes API credits is each brand you subscribe a webhook to.

| Action | Cost |
| - | - |
| Registering a webhook endpoint | Free |
| Receiving event deliveries | Free, at any volume |
| Subscribing a webhook to a brand | 1 API credit, charged on creation |
| Holding that subscription into a new calendar month | 1 API credit per month |
| Subscribing to `brandfetch.com` | Free of credits |

The creation credit is consumed as soon as the subscription exists, even if you remove it moments later, and it is not pro-rated. There are no refunds, so removing a brand and adding it back charges again. A subscription you created during the current month has already paid for that month, and renews at the start of the next one.

<Note>
  Subscribing to `brandfetch.com` is free of credits, so you can wire up an endpoint and test it end to end without spending anything. The exemption covers credits only: the subscription still occupies one of your plan's subscription slots, like any other.
</Note>

### Limits

| Limit | Value |
| - | - |
| Brand subscriptions held at once, across all of your webhooks | Your plan's monthly API credit allowance |
| Webhook endpoints per organization | 100 |

Prepaid credit packs pay for subscription charges, but they do not raise the subscription limit; that limit follows your plan's monthly allowance, so upgrading is what raises it. If your plan's allowance is unlimited, this limit will not be a practical constraint.

The subscription limit is checked when you add subscriptions, not maintained continuously, so a plan downgrade does not remove anything you already hold. What it changes is your next monthly renewal: if the renewal charge no longer fits your allowance plus any prepaid credits, your webhooks are paused, as described below.

| Denial | Code |
| - | - |
| Adding subscriptions past the subscription limit | `CAPACITY_EXCEEDED` |
| Adding more subscriptions than your remaining credits cover | `INSUFFICIENT_CREDITS` |
| Registering an endpoint when you already hold 100 | `WEBHOOK_LIMIT_REACHED` |

Delete unused endpoints before registering another.

### When a renewal cannot be funded

Monthly renewals never spill into overage billing. They are paid from your monthly allowance plus any prepaid credits, and when that is not enough, we pause your organization's webhooks rather than bill you for the difference. The same pause applies if the paid subscription itself lapses.

While webhooks are paused:

* Deliveries stop. Events that fire during the pause are skipped rather than held back, so they are not replayed once deliveries resume.
* Creating webhooks and adding subscriptions are declined with the code `BILLING_HOLD`.
* Your endpoints, their subscriptions, and their configuration all stay exactly as they were.

| What you do | When deliveries resume |
| - | - |
| Remove enough subscriptions to fit within your credits | Usually as part of the removal itself, otherwise within 24 hours |
| Buy more credits, or upgrade your plan | Within 24 hours |
| Restore a lapsed paid subscription | Within 24 hours |

Removing subscriptions is re-checked during the removal, so it normally lifts the pause on the spot. Every remedy is also picked up by a daily check, which is where the 24 hour figure comes from.

<Warning>
  Disabling a webhook stops its deliveries, but its subscriptions stay in place and keep renewing every month. Deleting the subscriptions is what stops the charge.
</Warning>

If a payment fails, your existing webhooks keep running and keep renewing, but new webhooks and new subscriptions are declined with the code `PAYMENT_FAILED` until you update your payment method.

## Event overview

<Info>
  Brandfetch implements version 1.0.0 of the [Standard
  Webhooks](https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md)
  specification. Verify deliveries with the [official Standard Webhooks
  libraries](https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries),
  or follow [Verify without a
  library](/delivery-methods/webhooks/best-practices#verify-without-a-library).
</Info>

Brandfetch generates event data that we can send you to inform you of brand activity.

When an event occurs, Brandfetch generates a new event object. A single API request might result in the creation of multiple events. For example, if we re-index a brand, you may receive `brand.company.updated` and `brand.updated` events.

By registering webhook endpoints with Brandfetch, you enable us to automatically send event payloads as part of POST requests to the registered webhook endpoint hosted by your application. After your webhook endpoint receives the event payload, your app can run backend actions (for example, updating your database after you receive a `brand.updated` event).

### Event payload

Each delivery carries a snapshot of the brand the event is about. It does not say which fields changed. If you need to know, compare the snapshot with the copy you stored.

See the full [list of event types](/delivery-methods/webhooks/event-types) that we can send to your webhook.

### Example event payload

The following delivery reports an update to the Brandfetch brand. `data.object` is shortened here.

<CodeGroup>
  ```JSON JSON theme={null}
  {
    "data": {
      "object": {
        "__typename": "Brand",
        "id": "idL0iThUh6",
        "name": "Brandfetch",
        "domain": "brandfetch.com",
        "claimed": true
      },
      "urn": "urn:brandfetch:brand:idL0iThUh6"
    },
    "delivery": "urn:brandfetch:organization:0123:webhook:1234:delivery:5678",
    "timestamp": "2026-09-23T10:15:00.123Z",
    "type": "brand.updated",
    "webhook": "urn:brandfetch:organization:0123:webhook:1234"
  }
  ```

  ```TypeScript TypeScript theme={null}
  interface WebhookEventPayload {
    readonly data: {
      readonly object: Record<string, unknown>;
      readonly urn: string;
    };
    readonly delivery: string;
    readonly timestamp: string;
    readonly type: string;
    readonly webhook: string;
  }
  ```
</CodeGroup>

| Field | Description |
| - | - |
| `type` | The event type, such as `brand.updated`. |
| `timestamp` | When the event happened, in ISO 8601. It is the same on every attempt. |
| `data.urn` | The URN of the brand the event is about. |
| `data.object` | The brand, as described [below](#data-object). |
| `webhook` | The URN of the webhook receiving the delivery. |
| `delivery` | The URN of this delivery attempt. Every attempt, retries included, gets a new one. |

### Request headers

Every delivery is a `POST` with these headers:

| Header | Value |
| - | - |
| `content-type` | `application/json` |
| `user-agent` | `Brandfetch-Hookshot/<version>` |
| `webhook-id` | The ID of this message: one event sent to one webhook. It is the same on every retry of the message. [Deduplicate](/delivery-methods/webhooks/best-practices#handle-duplicate-events) on it. |
| `webhook-timestamp` | When this attempt was sent, as a Unix timestamp in seconds. |
| `webhook-signature` | `v1,` followed by the base64 signature. See [how to verify it](/delivery-methods/webhooks/best-practices#verify-events-are-sent-from-brandfetch). |
| `webhook-delivery-id` | The ID of this attempt. Every attempt gets a new one. |
| `authorization` | The `Authorization` header you set with `urlHeaders`, if you set one. |

### Event type

You receive events for all of the event types your webhook endpoint is listening for in your configuration. Use the received event type to determine what processing your application needs to perform. Every event you can subscribe to is a `brand.*` event, so `data.object` is always a brand.

### Data object

`data.object` follows the shape of the [Brand API](/brand-api/overview) response. Brandfetch reads the brand when the event happens, and every retry carries that same snapshot. Fetch the brand from the Brand API if you need its current state.

A `brand.deleted` event reports a deleted brand, so its `data.object` carries only `__typename`, `id`, `name`, `domain`, and `urn`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.