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

# SSE streaming

> Consume typed server-sent events with idle detection and Last-Event-Id reconnection.

export const RemoteContract = () => <Warning>
    <strong>Preview surface.</strong> The root package types the intended
    workflow HTTP and SSE API. The reference engine does not ship a compatible
    workflow service today. Do not point it at the stable resident firer or
    <code>nika model serve</code>.
  </Warning>;

<RemoteContract />

A dropped connection is not a completed workflow. The preview stream requires
a terminal event and reconnects from the last event id after transport loss.

## Consume the union

```ts theme={"system"}
for await (const event of nika.jobs.stream(job_id)) {
  switch (event.type) {
    case 'task_start':
      ui.start(event.task_id, event.verb)
      break
    case 'task_complete':
      ui.complete(event.task_id, event.duration_ms)
      break
    case 'artifact_written':
      ui.addArtifact(event.path, event.size)
      break
  }
}
```

Terminal types are `completed`, `failed` and `cancelled`.

## Tune the connection

```ts theme={"system"}
const events = nika.jobs.stream(job_id, {
  idleTimeout: 120_000,
  maxReconnects: 5,
  reconnectDelay: 2_000,
  signal: request.signal,
})
```

Set the idle timeout above the longest legitimate silence. Keep reconnects
bounded so an outage cannot pin a worker forever.

## Resume without duplicates

<div className="sdk-flight">
  <span>SSE CONTINUITY · LAST-EVENT-ID</span>

  <pre tabIndex={0}>
    {`id: 41  task_complete
             │
             × TCP connection closes
             │
             └── reconnect header: Last-Event-Id: 41
                                            │
                                            ▼
        id: 42  artifact_written`}
  </pre>
</div>

The parser accepts standard multi-line `data:` fields, tracks `id:` and ignores
comments and keep-alive frames.

## Failure rules

* User abort: stop, do not reconnect.
* Idle timeout: fail with `NikaTimeoutError`.
* Non-retryable client error: fail immediately.
* Transport close before a terminal event: reconnect within the cap.

## Continue

<CardGroup cols={2}>
  <Card title="Jobs" icon="list-check" href="/sdk/remote/jobs">
    Persist the identity before opening the stream.
  </Card>

  <Card title="Run events" icon="signal" href="/sdk/runtime/events">
    Build a tolerant presentation reducer.
  </Card>

  <Card title="Artifacts" icon="box-archive" href="/sdk/remote/artifacts">
    Follow artifact events to typed downloads.
  </Card>

  <Card title="Type index" icon="brackets-curly" href="/sdk/reference/types">
    Read the full discriminated union.
  </Card>
</CardGroup>
