USSD Webhooks

The endpoints carriers call to deliver live USSD sessions to your service.

Mobile Sasa calls these endpoints to hand off each session event. You do not have to register anything: when a USSD code or extension is approved, your platform points Mobile Sasa at the first URL below automatically. Unlike the rest of the API, these routes take no authentication token, they are publicly accessible endpoints trusted by carrier IP ranges, so never put secrets in the URLs.

No Bearer token here

Webhook routes are called by Mobile Sasa, not by your server. They are unauthenticated by design. Do not send an Authorization header, and do not expose these URLs as if they were your API token endpoints.

Mobile Sasa webhook

POST/webhooks/ussd/mobilesasa

Mobile Sasa carries USSD for every Kenyan network. It sends each session event as a form post (application/x-www-form-urlencoded). Answer with JSON.

Received form fields
sessionIdreq
string

Unique session identifier from the carrier

phoneNumberreq
string

Subscriber phone number

networkCode
string

Network the subscriber is on

serviceCodereq
string

USSD code that was dialed

text
string

All input so far in the session, empty on the first request

Your response
// continue the session
{ "response": "Acme Services\n1. Check balance\n2. Buy data", "end_session": false }

// or end it
{ "response": "Thank you for using Acme Services.", "end_session": true }

No CON or END prefix here

end_session alone decides whether the session continues. Do not prefix the response text with CON or END , the subscriber would see the prefix on their handset.

Generic JSON webhook

POST/webhooks/ussd/inbound

For other carriers that speak a JSON API. Both the request from the carrier and your response use JSON.

Request body from carrier
msisdnreq
string

Subscriber phone

service_codereq
string

USSD code dialed

session_idreq
string

Carrier session ID

ussd_string
string

Subscriber input so far

network
string

Network identifier (airtel, telkom, equitel)

Request from carrier
{
  "msisdn": "+254712345678",
  "service_code": "*657#",
  "session_id": "carrier-sess-abc123",
  "ussd_string": "*657*1#",
  "network": "airtel"
}
Your response
{
  "response": "CON Acme Services\n1. Check balance\n2. Buy data",
  "end_session": false
}

Callback mode, your own server

When a code or extension is set to mode=callback, the platform forwards each session event to your callback_url as a POST. Your server must respond within 3 seconds with a JSON body.

POST to your callback_url for each session event
{
  "session_id":   "carrier-sess-abc123",
  "service_code": "*657#",
  "msisdn":       "+254712345678",
  "ussd_string":  "*657*1#",
  "network":      "safaricom"
}
Your response (continue, or end)
// continue the session
{ "response": "CON Your balance is KES 1,200.\n0. Back", "end_session": false }

// or end it
{ "response": "END Thank you!", "end_session": true }

Test the whole flow first

Exercise your menus and callback handlers end to end with USSD simulation before pointing a carrier at these webhook URLs.