# Events, watch & webhooks

> The event journal, reconnectable long-poll watch, and webhook destinations.

Source: https://docs.getrunstate.com/api/events/

<!-- Generated by apps/docs/scripts/gen-api.mjs from packages/contracts/openapi.yaml. Do not edit. -->

All paths are relative to the API base URL (`https://api.getrunstate.com`) and require `Authorization: Bearer <api key>`. See [the API overview](https://docs.getrunstate.com/api/) for authentication, idempotency and the error envelope.

## POST /destinations

```http
POST /v1/spaces/{spaceId}/destinations
```

Register webhook destination; signing secret returned once.

- **Key permission:** `coordination_write`
- **Idempotency-Key header:** required

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Request body** (JSON)

| Field | Type | Required | Notes |
| --- | --- | --- | --- |
| `url` | string (uri) | yes | pattern `^https?://` |
| `eventTypes` | array of string | no | default `[]` |

**Responses**

| Status | Meaning |
| --- | --- |
| `201` | Destination id and signingSecret |

```bash
curl -X POST "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/destinations" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"url":"<url>"}'
```

## GET /events

```http
GET /v1/spaces/{spaceId}/events
```

Durable event catch-up with settle window.

- **Key permission:** `coordination_read`
- **TypeScript SDK:** `rs.events.list()`
- **Python SDK:** `rs.events.list()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Query parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `cursor` | string |  |
| `limit` | integer | max 500; default `100` |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Events page with nextCursor |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/events" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```

## GET /deliveries

```http
GET /v1/spaces/{spaceId}/deliveries
```

Per-attempt webhook delivery audit, most recent first.

- **Key permission:** `coordination_read`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Delivery history rows |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/deliveries" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```

## GET /watch

```http
GET /v1/spaces/{spaceId}/watch
```

Reconnectable long-poll over events; filters by types, aggregate, scopeId; waitSeconds 0-30.

At-least-once, ordered by event_id. Clients persist nextCursor and re-issue it to reconnect, deduplicating by eventId. Aborting the request cancels the hold. scopeId matches scope aggregates in the subtree or events whose payload carries a scopeId in the subtree. Use webhooks for server-to-server push; watch is for workers and consoles that can hold a connection.

- **Key permission:** `coordination_read`
- **TypeScript SDK:** `rs.events.watch()`
- **Python SDK:** `rs.events.watch()`

**Path parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `spaceId` | string (uuid) | required |

**Query parameters**

| Name | Type | Notes |
| --- | --- | --- |
| `cursor` | string |  |
| `types` | string |  |
| `aggregate` | string |  |
| `scopeId` | string (uuid) |  |
| `limit` | integer |  |
| `waitSeconds` | integer | 0–30 |

**Responses**

| Status | Meaning |
| --- | --- |
| `200` | Events page with nextCursor |
| `400` | Error envelope `{"error":{"code","message","requestId"}}` |

```bash
curl -X GET "$RUNSTATE_BASE_URL/v1/spaces/$RUNSTATE_SPACE_ID/watch" \
  -H "Authorization: Bearer $RUNSTATE_API_KEY"
```
