Polls
Create a poll in a conversation, and the reasons you cannot read it back.
The poll payload posts a question with a fixed set of options that
participants tap to vote on.
{
"kind": "poll",
"question": "Which slot works for Saturday?",
"options": ["10:00", "13:30", "18:00"]
}Creating one is straightforward. Everything after creation is the part to read carefully — see What you cannot do below before you design around this.
Fields
Prop
Type
Uniqueness is enforced on the exact strings, so "10:00" and "10:00 " count
as two different options — which is rarely what you meant. Trim before you
send.
Polls need a conversation target. A recipient
send is plain text only, so you cannot open a cold
thread with a poll; send a message first, then poll into the conversation once
it exists.
A worked example
Nothing about a poll is special at the HTTP layer — it is message.send with a
different payload shape.
curl -X POST $MAPIER_BASE_URL/v1/commands/message.send \
-H "Authorization: Bearer $MAPIER_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: saturday-slot-poll-1" \
-d '{
"target": {
"kind": "conversation",
"conversationId": "a0000000-0000-4000-8000-000000000002"
},
"payload": {
"kind": "poll",
"question": "Which slot works for Saturday?",
"options": ["10:00", "13:30", "18:00"]
}
}'Check the option count and uniqueness yourself. The API does not validate
payload, so thirteen options or a duplicated string returns 202 and settles
failed on the stream — long after you could have told the caller.
What you cannot do with a poll
A poll is write-once. There is no read path.
/v1 has no vote command and no endpoint that returns a poll's
results. Once you have created a poll you cannot vote in it
programmatically, cannot fetch its tally, and cannot learn who chose what.
There is also no way to close, edit or delete a poll — /v1 exposes no
message edit, unsend or delete command at all.
Treat that as a gap in /v1 rather than a permanent shape. What matters today
is that there is no workaround at the API layer: a workflow that depends on
reading results back cannot be built on this endpoint.
What you can observe
The response stream carries exactly two event
shapes: command settlements for the things you sent, and message events for
inbound messages. Neither is a poll event.
So the most you learn is:
- That the poll was sent. A
commandevent withstatus: "succeeded", correlated bycommandIdor by yourIdempotency-Key. - What people say about it. Ordinary replies in the conversation arrive as
messageevents like any other text.
Unconfirmed
Whether a vote produces anything at all on the stream is not settled. There is no poll lifecycle
event in the contract, so do not write code that waits for one. If you need a tally you can act
on, ask people to reply in words and read the message events — or run the vote outside iMessage.
When a poll is still the right call
Given the above, polls work best when the humans in the conversation are the consumers of the result and your system only needs to have asked. Scheduling a team, collecting a soft preference, giving a group a tidy way to converge — those all work. Anything where your code must branch on the outcome does not.