# Subscribe to an event webhook

`POST /webhook.subscribe`

## Description

Create or update a webhook subscription for a given event. If a subscription
already exists for the same event and URL, its filter is updated instead of
creating a duplicate.

**Access:** Organization only.

**Required scope:** `webhook:write`

---

**OpenAPI Spec:** [webhooks.json](https://developer.ro.am/webhooks.json)

## Authentication

```
Authorization: Bearer YOUR_API_KEY
```

## Request Body

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `url` | string | Yes | Destination URL for webhook deliveries. HTTPS is required outside local environments. |
| `event` | "chat.message.dm" | "chat.message.channel" | "chat.message.reaction" | "recording.saved" | "transcript.started" | "transcript.saved" | "lobby.booked" | "user.status.update" | "onair.event.created" | "onair.event.updated" | "onair.event.canceled" | "onair.guest.rsvp" | "onair.guest.added" | Yes | Event to subscribe to. |
| `filter` | WebhookSubscriptionFilter | No |  |

**WebhookSubscriptionFilter**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `lobbyId` | string | No | For `lobby.booked`: restrict to bookings for the specified lobby. |
| `codes` | string[] | No | For `chat.message.reaction`: restrict to the specified reaction codes (e.g. 'thumbs_up', 'heart'). |
| `eventId` | string | No | For On-Air events (`onair.event.*`, `onair.guest.*`): restrict to the specified event. |
| `status` | "invited" | "going" | "maybe" | "notGoing" | No | For `onair.guest.rsvp`: restrict to the specified RSVP status. |

## Responses

### 200 - Subscription created or updated.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `id` | string | Yes | Unique identifier of the webhook subscription. |
| `event` | "chat.message.dm" | "chat.message.channel" | "recording.saved" | "transcript.saved" | "lobby.booked" | "onair.event.created" | "onair.event.updated" | "onair.event.canceled" | "onair.guest.rsvp" | "onair.guest.added" | Yes | Subscribed event name. |
| `url` | string | Yes | Destination URL for webhook deliveries. |
| `filter` | WebhookSubscriptionFilter | No | Event-specific filter applied to the subscription. |

**WebhookSubscriptionFilter**:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `lobbyId` | string | No | For `lobby.booked`: restrict to bookings for the specified lobby. |
| `codes` | string[] | No | For `chat.message.reaction`: restrict to the specified reaction codes (e.g. 'thumbs_up', 'heart'). |
| `eventId` | string | No | For On-Air events (`onair.event.*`, `onair.guest.*`): restrict to the specified event. |
| `status` | "invited" | "going" | "maybe" | "notGoing" | No | For `onair.guest.rsvp`: restrict to the specified RSVP status. |


#### Example Response

```json
{
  "id": "19c6401f-6d02-4d8c-87c5-9fc45f02f4b5",
  "event": "lobby.booked",
  "url": "https://example.com/hooks/lobby-booked",
  "filter": {
    "lobbyId": "L-12345"
  }
}
```

### 400 - Bad request.

### 401 - Presented invalid authentication credentials.

### 500 - An internal error occurred.

---

*Machine-readable API documentation.*
*Full documentation: https://developer.ro.am/docs/webhooks/webhook-subscribe*
