# Stream events and live drafts for one app

Stream one app's events. Server-sent events: the event name is the event type and data is the event JSON. Resume with Last-Event-ID (or cursor) set to the SSE id field and deduplicate by the JSON event id. Heartbeats arrive every 15 seconds, when authorization, including the organization's Platform API access, is revalidated. A stream open when the app is deleted receives platform.app.deleted. With threadId, draft frames carry the assistant's in-progress reply and draft.removed clears one; drafts have no cursor or replay guarantee.

`GET /api/platform/v1/apps/{appId}/events/stream`

Required permission: `thread:read`.

## Parameters

| Name | In | Type | Required | Description |

| --- | --- | --- | --- | --- |

| `threadId` | query | `string` | No | Only this thread's events. |

| `runId` | query | `string` | No | Only this run's events. |

| `types` | query | `string` | No | Comma-separated event types, at most 30. Reuse identical filters with a returned cursor. |

| `cursor` | query | `string` | No | A head, nextCursor or event cursor. Omit to start at the oldest retained event. |

| `limit` | query | `integer` | No | Maximum events per page, 1-500 (default 100). |

| `appId` | path | `string` | Yes | — |

## Example request

```bash
curl --request GET \
  --url https://api.hoplite.sh/api/platform/v1/apps/appId/events/stream \
  --header "X-Api-Key: $HOPLITE_API_KEY"
```

## 200 response

Success

Content type: `text/event-stream`. Response type: `string`.

```text

```

## Status codes

- `200` — Success

- `400` — Invalid request

- `401` — Authentication required

- `403` — Permission, app scope or entitlement denied

- `404` — App, source or thread not found

- `409` — Idempotency conflict or request in progress

- `410` — Event cursor expired

- `413` — Request too large

- `503` — Source storage or execution unavailable