USSD Webhooks
The endpoints carriers call to deliver live USSD sessions to your service.
The carrier 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 the carrier 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
Authorization header, and do not expose these URLs as if they were your API token endpoints.Carrier webhook
The carrier handles 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
- sessionIdstringrequired
- Unique session identifier from the carrier
- phoneNumberstringrequired
- Subscriber phone number
- networkCodestring
- Network the subscriber is on
- serviceCodestringrequired
- USSD code that was dialed
- textstring
- All input so far in the session, empty on the first request
// 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
For other carriers that speak a JSON API. Both the request from the carrier and your response use JSON.
Request body from carrier
- msisdnstringrequired
- Subscriber phone
- service_codestringrequired
- USSD code dialed
- session_idstringrequired
- Carrier session ID
- ussd_stringstring
- Subscriber input so far
- networkstring
- Network identifier (airtel, telkom, equitel)
{
"msisdn": "+254712345678",
"service_code": "*657#",
"session_id": "carrier-sess-abc123",
"ussd_string": "*657*1#",
"network": "airtel"
}{
"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.
{
"session_id": "carrier-sess-abc123",
"service_code": "*657#",
"msisdn": "+254712345678",
"ussd_string": "*657*1#",
"network": "safaricom"
}// 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