## Stream API Overview

The Stream API provides real-time speech-to-speech translation over a single persistent WebSocket connection. It supports both **consecutive mode** (speak, wait, hear translation) and **simultaneous mode** (continuous translation as you speak). This page covers the WebSocket transport: endpoint, authentication, audio frames, connection errors, and connection lifetime. For the shared application message layer, including `init`, `configure`, `flush`, and server events, see the [Stream message layer](https://developer.sanas.ai/Docs/Language-Translation/Stream-Message-Layer).

## Endpoint

```
WebSocket: wss://api.sanaslt.com/v3/stream
```

## Authentication

Authentication is provided via query parameters. Provide **one** of the following:

| Parameter | Description |
| --- | --- |
| `token` | JWT Bearer token (from Supabase) |
| `api_key` | API key |

Example connection URLs:

```
wss://api.sanaslt.com/v3/stream?token=<jwt_token>
wss://api.sanaslt.com/v3/stream?api_key=<api_key>
```

Authentication is validated **before** the WebSocket upgrade. On failure, the server returns HTTP 401, not a WebSocket close frame.

## Transport Model

- Send Stream JSON messages as WebSocket text frames.
- Send input audio as raw PCM bytes in WebSocket binary frames after receiving `configured`.
- Receive output audio as raw PCM bytes in WebSocket binary frames.
- Do not wrap audio in JSON or base64.

For message schemas, usage modes, and examples, see the [Stream message layer](https://developer.sanas.ai/Docs/Language-Translation/Stream-Message-Layer).

## Connection Lifecycle

Server | Client  
--- | ---  
opt[Manual turn finalization] | opt[End session]  
WebSocket connect with auth | 1  
Send init text frame | 2  
Send configure text frame | 3  
Send configured text frame | 4  
Stream input audio as binary frames | 5  
Send Stream events as text frames | 6  
Stream output audio as binary frames | 7  
Send flush text frame | 8  
Close WebSocket | 9

## Audio Frames

Input audio and output audio use raw PCM binary frames on the WebSocket transport.

- Encoding: 16-bit signed integer PCM (little-endian)
- Channels: Mono (1 channel)
- Input sample rate: Must match `input_sample_rate` from `init`
- Output sample rate: Matches `output_sample_rate` from `init`

Send audio in small frames, typically 10-20 ms of audio per frame, for the lowest latency. Larger frames add latency equal to the frame duration.

## Error Handling

### Connection Errors

If authentication fails, the server returns an HTTP error before the WebSocket upgrade:

| HTTP Status | Description |
| --- | --- |
| 401 | Missing, empty, invalid, or expired authentication credentials |

### Runtime Errors

During a session, runtime errors are delivered as `error` messages. Non-fatal errors, such as bad JSON or an unknown message type, do not close the connection. Fatal backend errors may be followed by the connection closing. See [`error`](https://developer.sanas.ai/Docs/Language-Translation/Stream-Message-Layer#error) for the message shape.

### Inactivity Timeout

If no messages are sent or received for 60 seconds (configurable), the server closes the WebSocket connection.

## Migration

For the v2 consecutive API to v3 Stream API migration guide, see [Migration Guide: v2 Consecutive API to v3 Stream API](https://developer.sanas.ai/Docs/Language-Translation/Stream-Message-Layer#migration-guide-v2-consecutive-api-to-v3-stream-api).
