Update README.md, docs/api/README.md, session-lifecycle guide, webhooks-and-events guide, and archive docs (BOT_INTEGRATION, API_QUICK_REFERENCE) with new endpoints and vote.received event. Made-with: Cursor
10 KiB
Session Lifecycle Guide
This guide walks through the full lifecycle of a Jackbox gaming session—from creation through closing and deletion—with narrative explanations, behavior notes, and curl examples.
Base URL: http://localhost:5000
Authentication: All write operations require a Bearer token. Set TOKEN in your shell and use -H "Authorization: Bearer $TOKEN" in curl examples.
1. Creating a Session
Only one active session can exist at a time. If an active session already exists, you must close it before creating a new one.
Notes are optional; they help you remember what a session was for (e.g., "Friday game night", "Birthday party").
Creating a session triggers a session.started WebSocket event broadcast to all authenticated clients. See Real-time updates via WebSocket for details.
Endpoint: POST /api/sessions
# Create a session with notes
curl -X POST "http://localhost:5000/api/sessions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"notes": "Friday game night"}'
# Create a session without notes (body can be empty)
curl -X POST "http://localhost:5000/api/sessions" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Response (201 Created):
{
"id": 5,
"notes": "Friday game night",
"is_active": 1,
"created_at": "2026-03-15T19:00:00.000Z",
"closed_at": null
}
If an active session already exists, you receive 400 with a message like "An active session already exists. Please close it before creating a new one." and an activeSessionId in the response.
2. Adding Games
You can add games in two ways: via the picker (weighted random selection) or manually by specifying a game ID.
Via the Picker
First, use POST /api/pick to select a game with filters and repeat avoidance. Then add that game to the session.
# 1. Pick a game (optionally filter by player count, session for repeat avoidance)
GAME=$(curl -s -X POST "http://localhost:5000/api/pick" \
-H "Content-Type: application/json" \
-d '{"playerCount": 6, "sessionId": 5}' | jq -r '.game.id')
# 2. Add the picked game to the session
curl -X POST "http://localhost:5000/api/sessions/5/games" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"game_id\": $GAME, \"manually_added\": false}"
Manual Addition
Add a game directly by its game_id (from the games catalog):
curl -X POST "http://localhost:5000/api/sessions/5/games" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"game_id": 42, "manually_added": true, "room_code": "ABCD"}'
Endpoint: POST /api/sessions/{id}/games
Side Effects of Adding a Game
When you add a game to an active session, several things happen automatically:
- Previous
playinggames are auto-transitioned toplayed. At most one game isplayingat a time. - The game's
play_countis incremented in the catalog. - The
game.addedwebhook is fired (if you have webhooks configured) and agame.addedWebSocket event is broadcast to session subscribers. - If you provide a
room_code, the room monitor is auto-started for player count tracking.
Newly added games start with status playing.
3. Tracking Game Status
Each game in a session has a status: playing, played, or skipped.
| Status | Meaning |
|---|---|
playing |
Currently being played (at most one at a time) |
played |
Finished playing |
skipped |
Skipped (e.g., technical issues); stays skipped |
Behavior: When you change a game's status to playing, any other games with status playing are automatically set to played. Skipped games are never auto-transitioned; they remain skipped.
Endpoint: PATCH /api/sessions/{sessionId}/games/{sessionGameId}/status
Important: In session game sub-routes, sessionGameId refers to session_games.id (the row in the session_games table), not games.id. When listing session games with GET /api/sessions/{id}/games, the id field in each object is the session_games.id.
# Mark a game as played (sessionGameId 14, not game_id)
curl -X PATCH "http://localhost:5000/api/sessions/5/games/14/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "played"}'
# Mark a game as playing (others playing → played)
curl -X PATCH "http://localhost:5000/api/sessions/5/games/14/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "playing"}'
# Mark a game as skipped
curl -X PATCH "http://localhost:5000/api/sessions/5/games/14/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "skipped"}'
4. Room Codes
Room codes are 4-character strings used by Jackbox games for lobby entry. Valid format: exactly 4 characters, uppercase letters (A–Z) and digits (0–9) only. Example: ABCD, XY9Z.
A room code enables room monitoring for player count. You can set or update it when adding a game or via a dedicated PATCH endpoint.
Endpoint: PATCH /api/sessions/{sessionId}/games/{sessionGameId}/room-code
# Set room code when adding a game
curl -X POST "http://localhost:5000/api/sessions/5/games" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"game_id": 42, "room_code": "ABCD"}'
# Update room code later
curl -X PATCH "http://localhost:5000/api/sessions/5/games/14/room-code" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"room_code": "XY9Z"}'
5. Player Count Monitoring
For games with a room code, you can track how many players join. The room monitor polls the Jackbox lobby to detect player count changes.
- Start monitoring: POST /api/sessions/{sessionId}/games/{sessionGameId}/start-player-check
- Stop monitoring: POST /api/sessions/{sessionId}/games/{sessionGameId}/stop-player-check
- Manual update: PATCH /api/sessions/{sessionId}/games/{sessionGameId}/player-count
When the player count changes (via room monitor or manual update), a player-count.updated WebSocket event is broadcast to session subscribers.
# Start room monitor (game must have a room code)
curl -X POST "http://localhost:5000/api/sessions/5/games/14/start-player-check" \
-H "Authorization: Bearer $TOKEN"
# Manually set player count
curl -X PATCH "http://localhost:5000/api/sessions/5/games/14/player-count" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"player_count": 6}'
# Stop monitoring
curl -X POST "http://localhost:5000/api/sessions/5/games/14/stop-player-check" \
-H "Authorization: Bearer $TOKEN"
6. Closing Sessions
Closing a session marks it as inactive. The API:
- Auto-finalizes all games with status
playingtoplayed - Sets
closed_atandis_active = 0 - Triggers a
session.endedWebSocket broadcast to session subscribers
You can add or update session notes in the close request body.
Endpoint: POST /api/sessions/{id}/close
curl -X POST "http://localhost:5000/api/sessions/5/close" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"notes": "Great session!"}'
Response (200 OK):
{
"id": 5,
"notes": "Great session!",
"is_active": 0,
"created_at": "2026-03-15T19:00:00.000Z",
"closed_at": "2026-03-15T23:30:00.000Z",
"games_played": 4
}
You cannot add games to a closed session.
7. Exporting Session Data
Export a session in two formats: JSON (structured) or TXT (human-readable).
Endpoint: GET /api/sessions/{id}/export
- JSON (
?format=json): Includessession,games, andchat_logsas structured data. Useful for archival or integrations. - TXT (default): Human-readable plaintext with headers and sections.
# Export as JSON
curl -o session-5.json "http://localhost:5000/api/sessions/5/export?format=json" \
-H "Authorization: Bearer $TOKEN"
# Export as TXT (default)
curl -o session-5.txt "http://localhost:5000/api/sessions/5/export" \
-H "Authorization: Bearer $TOKEN"
8. Deleting Sessions
Sessions must be closed before deletion. Active sessions cannot be deleted.
Deletion cascades to related data:
session_gamesrows are deletedchat_logsrows are deleted
Endpoint: DELETE /api/sessions/{id}
curl -X DELETE "http://localhost:5000/api/sessions/5" \
-H "Authorization: Bearer $TOKEN"
Response (200 OK):
{
"message": "Session deleted successfully",
"sessionId": 5
}
9. Real-time Updates via WebSocket
The API provides real-time updates over WebSocket for session events: session.started, game.added, session.ended, player-count.updated, and vote.received. Connect to /api/sessions/live, authenticate with your JWT, and subscribe to session IDs to receive these events without polling.
For connection setup, message types, and event payloads, see WebSocket Protocol.
Quick Reference: sessionGameId vs game_id
| Context | ID meaning | Example |
|---|---|---|
POST /api/sessions/{id}/games body |
game_id = catalog games.id |
{"game_id": 42} |
GET /api/sessions/{id}/games response id |
session_games.id |
Use 14 in sub-routes |
PATCH .../games/{sessionGameId}/status |
sessionGameId = session_games.id |
/sessions/5/games/14/status |
When in doubt: session game sub-routes use session_games.id, not games.id.