# Receive events with webhooks

Webhooks tell your systems the moment something happens in Relaypoint, so you don't need to poll the API. Relaypoint sends an HTTPS `POST` with a JSON body to the URL you choose.

## Add an endpoint

1. Go to **Settings › Integrations › Webhooks** and select **Add endpoint**.
2. Enter your URL, e.g. `https://example.com/hooks/relaypoint`.
3. Pick the events you want, or **All events**.
4. Copy the **signing secret**. You'll use it to verify each delivery.

## Events

| Event                   | Sent when                                 |
| ----------------------- | ----------------------------------------- |
| `conversation.created`  | A new conversation arrives on any channel |
| `conversation.assigned` | The assignee or team changes              |
| `conversation.closed`   | A conversation is closed                  |
| `message.created`       | A customer or agent adds a message        |
| `satisfaction.received` | A customer rates a conversation           |

## Verify the signature

Every delivery carries a `Relaypoint-Signature` header: an HMAC-SHA256 of the raw body, keyed with your signing secret. Reject anything that doesn't match.

:::tabs
@tab Node.js

```javascript
import crypto from 'node:crypto';

export function isValid(rawBody, header, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(header));
}
```

@tab Python

```python
import hashlib
import hmac

def is_valid(raw_body: bytes, header: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)
```
:::

:::warning Respond quickly
Reply with any `2xx` status within **10 seconds**, then do the slow work in a background job. Slower responses count as failures.
:::

## Retries

Failed deliveries are retried with exponential backoff for **24 hours**. After that the delivery is dropped, and after 3 days of failures the endpoint is paused and Admins get an email. You can replay any delivery from the endpoint's **Deliveries** tab.
