MobileSasaDocs

Surveys

Multi-question SMS conversations: a customer texts your keyword, gets asked each question in turn, and every answer is stored for you to pull over the API. No app, no data bundle needed on the customer's side.

A survey attaches to a keyword — every inbound text matching that keyword opens a survey session. The same survey engine also powers USSD survey mode. Endpoints live under /api/v1/ with a scoped mbs_ token or JWT.

Create a survey

POST/api/v1/surveys

Parameters

FieldTypeRequiredDescription
namestringYesInternal label.
keyword_uuiduuidYesThe approved keyword that triggers this survey.
sender_namestringYesSender the questions go out under — usually the shortcode itself.
welcome_messagestringYesSent once when a session starts, before the first question.
end_messagestringYesSent after the last answer — thank-yous, vouchers, next steps.
session_timeout_minutesintNoHow long to wait for an answer before the session is marked abandoned.
questionsQuestion[]NoThe questions, inline — or add them one at a time afterwards (below).
curl -X POST https://api.mobilesasa.com/api/v1/surveys \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Delivery satisfaction — July",
    "keyword_uuid": "8c11d2ab-…",
    "sender_name": "40404",
    "welcome_message": "Thanks for ordering from Dukapay! 3 quick questions:",
    "end_message": "Asante! Your feedback keeps us sharp.",
    "session_timeout_minutes": 30,
    "questions": [
      {
        "question": "How would you rate your delivery? Reply 1-5",
        "question_type": "numeric",
        "sequence": 1,
        "is_required": true
      },
      {
        "question": "Was the rider courteous? Reply YES or NO",
        "question_type": "yes_no",
        "sequence": 2,
        "is_required": true
      },
      {
        "question": "Anything we should improve?",
        "question_type": "open",
        "sequence": 3,
        "is_required": false
      }
    ]
  }'

Add questions

POST/api/v1/surveys/{uuid}/questions
GET/api/v1/surveys/{uuid}/questions
DELETE/api/v1/surveys/{uuid}/questions/{question_uuid}

Question fields

FieldTypeRequiredDescription
questionstringYesThe text sent to the participant.
question_typestringYesopen (free text), single_choice, multiple_choice, numeric, yes_no.
optionsJSON stringNoFor choice types: the options as a JSON array string, e.g. "[\"M-Pesa\",\"Card\",\"Cash\"]". Participants reply with the option number.
sequenceintYesOrder the question is asked in (1-based).
is_requiredbooleanNoRequired questions re-prompt on an invalid answer; optional ones accept SKIP.
curl -X POST https://api.mobilesasa.com/api/v1/surveys/5e9dd410-…/questions \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "question": "How did you pay? 1. M-Pesa 2. Card 3. Cash",
    "question_type": "single_choice",
    "options": "[\"M-Pesa\",\"Card\",\"Cash\"]",
    "sequence": 4,
    "is_required": true
  }'

Lifecycle

POST/api/v1/surveys/{uuid}/activate
POST/api/v1/surveys/{uuid}/pause
POST/api/v1/surveys/{uuid}/close

Statuses

FieldTypeRequiredDescription
draftinitialNoEditable (PATCH); not answering traffic. A survey needs at least one question — and no pending system approval — before it can activate.
activeliveNoKeyword texts open sessions and questions flow.
pausedholdNoNew sessions refused; re-activate any time.
closedfinalNoDone — data remains available.

Approval on amendments

Setting or changing a survey's run window (POST /surveys/{uuid}/amend with starts_at/ends_at) puts it through a quick system review; the survey can't activate while that review is pending. You're emailed automatically when it's approved or rejected.

Test it before going live

POST/api/v1/surveys/{uuid}/simulate

The simulator walks a fake session without sending real SMS — post the participant's next reply, get back what the survey would send:

curl -X POST https://api.mobilesasa.com/api/v1/surveys/5e9dd410-…/simulate \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "msisdn": "254712345678",
    "message": "START"
  }'

You can also restrict a live survey to test numbers with the whitelist (PUT /surveys/{uuid}/whitelist with {"msisdns": ["2547…"]}; empty array lifts the restriction).

Pull the responses

GET/api/v1/surveys/{uuid}/responses
curl "https://api.mobilesasa.com/api/v1/surveys/5e9dd410-…/responses?page=1" \
  -H "Authorization: Bearer $MOBILESASA_TOKEN"
Response — 200
{
  "success": true,
  "data": [
    {
      "uuid": "77b0…",
      "session_uuid": "d2c4…",
      "msisdn": "254712345678",
      "question_uuid": "31aa…",
      "answer": "5",
      "created_at": "2026-07-11T12:40:19Z"
    }
  ],
  "meta": { "page": 1, "page_size": 20, "total": 412 }
}

Answers cost units

Each question and confirmation the survey sends is a normal SMS billed in units from your SMS balance. A 3-question survey costs roughly 4–5 units per completed session.