Skip to main content

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โ€‹

StateMeaning
initiatedCreated when the user dials the shortcode
activeUser is navigating menus
expiredNo activity within the timeout window
completedEnded 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โ€‹

MethodPathPurpose
POST/v1/ussd/continueAdvance the session with the user's input
GET/v1/ussd/sessions/{session_id}Retrieve current session state
POST/v1/ussd/sessions/{session_id}/endEnd an active session

Base URL: https://api.afriroute.ai

โ–ถ๏ธ Continue a Sessionโ€‹

POST /v1/ussd/continue
FieldTypeRequiredDescription
session_idstringYesIdentifier from the initial send call
inputstringYesThe user's input/selection
messagestringYesThe next screen to display (max 182 chars)
end_sessionbooleanNoEnd the session after this screen (default false)
dataobjectNoCustom 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: true for terminal screens.

Last Updated: May 2026 ยท Need help? Contact Support โ†’