Replace existing docs with fresh documentation built entirely from source code analysis. OpenAPI 3.1 spec as source of truth, plus human-readable Markdown with curl examples, response samples, and workflow guides. - OpenAPI 3.1 spec covering all 42 endpoints (validated against source) - 7 endpoint reference docs (auth, games, sessions, picker, stats, votes, webhooks) - WebSocket protocol documentation (auth, subscriptions, 4 event types) - 4 guide documents (getting started, session lifecycle, voting, webhooks) - API README with overview, auth docs, and quick reference table - Old docs archived to docs/archive/ Made-with: Cursor
3.1 KiB
3.1 KiB
Votes Endpoints
Real-time popularity voting. Bots or integrations send votes during live gaming sessions. Votes are matched to the currently-playing game using timestamp intervals.
Endpoint Summary
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/votes/live |
Bearer | Submit a live vote (up/down) |
POST /api/votes/live
Submit a real-time up/down vote for the game currently being played. Automatically finds the active session and matches the vote to the correct game using the provided timestamp and session game intervals.
Authentication
Bearer token required. Include in header: Authorization: Bearer <token>.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| username | string | Yes | Identifier for the voter (used for deduplication) |
| vote | string | Yes | "up" or "down" |
| timestamp | string | Yes | ISO 8601 timestamp when the vote occurred |
{
"username": "viewer123",
"vote": "up",
"timestamp": "2026-03-15T20:30:00Z"
}
Behavior
- Finds the active session (single session with
is_active = 1). - Matches the vote timestamp to the game being played at that time (uses interval between consecutive
played_attimestamps). - Updates game
upvotes,downvotes, andpopularity_scoreatomically in a transaction. - Deduplication: Rejects votes from the same username within a 1-second window (409 Conflict).
Response
200 OK
{
"success": true,
"message": "Vote recorded successfully",
"session": { "id": 3, "games_played": 5 },
"game": {
"id": 42,
"title": "Quiplash 3",
"upvotes": 11,
"downvotes": 2,
"popularity_score": 9
},
"vote": {
"username": "viewer123",
"type": "up",
"timestamp": "2026-03-15T20:30:00Z"
}
}
Error Responses
| Status | Body | When |
|---|---|---|
| 400 | { "error": "Missing required fields: username, vote, timestamp" } |
Missing required fields |
| 400 | { "error": "vote must be either \"up\" or \"down\"" } |
Invalid vote value |
| 400 | { "error": "Invalid timestamp format. Use ISO 8601 format (e.g., 2025-11-01T20:30:00Z)" } |
Invalid timestamp |
| 404 | { "error": "No active session found" } |
No session with is_active = 1 |
| 404 | { "error": "No games have been played in the active session yet" } |
Active session has no games |
| 404 | { "error": "Vote timestamp does not match any game in the active session", "debug": { "voteTimestamp": "2026-03-15T20:30:00Z", "sessionGames": [{ "title": "Quiplash 3", "played_at": "..." }] } } |
Timestamp outside any game interval |
| 409 | { "error": "Duplicate vote detected (within 1 second of previous vote)", "message": "Please wait at least 1 second between votes", "timeSinceLastVote": 0.5 } |
Same username voted within 1 second |
| 500 | { "error": "..." } |
Server error |
Example
curl -X POST "http://localhost:5000/api/votes/live" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "viewer123",
"vote": "up",
"timestamp": "2026-03-15T20:30:00Z"
}'