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

# Create a webhook

> Register a webhook endpoint in the business portal or through the API.

You can register webhooks in the business portal or through the gateway API.
The portal is the easiest way to register several event types at once; the API
is useful for automation.

## Register in the business portal

<Steps>
  <Step title="Open Webhooks">
    Sign in to the business portal, open the **Settings** menu, and choose
    **Webhooks**.

    <Frame caption="Settings menu with Webhooks selected.">
      <img src="https://mintcdn.com/paytectechnologies/NqhoOkOWg2Ny5E8p/images/webhooks/settings-menu.png?fit=max&auto=format&n=NqhoOkOWg2Ny5E8p&q=85&s=884dc9cc24f3cc24fb8b60136acceed6" alt="The business portal Settings dropdown menu with the Webhooks item highlighted." width="1142" height="642" data-path="images/webhooks/settings-menu.png" />
    </Frame>
  </Step>

  <Step title="Start a registration">
    On the Webhooks page, select **Register webhook**. Before any endpoint is
    registered, the page shows an empty state.

    <Frame caption="The Webhooks page before any endpoint is registered.">
      <img src="https://mintcdn.com/paytectechnologies/NqhoOkOWg2Ny5E8p/images/webhooks/webhooks-empty.png?fit=max&auto=format&n=NqhoOkOWg2Ny5E8p&q=85&s=41f47c082ef3dc6869b493d6a310c58f" alt="The Webhooks page empty state, reading No webhooks yet, with a Register webhook button." width="1600" height="860" data-path="images/webhooks/webhooks-empty.png" />
    </Frame>
  </Step>

  <Step title="Enter the endpoint and events">
    Enter the **Endpoint URL** and select the **Event types** to send to it.
    Events that already have a registration are disabled here; edit or disable
    the existing webhook to change them.

    <Frame caption="The Register webhook dialog with an endpoint URL and event types selected.">
      <img src="https://mintcdn.com/paytectechnologies/NqhoOkOWg2Ny5E8p/images/webhooks/register-webhook.png?fit=max&auto=format&n=NqhoOkOWg2Ny5E8p&q=85&s=62ad08a9fd1b44c6ef6fb04b9f20f2d1" alt="The Register webhook dialog with an endpoint URL entered and several payment intent event types selected via checkboxes." width="1236" height="1366" data-path="images/webhooks/register-webhook.png" />
    </Frame>

    Select **Register**. The portal creates one registration per selected event
    type.
  </Step>

  <Step title="Review your registrations">
    Registered webhooks are listed with their **Event**, **Endpoint URL**,
    **Status**, and timestamps. From here you can send a test event, edit,
    disable, or view details.

    <Frame caption="The Webhooks page listing registered endpoints.">
      <img src="https://mintcdn.com/paytectechnologies/NqhoOkOWg2Ny5E8p/images/webhooks/webhooks-list.png?fit=max&auto=format&n=NqhoOkOWg2Ny5E8p&q=85&s=c324e818a96f2f56ec24e59d1b57e507" alt="The Webhooks page listing several registered webhooks, each with an event name, endpoint URL, an Active status, created and updated timestamps, and per-row actions." width="1600" height="1148" data-path="images/webhooks/webhooks-list.png" />
    </Frame>
  </Step>
</Steps>

## One registration per event type

There is exactly **one active registration per association and event type**.
Registering a type that already has one is rejected. To point an event at a
different URL, edit or disable the existing registration first.

<Warning>
  Disabling a webhook is permanent. The registration is deactivated and retained
  but cannot be reactivated. To receive that event type again, register a fresh
  webhook.
</Warning>

## Send a test event

The portal can send a **test event** to an active registration, so you can
confirm your endpoint receives and acknowledges deliveries before relying on
real traffic.

## Register through the API

The gateway exposes the same registrations. Each call registers or affects one
event type. All requests require the standard
[authentication headers](/authentication/overview).

<CodeGroup>
  ```bash Register theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  curl -sS -X POST https://api.zeam.money/gw/v1/webhooks \
    -H "Authorization: Bearer $ZEAM_TOKEN" \
    -H "x-zeam-auth: $ZEAM_APP_SECRET" \
    -H "x-association-id: $ZEAM_ASSOCIATION_ID" \
    -H "Content-Type: application/json" \
    -d '{ "url": "https://example.com/zeam/webhooks", "type": "IntentSuccessful" }'
  ```

  ```bash List theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  curl -sS https://api.zeam.money/gw/v1/webhooks \
    -H "Authorization: Bearer $ZEAM_TOKEN" \
    -H "x-zeam-auth: $ZEAM_APP_SECRET" \
    -H "x-association-id: $ZEAM_ASSOCIATION_ID"
  ```

  ```bash Deactivate theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
  curl -sS -X DELETE https://api.zeam.money/gw/v1/webhooks/$WEBHOOK_ID \
    -H "Authorization: Bearer $ZEAM_TOKEN" \
    -H "x-zeam-auth: $ZEAM_APP_SECRET" \
    -H "x-association-id: $ZEAM_ASSOCIATION_ID"
  ```
</CodeGroup>

* `POST /v1/webhooks` registers one event `type` for a `url` and returns `201`
  with the new `id`. A duplicate type returns `409`.
* `GET /v1/webhooks` lists registrations; `GET /v1/webhooks/{webhookId}` returns
  one.
* `DELETE /v1/webhooks/{webhookId}` deactivates a registration (`204`) and, like
  the portal, cannot be undone.

See the [API reference](/api-reference/introduction) for the full contracts, and
[Events](/webhooks/events) for the values `type` accepts.

## Endpoint requirements

* Use **HTTPS** in production and be publicly reachable by Zeam. Plain http is
  tolerated in the [sandbox](/access/sandbox) only.
* Respond quickly with a `2xx`, then hand processing to a background worker.
* Expect retries and possible duplicate deliveries; handle them idempotently.
* Reconcile by identifier rather than delivery order. See
  [Security](/webhooks/security).
