Skip to main content
Version: 2.0 PartyKit

Event Reference

All WebSocket messages are JSON objects with a type field. The transport is PartySocket (native WebSocket under the hood).

Client β†’ Server​

create_session​

Sent by host to create a new session.

{
type: 'create_session';
title: string;
hostId: string; // e.g. 'TANNIC-FALCON'
timerSeconds: number; // 15–120
wines: Array<{
name: string;
questions: Array<{
category: 'color' | 'country' | 'grape_variety' | 'vintage_year' | 'wine_name';
correctAnswer: string;
distractors: [string, string, string];
}>;
}>;
}

join_session​

Sent by participant to join a waiting session.

{ type: 'join_session'; code: string }

rejoin_host​

Sent by host on socket open to re-authenticate (after page refresh or reconnect).

{ type: 'rejoin_host'; hostId: string }

rejoin_session​

Sent by participant on socket open when a rejoinToken is in localStorage.

{ type: 'rejoin_session'; rejoinToken: string }

host:start / host:pause / host:resume / host:reveal / host:next / host:end​

Host control events β€” no additional payload.

{ type: 'host:start' }
{ type: 'host:pause' }
{ type: 'host:resume' }
{ type: 'host:reveal' }
{ type: 'host:next' }
{ type: 'host:end' }

submit_answer​

Sent by participant to select or change an answer.

{ type: 'submit_answer'; questionId: string; optionId: string }

Server β†’ Client​

session:created​

Sent to host after successful create_session.

{ type: 'session:created'; code: string; hostId: string }

participant:joined​

Sent to the joining participant.

{ type: 'participant:joined'; pseudonym: string; rejoinToken: string }

lobby:updated​

Broadcast to all connected clients when a participant joins or leaves the lobby.

{ type: 'lobby:updated'; participants: string[] }

host:state_snapshot​

Sent to host on rejoin_host (full current state).

{
type: 'host:state_snapshot';
code: string;
hostId: string;
phase: SessionPhase;
participants: string[];
question: QuestionPayload | null;
rankings: RankingEntry[];
}

participant:state_snapshot​

Sent to participant on rejoin_session.

{
type: 'participant:state_snapshot';
pseudonym: string;
phase: SessionPhase;
question: QuestionPayload | null;
}

sessions:list​

Sent to host listing their past and active sessions (sourced from KV).

{
type: 'sessions:list';
sessions: Array<{
code: string;
title: string;
createdAt: string;
status: 'waiting' | 'active' | 'ended';
participantCount: number;
finalRankings?: RankingEntry[];
}>;
}

game:question​

Broadcast when a new question starts.

{
type: 'game:question';
questionId: string;
prompt: string;
category: QuestionCategory;
options: Array<{ id: string; text: string }>; // shuffled; no 'correct' flag
roundIndex: number;
questionIndex: number;
totalQuestions: number;
totalRounds: number;
timerMs: number;
}

game:timer_tick​

Emitted every second during question_open and question_paused.

{ type: 'game:timer_tick'; remainingMs: number }

game:timer_paused / game:timer_resumed​

{ type: 'game:timer_paused'; remainingMs: number }
{ type: 'game:timer_resumed'; remainingMs: number }

game:participant_answered (host only)​

{ type: 'game:participant_answered'; answeredCount: number; totalCount: number }

game:answer_revealed​

Sent to host:

{
type: 'game:answer_revealed';
correctOptionId: string;
results: Array<{ pseudonym: string; points: number; totalScore: number }>;
}

Sent to each participant:

{
type: 'game:answer_revealed';
correctOptionId: string;
myPoints: number;
myTotalScore: number;
}

game:round_leaderboard​

{
type: 'game:round_leaderboard';
rankings: RankingEntry[];
roundIndex: number;
totalRounds: number;
}

game:final_leaderboard​

{ type: 'game:final_leaderboard'; rankings: RankingEntry[] }

session:ended​

{ type: 'session:ended' }

error​

{ type: 'error'; message: string }

Connection / Lifecycle Events​

server:state_snapshot​

Sent by the backend to every client immediately after they connect or reconnect. Contains the current session phase so clients can restore their UI state.

Direction: Server β†’ Client
Payload:

{
"phase": "waiting | question_open | question_paused | question_revealed | round_leaderboard | ended",
"code": "1234"
}

Participants use this event to detect when a session has ended while they were disconnected. If phase === "ended", the client transitions to the ended state and clears the rejoin token.


sessions:list​

Sent to the host in response to connecting with a host ID. Contains all sessions stored under that host ID.

Direction: Server β†’ Host
Payload:

[
{
"code": "1234",
"title": "My Wine Night",
"createdAt": "2024-01-01T00:00:00.000Z",
"status": "waiting | ended",
"participantCount": 3
}
]

host:state_snapshot​

Sent to a host on reconnect to restore their session state.

Direction: Server β†’ Host
Payload: Same shape as the full host game state (participants, current question, phase, etc.)


participant:state_snapshot​

Sent to a participant on reconnect to restore their game state.

Direction: Server β†’ Participant
Payload: Same shape as the full participant game state (phase, current question, selected option, etc.)


Types​

type QuestionCategory = 'color' | 'country' | 'grape_variety' | 'vintage_year' | 'wine_name';
type SessionPhase = 'waiting' | 'question_open' | 'question_paused' | 'question_revealed' | 'round_leaderboard' | 'ended';

interface RankingEntry {
pseudonym: string;
score: number;
rank: number;
}