# GET /v1/conversations/{conversation_id}/events

> The one stream (SSE): replies as they are typed, work started and finished, progress, approvals, tool calls, files.

In [Conversations API](https://vestra.ai/developers/reference/api/conversations.md): Ask Bash in a conversation, follow its reply as it happens, and stop it.

Send `Authorization: Bearer vk_test_...` on every call.

The one stream (SSE): replies as they are typed, work started and finished, progress, approvals, tool calls, files. Resume with Last-Event-ID. Filter to one task's events with task_id.

Your API key, or a session's token, scope `runtime` or `all`. On the card: [`events`](https://vestra.ai/developers/events.md). Every call here is a checked sample.

## Request

Path:

- `conversation_id` (`string`, required): The conversation's id (`conv_...`).

Query:

- `format` (`"sse" | "json"`): sse follows the events as they happen (text/event-stream); json reads one page of them. Default: sse.
- `after` (`integer`): Only events after this seq. On the stream, a Last-Event-ID header does the same. Absent: from the first kept event.
- `limit` (`integer`): With format json: at most this many events, 1 to 500. Default: 100.
- `task_id` (`string`): Only this task's events (task_...).

Headers:

- `Last-Event-ID` (`string`): Resume after this event id.

## Answers 200

A stream of events; with format=json, a page of them.

- `data` (`object[]`): The events, oldest first.
  - `seq` (`integer`): Its place on the conversation's stream, counting up: send the last one you saw to pick up after it.
  - `type` (`string`): What happened, from the one catalog of events: the events reference says what each carries and where it is delivered. Limits: one of 34 values. Example: `message.completed`.
  - `data` (`map of any`): What it says: its fields depend on its type, as the events reference lists them.
  - `created_at` (`string`): When it happened, as an ISO 8601 time.
- `next_after` (`integer`): The seq to send as after for the next page: the last one here, or the after you sent (0 without one) when the page is empty.

## Code

**TypeScript**

```ts
for await (const event of vestra.events('conv_8f2k')) {
  if (event.type === 'message.completed') break;
}
```

**Python**

```python
for event in vestra.events("conv_8f2k"):
    if event.type == "message.completed":
        break
```

**CLI**

```bash
vestra events conv_8f2k
```

**HTTP**

```bash
# Stream a conversation live. If the connection drops, reconnect with the last seq you saw.
curl -N "$VESTRA_BASE_URL/v1/conversations/conv_8f2k/events" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Last-Event-ID: 41"

# Read the same events as JSON. You get them in pages, after the seq you give.
curl "$VESTRA_BASE_URL/v1/conversations/conv_8f2k/events?format=json&after=41" \
  -H "Authorization: Bearer $VESTRA_API_KEY"

# Read a task afterwards. You get every step of one task, with tokens and cost per turn.
curl "$VESTRA_BASE_URL/v1/tasks/task_91d/trace" \
  -H "Authorization: Bearer $VESTRA_API_KEY"

# Send events to your server. Register a URL and the events it wants. The signing secret is shown only once.
curl "$VESTRA_BASE_URL/v1/webhooks" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://hooks.example.com/vestra", "events": ["task.completed", "interaction.created", "usage.cap_reached"] }'

# Catch up on what you missed. List the events your webhooks were sent, newest first.
curl "$VESTRA_BASE_URL/v1/events?type=task.failed" \
  -H "Authorization: Bearer $VESTRA_API_KEY"
```

**MCP**

```json
{
  "method": "tools/call",
  "params": {
    "name": "events",
    "arguments": { "user": "traveller-42", "conversation": "conv_8f2k", "after": 0 }
  }
}
```
