> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tokenfactory.nebius.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Stream output and events

> Observe stdout, stderr, and operation events over SSE, resume after disconnect, and verify the final result.

The REST event endpoint exposes a server-sent events (SSE) stream for one operation. It carries primary-process and child-process events, including stdout, stderr, spawn, exit, and completion. The subscription observes execution; disconnecting it does not cancel the operation or extend its lifetime.

Complete [access setup](/sandboxes/start/set-up-access), create an operation, and keep its UUID. The end-to-end [streaming recipe](/sandboxes/cookbook/stream-a-build-or-test-run) runs a small test suite and includes a standard-library Python SSE client.

## Choose live or historical reading

Use `follow=1` to send available events and continue following an active operation. Use `follow=0` to read only the events currently available. Following requires the operation's spawn permission in addition to baseline list permission because the server keeps subscription state.

Every normal frame has an `id`, an `event` name, and JSON `data`. Keepalive comments start with `:` and contain no application event. An `sse_error` frame reports an in-band stream failure after HTTP `200` has already been sent.

The JSON object identifies the process with `spid`. The primary process is `spid=1`; additional subprocesses use `spid` values of 2 or greater. Add `spid=<id>` to the query when only one process is relevant.

## Decode output as it arrives

For `stdout` and `stderr` events, inspect `data.encoding` before displaying `data.value`. Decode `base64` values to bytes. An `ascii` value can be displayed as text. Preserve the channel label: stderr is useful even when the process ultimately succeeds.

Output chunks reflect process writes and buffering. They are not guaranteed to align with application lines. Ordering is represented by the event IDs in the combined stream; do not infer a stronger ordering guarantee between the operating system's stdout and stderr streams.

## Commit a resumable cursor

Parse a complete SSE frame, validate its JSON, perform the application's side effect, and only then save its event ID. The saved ID means “fully processed,” not merely “received from the socket.” If the connection breaks halfway through a frame, leave the cursor unchanged.

Reconnect with the last successfully processed ID:

```http theme={null}
GET /sandboxes/v1/operations/OPERATION_ID/events?follow=1 HTTP/1.1
Authorization: Bearer YOUR_API_KEY
Project: YOUR_PROJECT_ID
Last-Event-Id: 42
```

The service sends events after that ID. Consumers should still deduplicate by event ID so a crash between an external side effect and cursor persistence does not display or apply an event twice.

```mermaid theme={null}
%%{init: { "sequence": { "diagramMarginX": 10, "actorMargin": 25, "width": 100, "height": 40, "mirrorActors": false, "wrap": true } } }%%
sequenceDiagram
  participant Client
  participant Events
  participant Operation
  Client->>Events: Subscribe
  Events-->>Client: Event 42
  Note over Client: Process 42<br/>Save ID 42
  Note over Client,Events: Disconnected
  Note over Operation: Still running
  Client->>Events: Resume after 42
  Events-->>Client: Events after 42
  Client->>Operation: Get final status
  Operation-->>Client: Status and result
```

The cursor belongs to your event consumer. Reconnecting continues observation of the same operation; it does not submit the command again.

## Separate stream completion from execution success

An `exit` event reports that a process ended. A `completion` event describes operation completion. Neither replaces the final status query. After the stream closes, query `GET /operations/{operationId}` and check the terminal operation status, primary process exit code, signal, timeout flag, truncation flags, and any operation error.

If recorded output is truncated, the stream is not an unlimited log store. Use the final result and a retained file artifact when the workload requires complete output, subject to the documented retention rules.

## Recover observation failures

| Response or event | Action |
| - | - |
| Early connection close | Reconnect from the last processed event ID, then query final status if the operation may already be terminal. |
| `sse_error` | Treat the stream as broken, wait briefly, and reconnect from the last processed ID. |
| `410` or `425` | Honor `Retry-After` and retry the observation request. |
| `401` or `403` | Refresh the credential or obtain the required permission. |
| `502` or `504` while opening | Retry observation from the saved cursor. Do not resubmit the operation. |

The [SSE endpoint reference](/api-reference/sandboxes/operations/stream-the-operation-event-log-via-server-sent-events) defines the wire format, query parameters, permissions, event schemas, and errors. The [streaming recipe](/sandboxes/cookbook/stream-a-build-or-test-run) demonstrates progressive output, deliberate disconnect and resume, a successful test run, and a test run whose process exits nonzero.
