USSD codes & extensions
Two ways onto the dial pad: apply for your own dedicated *XYZ# code, or take an extension on a shared code (*384*45#) and be live in days instead of weeks.
Endpoints live under /api/v1/ with a scoped mbs_ token or JWT. Once a code or extension is approved, you decide how sessions are answered — a hosted menu, a survey, or callback mode against your own backend.
Fees
Approval checks your wallet — and fails if it can't pay
Option A — extension on a shared code
List the platform's shared codes, then check whether the extension you want is free:
curl "https://api.mobilesasa.com/api/v1/ussd/shared-codes/6a77e0b2-…/availability?extension=45" \
-H "Authorization: Bearer $MOBILESASA_TOKEN"Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| ussd_code_id | uuid | Yes | UUID of the shared code (from the listing above). |
| extension | string | Yes | The digits after the star — customers dial *384*45# for extension 45. 1–2 digit extensions cost more than longer ones. |
| networks | string[] | Yes | Networks the extension must answer on. |
curl -X POST https://api.mobilesasa.com/api/v1/ussd/extensions \
-H "Authorization: Bearer $MOBILESASA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"ussd_code_id": "6a77e0b2-…",
"extension": "45",
"networks": [
"safaricom",
"airtel"
]
}'Option B — dedicated code
A dedicated code (*728#) is registered with the networks in your name — expect network paperwork and a longer lead time. Send JSON for a bare application, or multipart/form-data when attaching supporting documents (authorisation letters, business certificate — 10 MB max per file; the file field name becomes the document type, with an optional network_{field} form value scoping it to one network).
curl -X POST https://api.mobilesasa.com/api/v1/ussd/codes \
-H "Authorization: Bearer $MOBILESASA_TOKEN" \
-F "code=*728#" \
-F "networks=safaricom" \
-F "networks=airtel" \
-F "[email protected]" \
-F "network_request_letter=safaricom"JSON mode works too when there are no documents: {"code": "*728#", "networks": ["safaricom","airtel"]}.
Track the application
Both codes and extensions carry an approval_status (pending → approved | rejected, with rejection_reason on rejects — you're also emailed automatically either way) and a runtime status once live.
curl "https://api.mobilesasa.com/api/v1/ussd/extensions/91c2f7aa-…" \
-H "Authorization: Bearer $MOBILESASA_TOKEN"Point it somewhere
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| mode | string | No | menu (hosted menu), survey, or callback (your backend drives every screen — see callback mode). |
| menu_id | uuid | No | The approved menu to serve, when mode is menu. |
| survey_id | uuid | No | The survey to run, when mode is survey. |
| callback_url | string | No | Your HTTPS endpoint, when mode is callback. |
curl -X PUT https://api.mobilesasa.com/api/v1/ussd/extensions/91c2f7aa-… \
-H "Authorization: Bearer $MOBILESASA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "callback",
"callback_url": "https://example.com/ussd"
}'