Polls
Send a poll into a chat, add options, vote, and read the tally.
Polls let a chat vote on a set of options inline, without leaving the conversation. They are an iMessage feature — see Protocol Selection for what each protocol supports.
Two things shape everything below:
- The chat must already exist. A poll cannot be the first message of a new chat — create the chat with
POST /v3/chatsfirst. - Options are add-only. Once an option exists it can never be edited or removed. You can append new ones for the life of the poll.
Create a poll
Section titled “Create a poll”curl -X POST https://api.linqapp.com/api/partner/v3/chats/{chatId}/polls \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "poll": { "options": [ { "text": "Tacos" }, { "text": "Sushi" } ], "idempotency_key": "poll-abc123" } }'await client.chats.polls.create({chatId}, { poll: { options: [ { text: "Tacos", }, { text: "Sushi", }, ], idempotency_key: "poll-abc123", },});client.chats.polls.create( {chat_id}, poll={ "options": [ { "text": "Tacos", }, { "text": "Sushi", }, ], "idempotency_key": "poll-abc123", },)client.Chats.Polls.Create(context.TODO(), {chatId}, linq.ChatPollNewParams{ Poll: linq.F(map[string]any{ Options: linq.F([]any{ map[string]any{ Text: linq.F("Tacos"), }, map[string]any{ Text: linq.F("Sushi"), }, }), IdempotencyKey: linq.F("poll-abc123"), }),})| Field | Required | Type | Description |
|---|---|---|---|
poll | Yes | object | — |
A poll needs at least two options, and has no title or question field — send the question as a normal text message before the poll if you need one. Pass idempotency_key to make retries safe.
The response is a poll envelope. Its message_id is the poll-definition message, and it is how you reference this poll from every other endpoint — hold on to it. See the Create Poll API reference.
Add options
Section titled “Add options”curl -X POST https://api.linqapp.com/api/partner/v3/messages/{messageId}/poll/options \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "options": [ { "text": "Pizza" } ] }'await client.messages.poll.addOptions({messageId}, { options: [ { text: "Pizza", }, ],});client.messages.poll.add_options( {message_id}, options=[ { "text": "Pizza", }, ],)client.Messages.Poll.AddOptions(context.TODO(), {messageId}, linq.MessagePollAddOptionsParams{ Options: linq.F([]any{ map[string]any{ Text: linq.F("Pizza"), }, }),})Appends options and returns the full poll. Anyone in the chat can add options, not just the creator — an inbound add arrives as a poll.updated webhook carrying only the new options. See the Add Options API reference.
curl -X POST https://api.linqapp.com/api/partner/v3/messages/{messageId}/poll/votes \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "option_id": "97ce8c17-7ef6-4bbc-a89a-6b93d189712f", "operation": "add" }'await client.messages.poll.vote({messageId}, { option_id: "97ce8c17-7ef6-4bbc-a89a-6b93d189712f", operation: "add",});client.messages.poll.vote( {message_id}, option_id="97ce8c17-7ef6-4bbc-a89a-6b93d189712f", operation="add",)client.Messages.Poll.Vote(context.TODO(), {messageId}, linq.MessagePollVoteParams{ OptionId: linq.F("97ce8c17-7ef6-4bbc-a89a-6b93d189712f"), Operation: linq.F("add"),})Votes are a per-option toggle: one call changes one option, with operation set to add or remove. A voter picking three options is three calls, and three separate poll.vote.added webhooks. See the Vote API reference.
Read the tally
Section titled “Read the tally”curl https://api.linqapp.com/api/partner/v3/messages/{messageId}/poll \ -H "Authorization: Bearer $LINQ_API_KEY"await client.messages.poll.retrieve({messageId});client.messages.poll.retrieve({message_id})client.Messages.Poll.Retrieve(context.TODO(), {messageId})Returns the poll’s current state: every option, the voters on each, and total_voters. Note that total_voters counts distinct participants — someone who voted for two options counts once — so it will not match the sum of the per-option voter counts. See the Get Poll API reference.
You do not have to poll GET /v3/messages/{messageId}/poll to stay current; the webhooks below carry each change as it happens.
Webhooks
Section titled “Webhooks”Nine events cover the poll lifecycle. See Webhook Events for payload schemas and Webhooks for setup.
| Event | Fires when |
|---|---|
poll.received | A participant sends a poll to your line |
poll.sent | A poll you created leaves the device |
poll.delivered | That poll reaches the recipient |
poll.read | The recipient reads it |
poll.updated | Someone adds options to an existing poll |
poll.failed | An outbound poll or poll action failed to send |
poll.vote.added | A participant votes for an option |
poll.vote.removed | A participant takes a vote back |
poll.reaction.added | Someone reacts to the poll message |
Poll reactions are stickers, which cannot be removed, so poll.reaction.added has no removal counterpart.
Important notes
Section titled “Important notes”- iMessage only — polls are not available on RCS or SMS.
- The chat must exist first — a poll cannot open a new chat.
- No question field — send the question as a separate text message.
- Two options minimum, and options are add-only and immutable once created.
- One option per vote call — votes toggle per option, not as a set.
- Reference the poll by
message_id, the poll-definition message returned by create.
Related
Section titled “Related”- Reactions — tapbacks, including on a poll message
- Sending Messages — the text message that carries your question
- Webhook Events — every poll payload shape