im.polls manages iMessage poll messages. A poll always belongs to a chat, so create(...) takes chat.guid. If you only have email addresses or phone numbers, create the chat first with im.chats.create(...).
After a poll is created, store poll.pollMessageGuid. You need it to read the poll, vote, unvote, add options, and subscribe to events for that poll.
What You Can Do
| Need | Use this when |
|---|---|
| Create a poll | You want to send a new poll message into a chat |
| Read state | You need the latest title, options, and votes |
| Vote | The current account chooses an option or changes its choice |
| Unvote | The current account removes its choice |
| Add an option | You want to append another option to an existing poll |
| Subscribe to events | You need live poll creation, option, vote, and unvote changes |
Two IDs
Poll APIs use two IDs. Keep them separate and the rest of the API is straightforward:| ID | What it identifies | Where it comes from |
|---|---|---|
pollMessageGuid | The poll | poll.pollMessageGuid |
optionIdentifier | A poll option | poll.options[*].optionIdentifier |
- Pass
pollMessageGuidto say which poll you are operating on. - Pass
optionIdentifierwhen you need to choose a specific option.
Create a Poll
Poll:
| Input | Rule |
|---|---|
chat | Pass chat.guid, not an email address or phone number |
title | Trimmed by the SDK/server; must not be empty after trimming |
choices | At least two strings; each choice is trimmed and must not be empty |
Read and Modify
Get State
Poll. Use this when you need fresh option IDs or current vote state. Missing polls throw NotFoundError.
Vote
Poll.
| Case | Result |
|---|---|
| Current account has not voted | Records the selected option |
| Current account already voted | Replaces the previous choice |
pollMessageGuid does not exist | Throws NotFoundError |
optionIdentifier is invalid | Throws ValidationError |
Unvote
Poll. Missing polls throw NotFoundError.
Add an Option
Poll. The new option is appended to options.
| Input | Rule |
|---|---|
pollMessageGuid | Existing poll message GUID |
text | Trimmed by the SDK/server; must not be empty after trimming |
NotFoundError.
create(...), vote(...), unvote(...), and addOption(...) accept optional { clientMessageId } for idempotent retries from your job system. Most direct calls can omit it. See error handling for details.Poll Events
subscribeEvents(...) returns TypedEventStream<PollEvent>. Use the stream to observe changes made by other people, other devices, or another part of your system. Immediately after your code calls vote(...), unvote(...), or addOption(...), use that method’s returned Poll.
Scope
Only one poll:Outer Event
Every poll event hastype: "poll.changed". The outer fields answer which poll changed, which chat it belongs to, who triggered it, and when:
Delta Types
event.delta.type tells you what changed. Each type carries different fields:
event.delta.type | Meaning | Extra fields |
|---|---|---|
created | The poll was created | title, options |
optionAdded | A new option was appended | title, options |
voted | A participant voted or changed their vote | optionIdentifier |
unvoted | A participant removed their vote | optionIdentifier |
Handle Events
Switch onevent.delta.type. When you subscribe to one poll, you do not need to check pollMessageGuid again:
event.pollMessageGuid to identify the poll:
Next Steps
- Chats — create a chat and get
chat.guid - Messages — understand how poll messages appear in the message stream
- Events — catch up on durable events after a disconnect
- Error Handling — handle
NotFoundError,ValidationError, and idempotent retries