Poll API
A poll is sent like a message, from a template that includes a Poll component. This page is the reference; the bulk-messaging guide shows the send flow end to end.
Create a poll template
Add a Poll component (a question and a list of options) to a template via ExternalTemplateService.CreateTemplate. Fields support {{placeholders}} so one template can be reused with per-recipient vars:
TemplateComponent {
component_type: TemplateComponentType::Poll.into(),
question: Some("{{question}}".to_string()),
options: vec!["{{option_1}}".into(), "{{option_2}}".into(), "{{option_3}}".into()],
..Default::default()
}Send a poll
Send with ExternalMessageService.CreateSendRequest, supplying a poll_config. Because poll sends carry a poll_config, they use the generated-stub path rather than the curated SendOnly surface:
let resp = client.create_send_request(CreateSendRequestReq {
template_id: poll_template_id.to_string(),
recipients: vec![RecipientInput {
ppnum: "12312345678".to_string(),
vars: Some(build_vars(&[("question", "How satisfied are you?"),
("option_1", "Very"), ("option_2", "Somewhat"), ("option_3", "Not")])),
}],
poll_config: Some(PollConfig { expires_in_hours: Some(48), allow_multiple: false }),
}).await?;Get aggregated results
ExternalAppService.GetPollResults returns the totals:
| Field | Type | Description |
|---|---|---|
poll_id | string | Poll identifier |
question | string | The poll question |
results | repeated | Per-option option_text, count, percentage |
total_responses | int32 | Total responses received |
List individual responses
ExternalAppService.ListPollResponses returns per-respondent rows (responder_ppnum, selected_option, responded_at), cursor-paginated: pass limit and an optional cursor, and read has_more + next_cursor to page forward.
Receive responses in real time
Poll responses also arrive as POLL_RESPONSE_RECEIVED events on the event stream, so you can process them as they happen without polling.