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

# Sandbox events

> Consume the curated SSE stream, resume safely, and reconcile event history.

Sandbox events use one versioned envelope across SSE and JSON history:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
	"id": "1042",
	"object": "sandbox.event",
	"version": "v1",
	"type": "message.updated",
	"ts": "2026-08-06T12:00:00.000Z",
	"sandbox_id": "c_…",
	"turn_id": "turn_…",
	"data": {}
}
```

Payloads are curated. Sparkles never forwards a raw agent-runtime event, tool payload, credential, internal session identifier, or compatibility `raw` field.

## Event types

| Type                 | Meaning                                                       |
| -------------------- | ------------------------------------------------------------- |
| `snapshot`           | Current resource and turn state sent when a stream connects.  |
| `sandbox.status`     | Transient lifecycle update during boot or state changes.      |
| `turn.started`       | A prompt began a new turn.                                    |
| `turn.completed`     | A turn settled as `succeeded`, `failed`, or `canceled`.       |
| `message.updated`    | Latest snapshot of one assistant message part.                |
| `message.completed`  | The assistant's final message for a turn.                     |
| `tool.updated`       | Curated tool-call state changed.                              |
| `approval.requested` | A tool is waiting for an approval decision.                   |
| `approval.resolved`  | A pending approval was approved, denied, canceled, or failed. |
| `sandbox.error`      | A public, sanitized execution error occurred.                 |

Unknown internal event types are explicitly dropped by the translation layer.

## Snapshot semantics

`message.updated` is last-write-wins. Use `part_id` as the key and replace the stored snapshot instead of concatenating deltas. A later `message.completed` marks the assistant result as final.

## Resume and replay

Durable frames have an SSE `id` equal to the coordinator event sequence. `snapshot` and transient `sandbox.status` frames intentionally have no SSE ID because they cannot be rewound.

On reconnect, send the last processed durable ID in `Last-Event-ID`. The `since` query parameter is the fallback for clients that cannot set the header. A fresh connection starts with a snapshot and follows the live tail; request `?since=0` to replay retained history.

The stream sends keepalive pings and can cover the complete create-to-boot window before an agent session exists. Network delivery is at least once within retention. Deduplicate by durable `id`, and use the JSON events page plus `GET /sandboxes/{id}` to recover from a stale or pruned cursor.

Browser `EventSource` cannot set the bearer authorization header. Use a fetch-based SSE reader.
