anonymous poll’s voter identities are never served (the creator included), and a hidden poll’s counts are withheld from every frame until it closes.
Create a poll
A poll rides an ordinarysend():
CloakPollError before anything is sent; a server-side deny arrives as -15 (missing the create-polls capability) or -16 (malformed) on sendRejected. Poll messages never expire.
Read a poll
A message carrying a poll (live or from history) exposesmsg.poll: state is the server’s structure (absolute tallies, counts: null while a hidden poll is open, myVotes always [] for a bot) and data is the decrypted question and labels (null when undecryptable, never ciphertext).
Live tallies arrive as pollUpdate events whenever someone votes on a visible, non-hidden poll:
Close and inspect
Closing is lazy: nothing fires server-side when the window passes. Read the final numbers withfetchPollState() (which is also the hidden-poll reveal after close), end one early with closePoll() (the creator or message_manage; this broadcasts the final tally), and list an identified poll’s voters per option with fetchPollVoters():
fetchPollVoters hard-refuses anonymous polls (-8) and hidden polls that are still open (-9 on that opcode), for everyone, the creator included. All three take an optional { threadId } for polls living inside threads.
Next
Sending messages
The send path polls ride.
Threads
Polls work inside threads too.
What is encrypted, and what is not
Why the question is ciphertext but the tally is not.
Events
The
pollUpdate payload.