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

# Webhooks

> Receive real-time notifications when events occur in your Monk account

# Webhooks

Webhooks allow you to receive real-time HTTP notifications when events occur in your Monk account. Instead of polling the API for changes, webhooks push data to your server as events happen.

## How Webhooks Work

1. You configure a webhook endpoint URL in your [Settings](https://sandbox.monk.com/settings)
2. When an event occurs (e.g., an invoice is created), Monk sends an HTTP POST request to your endpoint
3. Your server processes the event and returns a `2xx` response to acknowledge receipt

<Info>
  Webhooks are sent asynchronously and may arrive out of order. Use the `id`
  field and timestamps to handle deduplication and ordering.
</Info>

## Setting Up Webhooks

### 1. Create an Endpoint

Navigate to **Settings → Webhooks** in your Monk dashboard and click **Add Endpoint**.

Provide:

* **URL**: Your HTTPS endpoint that will receive webhook events
* **Events**: Select which events to subscribe to

### 2. Get Your Signing Secret

After creating the endpoint, copy the signing secret. You'll use this to [verify webhook signatures](/api-reference/webhooks/verification).

<Warning>
  Store your signing secret securely. Never expose it in client-side code.
</Warning>

### 3. Handle Incoming Webhooks

Your endpoint should:

1. Verify the webhook signature
2. Process the event
3. Return a `2xx` status code quickly

```javascript theme={null}
// Example Express.js handler
app.post('/webhooks/monk', (req, res) => {
  const payload = req.body;
  const signature = req.headers['x-monk-signature'];

  // Verify signature (see Verification docs)
  if (!verifySignature(payload, signature, SIGNING_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  const event = req.headers['x-monk-event'];
  console.log(`Received ${event}:`, payload);

  // Acknowledge receipt
  res.status(200).send('OK');
});
```

## Webhook Headers

Each webhook request includes these headers:

| Header               | Description                          |
| -------------------- | ------------------------------------ |
| `Content-Type`       | Always `application/json`            |
| `User-Agent`         | `Monk-Webhook/1.0`                   |
| `X-Monk-Event`       | Event type (e.g., `invoice.created`) |
| `X-Monk-Delivery-Id` | Unique delivery ID for idempotency   |
| `X-Monk-Signature`   | Signature for verification           |

## Retry Policy

If your endpoint returns a non-`2xx` response or times out, Monk will retry delivery:

* **Total attempts**: 6 (1 initial + 5 retries)
* **Backoff**: Exponential with jitter (\~15s, 30s, 1m, 2m, 5m)
* **Timeout**: 10 seconds per attempt

After all retries are exhausted, the delivery is marked as failed.

## Best Practices

<AccordionGroup>
  <Accordion title="Return 2xx quickly">
    Webhook requests timeout after 10 seconds. Return a `200` response
    immediately, then process the event asynchronously in a background job if
    needed.
  </Accordion>

  <Accordion title="Handle duplicates">
    Use the `X-Monk-Delivery-Id` header or the payload `id` field to detect and
    ignore duplicate deliveries.
  </Accordion>

  <Accordion title="Always verify signatures">
    Never trust webhook payloads without [verifying the
    signature](/api-reference/webhooks/verification). This prevents spoofed
    requests.
  </Accordion>

  <Accordion title="Use HTTPS">
    We enforce HTTPS endpoints to ensure webhook payloads are encrypted in
    transit.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Webhook Events" icon="bell" href="/api-reference/webhooks/events">
    See all available events and their payload structures
  </Card>

  <Card title="Signature Verification" icon="shield-check" href="/api-reference/webhooks/verification">
    Learn how to verify webhook signatures
  </Card>
</CardGroup>
