# Follow a session live

`GET /o/{org}/p/{project}/sessions/{session}/events`

A server-sent event stream of the run as it happens. Before the sandbox
starts you get `status` events (`{status}`); then the harness's own
events, each with an `id`. The stream ends with `done`, whose data is
`{status, output, result}`: `result` is the `SessionAnswer`, or null when
the run produced none. `error` (`{message}`) ends it early. Reconnect
with `Last-Event-ID` (or `?cursor=`) to resume after the last event you
saw. Comment lines (`: keepalive`) keep idle connections open.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `org` | path | string | yes | The org's slug or id. A caller with no role in the org gets `404`. |
| `project` | path | string | yes | A Project's handle (name) or id, resolved inside `{org}` — OR the reserved sentinel `_` meaning "no Project" (a direct-repo / repo-less dispatch on `POST`; "no Project constraint, resolve by session id alone" everywhere else). A real handle that doesn't match the session's actual Project is `404`.  |
| `session` | path | string | yes | The session's full id (`execution_id`). |
| `Last-Event-ID` | header | string | no | Resume after this event id. |
| `cursor` | query | string | no | Same as `Last-Event-ID`, for clients that cannot set headers. |

## Example request

```bash
curl -N "https://api.prix.dev/o/$RUSH_ORG/p/_/sessions/$SESSION_ID/events" \
  -H "Authorization: Bearer $RUSH_API_KEY" \
  -H "Accept: text/event-stream"
```

```typescript
const org = process.env.RUSH_ORG;
const sessionId = process.env.SESSION_ID;

const res = await fetch(`https://api.prix.dev/o/${org}/p/_/sessions/${sessionId}/events`, {
  headers: {
    Authorization: `Bearer ${process.env.RUSH_API_KEY}`,
    Accept: "text/event-stream",
  },
});

// Each frame is `event: <type>` and `data: <json>`, then a blank line.
const decoder = new TextDecoder();
for await (const chunk of res.body!) {
  process.stdout.write(decoder.decode(chunk, { stream: true }));
}
```

```python
import os

import requests

org = os.environ["RUSH_ORG"]
session_id = os.environ["SESSION_ID"]

res = requests.get(
    f"https://api.prix.dev/o/{org}/p/_/sessions/{session_id}/events",
    headers={"Authorization": f"Bearer {os.environ['RUSH_API_KEY']}", "Accept": "text/event-stream"},
    stream=True,
)

for line in res.iter_lines(decode_unicode=True):
    print(line)
```

## Responses

### 200

The event stream.

### 401

No bearer, an unknown, revoked or expired one, or an API key on a route keys cannot call.

### 404

No such resource for the caller, including one that exists in an org the caller cannot see.

## Example response (200)

```http
event: status
data: {"status":"allocating","id":"3f9c2a71d04b8e65"}

event: done
data: {"status":"completed","output":"runtime: guest harness completed","result":{"text":"Pinned the clock in checkout.spec.ts.","structured":null,"schema_valid":null}}
```
