USSD Sessions
A USSD session holds the state of a single user interaction โ from the moment they dial your shortcode until the flow ends or times out. This page covers advancing, inspecting, and ending sessions, plus storing custom session data.
๐ Session Lifecycleโ
| State | Meaning |
|---|---|
initiated | Created when the user dials the shortcode |
active | User is navigating menus |
expired | No activity within the timeout window |
completed | Ended by your app or the user |
Sessions are keyed by session_id. Always store and look up state by session_id rather than phone number, since one user may have concurrent sessions.
๐ก Endpointsโ
| Method | Path | Purpose |
|---|---|---|
POST | /v1/ussd/continue | Advance the session with the user's input |
GET | /v1/ussd/sessions/{session_id} | Retrieve current session state |
POST | /v1/ussd/sessions/{session_id}/end | End an active session |
Base URL: https://api.afriroute.ai
โถ๏ธ Continue a Sessionโ
POST /v1/ussd/continue
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | Identifier from the initial send call |
input | string | Yes | The user's input/selection |
message | string | Yes | The next screen to display (max 182 chars) |
end_session | boolean | No | End the session after this screen (default false) |
data | object | No | Custom state to persist on the session |
curl -X POST https://api.afriroute.ai/api/v1/ussd/continue \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"session_id": "sess_abc123",
"input": "2",
"message": "Enter recipient phone:",
"data": { "step": "transfer_phone" }
}'
await fetch('https://api.afriroute.ai/api/v1/ussd/continue', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
session_id: 'sess_abc123',
input: '2',
message: 'Enter recipient phone:',
data: { step: 'transfer_phone' }
})
});
import requests
requests.post(
'https://api.afriroute.ai/api/v1/ussd/continue',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'session_id': 'sess_abc123',
'input': '2',
'message': 'Enter recipient phone:',
'data': {'step': 'transfer_phone'},
},
)
๐ Get Session Stateโ
GET /v1/ussd/sessions/{session_id}
curl https://api.afriroute.ai/api/v1/ussd/sessions/sess_abc123 \
-H "Authorization: Bearer $AFRIROUTE_API_KEY"
Responseโ
{
"session_id": "sess_abc123",
"phone": "+251911234567",
"shortcode": "*123#",
"status": "active",
"created_at": "2026-05-28T10:30:00Z",
"last_activity": "2026-05-28T10:32:15Z",
"expires_at": "2026-05-28T10:33:45Z",
"data": {
"step": "transfer_phone",
"recipient": "+251922334455"
},
"history": [
{ "step": 1, "input": null, "output": "Welcome!..." },
{ "step": 2, "input": "2", "output": "Enter recipient phone:" }
]
}
โน๏ธ End a Sessionโ
POST /v1/ussd/sessions/{session_id}/end
curl -X POST https://api.afriroute.ai/api/v1/ussd/sessions/sess_abc123/end \
-H "Authorization: Bearer $AFRIROUTE_API_KEY"
Returns the session with status: "completed". You can also end a session by setting end_session: true on a /continue call.
๐๏ธ Storing Session Dataโ
Use the data object to carry state between steps. It is encrypted at rest and returned on every GET. Keep it small โ it is meant for flow state (current step, partial inputs), not large records.
// Persist progressively as the user advances
await continueUSSD({
session_id: 'sess_abc123',
input: '+251922334455',
message: 'Enter amount:',
data: { step: 'transfer_amount', recipient: '+251922334455' }
});
โฑ๏ธ Timeout Handlingโ
The default timeout is 90 seconds of inactivity (configurable up to 180 via timeout on the initial send). When a session expires you receive a ussd.session_ended callback with reason: "expired" โ use it to clean up partial state. See Callbacks.
๐ก Best Practicesโ
- Key everything by
session_id, never by phone number. - Make each step idempotent โ the same input may arrive twice on retries.
- Persist only flow state in
data; store records in your own database. - End sessions explicitly with
end_session: truefor terminal screens.
๐ Related Resourcesโ
Last Updated: May 2026 ยท Need help? Contact Support โ