> ## Documentation Index
> Fetch the complete documentation index at: https://sparkggdocs.internal.tuniform.tn/llms.txt
> Use this file to discover all available pages before exploring further.

# WebSocket connection

> How to authenticate and connect to the Tuniform Stream Alerts WebSocket for real-time event delivery.

## Stream Alerts service

The Stream Alerts service provides **real-time event delivery** via WebSocket. When a creator receives a donation, subscription, or other event on Tuniform, the event is instantly pushed to all connected WebSocket clients for that creator.

This allows:

* **OBS overlays** to display live alerts during streams
* **External platforms** (e.g., SparkGG) to subscribe to real-time creator activity
* **Custom tools** to react to donations, subscriptions, and other events as they happen

<Info>
  There is also a **fallback polling mechanism**: overlay clients can periodically poll the Tuniform server to fetch events from the database. This ensures alerts are never permanently lost if the WebSocket connection is temporarily unavailable. However, the WebSocket path is the **primary real-time delivery channel**.
</Info>

***

## Connection endpoint

Connect to the WebSocket using the following URL format:

<CodeGroup>
  ```bash Connection URL theme={null}
  wss://stream-alerts.tuniform.tn/ws?token=<stream_token>
  ```
</CodeGroup>

### Authentication

Every creator on Tuniform has a unique **stream token** — a 64-character hex string that acts as an API key. This token is passed as the `token` query parameter when connecting.

<ResponseField name="token" type="string" required>
  The creator's unique 64-character hex stream token, passed as a query parameter.
</ResponseField>

### Connection responses

| Scenario                 | HTTP Status               | Response                            |
| ------------------------ | ------------------------- | ----------------------------------- |
| Valid token              | `101 Switching Protocols` | WebSocket connection established    |
| Missing token            | `401 Unauthorized`        | `"Missing 'token' query parameter"` |
| Invalid or expired token | `401 Unauthorized`        | `"Invalid or expired token"`        |

***

## Handshake message

Immediately after a successful connection, the server sends a **handshake confirmation** message. This is always the **first message** received.

```json Handshake Response theme={null}
{
  "type": "CONNECTED",
  "kick_username": "creator_kick_handle",
  "user_id": 12345
}
```

<ParamField body="type" type="string" required>
  Always `"CONNECTED"` for the handshake message.
</ParamField>

<ParamField body="kick_username" type="string">
  The creator's Kick.com username. Empty string if not set.
</ParamField>

<ParamField body="user_id" type="integer" required>
  The creator's Tuniform user ID.
</ParamField>

<Warning>
  Always process the handshake message separately from event payloads. The first message after connection is **always** the `CONNECTED` handshake — never an event.
</Warning>

***

## Message flow

<Steps>
  <Step title="Client connects">
    Open a WebSocket connection to `wss://stream-alerts.tuniform.tn/ws?token=<stream_token>`.
  </Step>

  <Step title="Server authenticates">
    The server validates the `token` query parameter. Invalid tokens receive a `401` HTTP response.
  </Step>

  <Step title="Handshake received">
    On success, the server sends a `{"type":"CONNECTED",...}` message.
  </Step>

  <Step title="Events stream in">
    All subsequent messages are event payloads (donations, subscriptions, etc.) scoped to the authenticated creator.
  </Step>
</Steps>

### Key behaviors

<CardGroup cols={2}>
  <Card title="Server → Client only" icon="arrow-right">
    This is a **one-way broadcast system**. The server pushes events to connected clients. Messages sent by the client are ignored.
  </Card>

  <Card title="JSON text frames" icon="brackets-curly">
    Each event is sent as a **WebSocket text frame** containing a JSON-serialized object.
  </Card>

  <Card title="Creator-scoped" icon="user">
    Events are **scoped to the creator** — you only receive events for the creator whose `stream_token` you authenticated with.
  </Card>

  <Card title="Automatic keep-alive" icon="heart-pulse">
    The server sends **Ping** frames automatically. Standard WebSocket clients handle Pong responses transparently — no action needed.
  </Card>
</CardGroup>

***

## Next steps

<Card title="Event payload schemas" icon="code" href="/sparkgg/events" horizontal>
  Explore the full JSON schema for donation, subscription, and future event types.
</Card>
