# WebSocket Protocol

Real-time sync events broadcast to connected clients.

## Connect to WebSocket

**Endpoint**: `WS /ws/sync?token=<token>`

### Connection Parameters

| Parameter | Type   | Required | Description              |
| --------- | ------ | -------- | ------------------------ |
| token     | string | Yes      | JWT authentication token |

### Example Connection

```javascript
const ws = new WebSocket("wss://bookhoard.com/ws/sync?token=eyJhbG...");
```

## Message Format

All messages are JSON objects with a `type` field.

### Client → Server Messages

#### Ping (Heartbeat)

```json
{
  "type": "ping"
}
```

Keep connection alive. Server responds with `pong`.

### Server → Client Messages

#### Progress Update

```json
{
  "type": "progress_update",
  "timestamp": "2026-01-31T10:00:00Z",
  "data": {
    "book_id": "uuid",
    "progress": {
      "percentage": 0.45678,
      "epubcfi": "epubcfi(/6/4/2:15)",
      "chapter": 3
    },
    "annotations": {}
  },
  "source_device": {
    "id": "device-uuid",
    "name": "My Kobo",
    "type": "kobo"
  }
}
```

Broadcast when any device updates reading progress.

#### Conflict Detected

```json
{
  "type": "conflict",
  "timestamp": "2026-01-31T10:00:00Z",
  "data": {
    "book_id": "uuid",
    "conflict_id": "uuid",
    "conflict_type": "progress"
  }
}
```

Broadcast when a sync conflict is detected.

#### Pong

```json
{
  "type": "pong"
}
```

Server response to client `ping`.

## Connection Management

- **Heartbeat**: Send `ping` every 30 seconds
- **Reconnect**: Use exponential backoff if connection drops
- **Authentication**: Token must be valid for connection
- **Rate Limits**: 60 messages/minute per connection

## Error Handling

```json
{
  "type": "error",
  "message": "Invalid token",
  "code": "AUTH_FAILED"
}
```
