docs: add sync protocols and WebSocket API documentation

Phase 2 part 7: Add real-time sync protocol documentation
- KOReader Protocol: progress sync, metadata fetch
- Kobo Protocol: markup sync, library fetch
- WebSocket: real-time events (progress updates, conflicts)
- Include message format examples for all protocols
This commit is contained in:
2026-02-02 08:52:13 -05:00
parent 55024bb70a
commit 3e81477341
3 changed files with 337 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
# Kobo Sync Protocol
Kobo uses a proprietary sync protocol with JSON payloads.
## Kobo Markup Sync
**Endpoint**: `POST /api/sync/kobo/markup`
**Auth**: Device token required
**Content-Type**: `application/json`
### Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer device token |
| x-kobo-device | string | Yes | JSON device info |
| Content-Type | string | Yes | application/json |
### Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| ReadingSync | array | No | Array of reading progress data |
| ReadingSync[].ContentId | string | Yes | Book UUID |
| ReadingSync[].PercentRead | float | Yes | Progress percentage (0-100) |
| ReadingSync[].EntitlementId | string | Yes | Kobo entitlement ID |
| ReadingSync[].RemainingTimeMinutes | integer | No | Estimated remaining time |
| ReadingSync[].LastModified | string | Yes | ISO 8601 timestamp |
| BookmarkSync | array | No | Array of bookmarks/highlights |
### Example Request
```http
POST /api/sync/kobo/markup
Authorization: Bearer device-token
x-kobo-device: {"DeviceId":"device-id","Model":"Kobo Clara"}
Content-Type: application/json
{
"ReadingSync": [
{
"ContentId": "book-uuid",
"PercentRead": 45.6,
"EntitlementId": "entitlement-id",
"RemainingTimeMinutes": 120,
"LastModified": "2026-01-30T20:00:00Z"
}
],
"BookmarkSync": [
{
"ContentId": "book-uuid",
"BookmarkText": "highlighted text",
"BookmarkType": "annotation",
"BookmarkTitle": "Chapter 3"
}
]
}
```
### Response (200 OK)
```json
{
"Status": "Success",
"MarkupsSynced": 5,
"BookmarksSynced": 3
}
```
## Kobo Library Fetch
**Endpoint**: `GET /api/sync/kobo/library`
**Auth**: Device token required
### Example Request
```http
GET /api/sync/kobo/library
Authorization: Bearer device-token
```
### Response (200 OK)
```json
{
"library_sync": [
{
"ContentId": "book-uuid",
"ContentType": "6",
"Title": "Book Title",
"Author": "Author Name",
"PercentRead": 42.3,
"PagesRemaining": 115,
"BookmarkCount": 3,
"LastModified": "2026-01-30T20:00:00Z"
}
]
}
```
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
+125
View File
@@ -0,0 +1,125 @@
# KOReader Sync Protocol
KOReader uses a custom JSON-based sync protocol.
## KOReader Progress Sync
**Endpoint**: `POST /api/sync/koreader/progress`
**Auth**: Device token required
**Content-Type**: `application/json`
### Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer device token |
| Content-Type | string | Yes | application/json |
### Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| library_id | string | No | Library UUID |
| books | array | Yes | Array of book sync data |
| books[].uuid | string | Yes | Book UUID |
| books[].title | string | Yes | Book title |
| books[].authors | array | Yes | Array of author names |
| books[].progress | float | Yes | Progress percentage (0-1) |
| books[].percentage | float | Yes | Progress percentage (0-1) |
| books[].last_read | string | Yes | ISO 8601 timestamp |
| books[].chapter | integer | No | Current chapter |
| books[].epubcfi | string | No | EPUB CFI location |
| books[].character | integer | No | Character offset |
| books[].bookmarks | array | No | Array of bookmarks/highlights |
### Example Request
```json
{
"library_id": "optional-uuid",
"books": [
{
"uuid": "book-uuid",
"title": "Book Title",
"authors": ["Author Name"],
"progress": 0.45,
"percentage": 0.45,
"last_read": "2026-01-30T20:00:00Z",
"chapter": 3,
"epubcfi": "epubcfi(/6/4/2:15)",
"character": 15432,
"bookmarks": [
{
"chapter": 3,
"datetime": "2026-01-30T19:55:00Z",
"notes": "highlighted text",
"pos0": "epubcfi(/6/4/2:15)",
"pos1": "epubcfi(/6/4/2:20)",
"page": 45,
"text": "highlighted text excerpt",
"type": "highlight"
}
],
"highlights": [],
"notes": []
}
]
}
```
### Response (202 Accepted)
```json
{
"sync_status": "accepted",
"books_synced": 1,
"conflicts": [
{
"book_uuid": "book-uuid",
"conflict_type": "progress_mismatch",
"device_progress": 0.45,
"server_progress": 0.42,
"resolution": "device_wins"
}
]
}
```
## KOReader Metadata Fetch
**Endpoint**: `GET /api/sync/koreader/metadata/{book_uuid}`
**Auth**: Device token required
### Example Request
```http
GET /api/sync/koreader/metadata/book-uuid
Authorization: Bearer device-token
```
### Response (200 OK)
```json
{
"uuid": "book-uuid",
"title": "Book Title",
"authors": ["Author Name"],
"progress": {
"percentage": 0.42,
"character": 15432,
"epubcfi": "epubcfi(/6/4/2:15)",
"chapter": 3,
"chapter_progress": 0.234
},
"annotations": {
"highlights": [...],
"notes": [...],
"bookmarks": [...]
},
"last_sync": "2026-01-30T20:00:00Z"
}
```
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
+109
View File
@@ -0,0 +1,109 @@
# 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"
}
```
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->