Building a USSD application

A simple guide to understanding the request and response flow behind a USSD application.

Using a local callback

If your backend is running locally, you can use its local URL as the callback when CORS is configured to allow requests from the emulator. If you run into CORS restrictions, configure CORS on your backend to allow the emulator's origin. Alternatively, tools such as ngrok can expose your local backend through a public HTTPS URL, which you can use as the callback.

How USSD works

A user starts a USSD session by dialing a service code. The USSD gateway sends the request to your application, and your application responds with the next screen.

User
USSD Gateway
Your Backend

This emulator replaces the USSD gateway during development. It sends the same kind of request to your callback and displays the response.

Build your callback

Your backend needs an HTTP endpoint that accepts the USSD request and returns a plain-text response.

callbackHTTP
 POST /api/ussd 

Request format

The emulator supports both GET and POST callbacks.

POST

POST requests contain the USSD data as JSON.

request.jsonJSON
 { "sessionId": "123456789", "serviceCode": "*123#", "phoneNumber": "254700000000", "text": "1*2" } 

GET

GET requests contain the same values as URL query parameters.

requestHTTP
 GET /api/ussd ?sessionId=123456789 &serviceCode=*123%23 &phoneNumber=254700000000 &text=1*2 

Response format

Your backend should return a plain-text response beginning with either CON or END.

CON

Use CON when you want the session to continue and expect more input.

responseTEXT
 CON Welcome to Acme 1. Check Balance 2. Buy Airtime 

END

Use END when the session is finished.

responseTEXT
 END Transaction successful 

Session and text

The emulator generates a session ID when a session starts. The same ID is sent with every request during that session.

The text value contains the user's input history separated by *.

Input: 1
Input: 2
Input: 500
text: 1*2*500

Testing locally

You can point the emulator directly at a local backend, for example:

callbackURL
 http://localhost:8000/api/ussd 

When the emulator is hosted online, your browser cannot normally access a callback running only on your machine. For local development, expose your backend through a secure tunnel.

Your backend must also allow requests from the emulator through CORS. If the callback works with curl or Postman but not from the emulator, check your backend's CORS configuration.