Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.messagesender.ai/llms.txt

Use this file to discover all available pages before exploring further.

Polls let you collect structured responses from contacts over SMS. A poll consists of an optional introductory message, one or more questions (multiple choice or open-ended), and an optional closing message. Participants receive questions sequentially via text and respond by replying with their chosen option code. Branching logic lets you route participants to different questions based on their answers.

Poll statuses

StatusDescription
draftBeing configured; not yet started.
scheduledApproved to start at scheduledFor.
activeCurrently sending questions to participants.
pausedExecution paused; participants retain their progress.
completedPoll finished or manually closed.

List polls


GET /api/polls
Returns all polls for your organization ordered by creation date descending.

Response

[
  {
    "id": "d4e5f6a7-b8c9-0123-defg-456789012345",
    "organizationId": "3f4e5c6d-7a8b-9012-cdef-1234567890ab",
    "name": "April Voter Survey",
    "status": "completed",
    "introductoryText": "Hi {{firstName}}, we have 2 quick questions for you.",
    "outroText": "Thanks for your feedback!",
    "questions": [...],
    "completionTargetEnabled": true,
    "completionTarget": 500,
    "scheduledFor": null,
    "timezone": null,
    "createdAt": "2025-04-01T09:00:00.000Z",
    "updatedAt": "2025-04-02T16:30:00.000Z"
  }
]

Create a poll


POST /api/polls
Creates a new poll in draft status. Questions must be numbered sequentially starting at 1.

Request body

name
string
required
Display name for the poll (max 200 characters).
introductoryText
string
Opening message sent to participants before the first question. Supports merge fields ({{firstName}}, etc.).
outroText
string
Closing message sent after the participant completes all questions.
introMediaUrl
string (URL)
Public URL of media to attach to the introductory message, making it MMS.
outroMediaUrl
string (URL)
Public URL of media to attach to the closing message.
questions
object[]
required
Array of question objects. Must contain between 1 and 20 questions numbered sequentially from 1.
completionTargetEnabled
boolean
When true, the poll automatically closes once completionTarget responses are collected.
completionTarget
number
Required when completionTargetEnabled is true. Number of completed participants at which the poll closes automatically.

Example request

{
  "name": "April Voter Survey",
  "introductoryText": "Hi {{firstName}}, we have 2 quick questions for you today.",
  "outroText": "Thank you for your feedback!",
  "questions": [
    {
      "questionNumber": 1,
      "text": "Do you plan to vote in the upcoming election? Reply 1 for Yes, 2 for No.",
      "type": "multiple_choice",
      "responseCode": "q1_vote_intent",
      "options": [
        { "code": "1", "label": "Yes" },
        { "code": "2", "label": "No" }
      ]
    },
    {
      "questionNumber": 2,
      "text": "What is the most important issue to you? Reply 1 for Economy, 2 for Healthcare, 3 for Education.",
      "type": "multiple_choice",
      "responseCode": "q2_top_issue",
      "options": [
        { "code": "1", "label": "Economy" },
        { "code": "2", "label": "Healthcare" },
        { "code": "3", "label": "Education" }
      ]
    }
  ],
  "completionTargetEnabled": true,
  "completionTarget": 500
}

Response

Returns the created poll with status 201.
{
  "id": "d4e5f6a7-b8c9-0123-defg-456789012345",
  "organizationId": "3f4e5c6d-7a8b-9012-cdef-1234567890ab",
  "name": "April Voter Survey",
  "status": "draft",
  "introductoryText": "Hi {{firstName}}, we have 2 quick questions for you today.",
  "outroText": "Thank you for your feedback!",
  "questions": [...],
  "completionTargetEnabled": true,
  "completionTarget": 500,
  "createdAt": "2025-04-24T10:00:00.000Z",
  "updatedAt": "2025-04-24T10:00:00.000Z"
}

Get a poll


GET /api/polls/:id
Returns the full poll record including questions and current status.

Path parameters

id
string (UUID)
required
The poll’s UUID.

Start a poll


POST /api/polls/:id/start
Starts a poll immediately or schedules it for a future time. You must specify the audience using segmentId or contactFilter. If scheduledFor is more than 30 seconds in the future, the poll is scheduled rather than started immediately. When started immediately, the poll status changes to active and message delivery begins in the background. The endpoint returns 202 Accepted immediately while sending continues asynchronously.

Path parameters

id
string (UUID)
required
The poll’s UUID.

Request body

segmentId
string (UUID)
UUID of a saved segment to use as the audience. Mutually exclusive with contactFilter.
contactFilter
object
Ad-hoc filter defining the audience. Mutually exclusive with segmentId.
scheduledFor
string (ISO 8601 datetime)
When to start the poll. If omitted or within 30 seconds of now, the poll starts immediately.
timezone
string
IANA timezone string for display purposes (e.g. America/New_York). Used when storing the scheduled time.

Example request — start immediately

{
  "segmentId": "c3d4e5f6-a7b8-9012-cdef-234567890123"
}

Example request — schedule for later

{
  "contactFilter": { "tags": ["registered-voter"], "tagsLogic": "AND" },
  "scheduledFor": "2025-04-28T14:00:00.000Z",
  "timezone": "America/New_York"
}

Response

Returns the updated poll object. When starting immediately, status is active and HTTP status is 202. When scheduling, status is scheduled and HTTP status is 200.
{
  "id": "d4e5f6a7-b8c9-0123-defg-456789012345",
  "status": "active",
  "message": "Poll starting in background"
}

List participants


GET /api/polls/:id/participants
Returns participants in the poll with their contact details and current progress.

Path parameters

id
string (UUID)
required
The poll’s UUID.

Query parameters

status
string
Filter by participant status: not_started, in_progress, completed, or terminated. Omit to return all.
Search participants by first name, last name, or phone number.
limit
number
Number of results to return. Default 100, max 500.

Response

{
  "poll": {
    "id": "d4e5f6a7-b8c9-0123-defg-456789012345",
    "name": "April Voter Survey",
    "status": "active",
    "questionCount": 2
  },
  "participants": [
    {
      "participantId": "e5f6a7b8-c9d0-1234-efgh-567890123456",
      "contactId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "firstName": "Jane",
      "lastName": "Smith",
      "phone": "+19195551234",
      "status": "completed",
      "currentQuestionNumber": 2,
      "startedAt": "2025-04-24T10:05:00.000Z",
      "completedAt": "2025-04-24T10:08:00.000Z",
      "responseCount": 2,
      "lastResponseAt": "2025-04-24T10:08:00.000Z"
    }
  ]
}

Key fields reference

questions[].type
string
multiple_choice requires participants to reply with one of the defined option codes. open_ended accepts any text reply.
questions[].options
object[]
Each option has a code (the keyword participants text back, e.g. "1") and a label (the human-readable choice shown in the question text). Multiple-choice questions require 2–9 options.
completionTarget
number | null
When set, the poll closes automatically after this many participants complete all questions.
Polls respect quiet hours (8 AM–9 PM in the organization’s timezone). Questions are not sent outside this window; participants in progress when quiet hours begin resume the next day.
You cannot update an active poll’s questions or structure. Pause the poll first, then update it, then resume.