poll-realtime-events.md
Poll Real-Time Socket Events
Polls broadcast three socket event types through the existing EdgeSocket connection. All messages arrive on the same WebSocket channel used for chat.
REST API
Get Poll
Fetch the current state of a poll by ID. Use this on initial load or to hydrate state after reconnecting.
GET /client/v1/polls/{id}
GET /mobile/v1/polls/{id}
Response:
{
"id": "abc123",
"title": "Who will win the match?",
"image": "https://cdn.example.com/poll-banner.jpg",
"startsAt": "2026-05-12T18:00:00Z",
"endsAt": "2026-05-12T20:00:00Z",
"status": 2,
"showResults": true,
"videoId": "vid456",
"totalVotes": 347,
"hasVoted": true,
"userVotedOptionId": "opt1",
"options": [
{ "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 152 },
{ "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 130 },
{ "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 65 }
]
}
hasVotedanduserVotedOptionIdare user-specific (based on the authenticated user).- If
showResultsisfalseand the user has not voted,voteCountandtotalVoteswill be0.
Submit Vote
POST /client/v1/polls/{id}/vote
POST /mobile/v1/polls/{id}/vote
Body:
{
"optionId": "opt1"
}
Socket Events
poll:started
Sent when an admin activates a poll. The client should display the poll UI.
{
"type": "poll:started",
"pollId": "abc123",
"title": "Who will win the match?",
"image": "https://cdn.example.com/poll-banner.jpg",
"startsAt": "2026-05-12T18:00:00Z",
"endsAt": "2026-05-12T20:00:00Z",
"status": 2,
"showResults": true,
"videoId": "vid456",
"totalVotes": 0,
"options": [
{ "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 0 },
{ "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 0 },
{ "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 0 }
]
}
poll:vote
Sent after each vote is submitted. Use this to update vote counts in real time.
{
"type": "poll:vote",
"pollId": "abc123",
"optionId": "opt1",
"userId": "user456"
}
optionIdis the option that received the vote.userIdis the user who voted.- Increment the local vote count for the given
optionIdby 1 and incrementtotalVotesby 1.
poll:ended
Sent when an admin ends the poll. The client should lock voting and show final results.
{
"type": "poll:ended",
"pollId": "abc123",
"title": "Who will win the match?",
"image": "https://cdn.example.com/poll-banner.jpg",
"startsAt": "2026-05-12T18:00:00Z",
"endsAt": "2026-05-12T20:00:00Z",
"status": 3,
"showResults": true,
"videoId": "vid456",
"totalVotes": 1204,
"options": [
{ "id": "opt1", "text": "Team A", "displayOrder": 1, "voteCount": 540 },
{ "id": "opt2", "text": "Team B", "displayOrder": 2, "voteCount": 489 },
{ "id": "opt3", "text": "Draw", "displayOrder": 3, "voteCount": 175 }
]
}
Poll Status Values
| Value | Name | Description |
|---|---|---|
| 1 | Draft | Not yet visible to users |
| 2 | Active | Accepting votes |
| 3 | Ended | Voting closed, showing results |
Implementation Flow
- Listen for
poll:startedon the socket. When received, render the poll UI with the provided options. - When the user selects an option, call
POST /polls/{id}/votewith{ "optionId": "..." }. - Listen for
poll:votemessages. For each one, increment the vote count for the givenoptionIdby 1. Only update the UI ifshowResultsistrue(from the initialpoll:starteddata) or the current user has already voted. - Listen for
poll:ended. When received, disable voting and display the final results from the message payload. - If the user joins late (after
poll:startedwas already sent), callGET /polls/{id}to fetch the current poll state.