# watch

> Show your agent's screen live, and let a person take control.

Show a user's Bash at work on its own computer, live. Open a session to get a link to that computer's screen, for a browser tab or an iframe. With control turned on, a person can take over the mouse and keyboard, then hand control back to Bash.

## TypeScript

```ts
const traveller = vestra.user('traveller-42');

// Watch the screen live. Open session.url in a browser tab or an iframe.
const session = await traveller.watch();
console.log(session.url, session.expires_at);

// Let a person take control. They can take over from Bash, hand control back, and end the session.
const wheel = await traveller.watch({ control: true });
await wheel.take();
await wheel.giveBack();
await wheel.end();

// Take a screenshot. You get the latest frame of their browser as a JPEG.
const jpeg = await traveller.screenshot();
console.log(jpeg.byteLength);
```

## Python

```python
traveller = vestra.user("traveller-42")

# Watch the screen live. Open session.url in a browser tab or an iframe.
session = traveller.watch()
print(session.url, session.expires_at)

# Let a person take control. They can take over from Bash, hand control back, and end the session.
wheel = traveller.watch(control=True)
wheel.take()
wheel.give_back()
wheel.end()

# Take a screenshot. You get the latest frame of their browser as a JPEG.
print(len(traveller.screenshot()))
```

## CLI

```bash
# Watch the screen live. You get a link to their screen, valid for 15 minutes.
vestra watch --user traveller-42

# Let a person take control. With --control, whoever opens the link can take over from Bash.
vestra watch --user traveller-42 --control
```

## HTTP

```bash
# Watch the screen live. Create a session with a screen to watch, and open its url in a browser tab or an iframe.
curl "$VESTRA_BASE_URL/v1/sessions" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_id": "traveller-42", "screen": "view" }'

# Let a person take control. In a session opened with "screen": "control", the person can take over from Bash,
# using the session's own token.
curl "$VESTRA_BASE_URL/v1/sessions/ses_8h2/screen" \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "action": "take" }'

# Take a screenshot. You get the latest frame of the user's browser as a JPEG.
curl "$VESTRA_BASE_URL/v1/users/traveller-42/screenshot" \
  -H "Authorization: Bearer $VESTRA_API_KEY" \
  -o screen.jpg
```

## MCP

```json
{
  "method": "tools/call",
  "params": {
    "name": "watch",
    "arguments": { "user": "traveller-42", "control": true }
  }
}
```

## Good to know

### What a session is

`watch`, `talk` and [`embed`](https://vestra.ai/developers/embed.md) all open a session (`POST /v1/sessions`): a short-lived link for one user. A session's `url` carries its own token, valid for 15 minutes. The token can only reach that user and the session's conversation, and it never shows what anything costs.

### Who has control

The `screen.control` event says when the person takes control and when Bash has it back. Each call to `GET /v1/sessions/{id}/screen` makes new credentials for the screen's stream, and each set lasts 5 minutes.

### Screenshots

`GET /v1/users/{id}/screenshot` returns the latest frame of the user's browser as a JPEG.

## The routes behind watch

- `GET` [/v1/sessions/{session_id}/screen](https://vestra.ai/developers/reference/api/sessions/get-v1-sessions-session-id-screen.md): With the session's token: the stream credentials of the user's Bash browser, good for 5 minutes. For a session opened with a screen. 409 payment_in_progress while the person pays for something in their browser.
- `POST` [/v1/sessions/{session_id}/screen](https://vestra.ai/developers/reference/api/sessions/post-v1-sessions-session-id-screen.md): With the session's token, in control mode: the user takes the wheel or gives it back (action), or says they are driving (input), so Bash waits.
- `GET` [/v1/users/{user_id}/screenshot](https://vestra.ai/developers/reference/api/sessions/get-v1-users-user-id-screenshot.md): The latest frame of the user's browser, as a JPEG. 409 browser_in_use while a person finishes a sign-in on it (a browser fetch with front open): its page is for them alone. 409 payment_in_progress while the person pays for something in their browser, or just after. Key scope: `runtime` (or `all`).
- `GET` [/v1/users/{user_id}/browser/watch](https://vestra.ai/developers/reference/api/computer-setup/get-v1-users-user-id-browser-watch.md): Watch the browser fetch's tabs live, as text/event-stream. Read only: allowed sites only, a tab on a blocked path is hidden, and it never wakes the computer. Key scope: `runtime` (or `all`).

Next: [`talk`](https://vestra.ai/developers/talk.md)
