Skip to main content
This guide shows how to run a simple USSD menu app on your own server using a Belio callback endpoint. Belio will call your server whenever a subscriber dials your shortcode and presses keys on their phone. Your job is only to:
  1. Receive the JSON request.
  2. Read the full inputs history.
  3. Return the next screen as JSON.

Belio Eats Flow

This demo implements a small menu modeling a fast-food restaurant.
  • Home
    • 1. Order Food
    • 2. Track Order
  • Order Food
    • 1. Nyama Choma
    • 2. Pilau Beef
    • 3. Fried Tilapia
    • then: Quarter / Half / Full → Confirm → Done
  • Track Order
    • enter order number → status → Done

Screens

Language Examples

TypeScript Example

Prerequisites

  • Node.js 18+
  • A terminal

Create the project

src/server.ts

Run it

Add this script to package.json:
Then run:

Test With curl

You can test the callback without a phone.

Home screen

Expected response:

Order Food -> Nyama Choma -> Full -> Place order

Expected behavior:
  • action is END
  • the message mentions Nyama Choma
  • the message includes ORD-100245

Track an order

  • action is END
  • the message mentions Order Status
  • the message includes ORD-100245

Connect Belio to Your Server

  1. Deploy your app so it has a public HTTPS URL.
  2. For local testing, use a tunnel like ngrok http 3000.
  3. Configure the USSD callback URL as:
  1. Dial the shortcode on a test phone and walk through the menu.

Security and Reliability

For a real deployment, treat the callback as a public API endpoint.

Security

  • Validate the request body shape before processing it.
  • Reject anything that is not JSON.
  • Treat sessionId, msisdn, and inputs as untrusted input.
  • Do not log sensitive personal data unless you need it.
  • If Belio provides a signature or token, verify it on every request.
  • Use HTTPS only.
  • Do not rely on a hard-to-guess path as the only protection.

Reliability

  • Return HTTP 200 consistently for valid USSD replies, even when the input is invalid.
  • Never let the callback hang. USSD gateways expect a fast response.
  • Keep the menu logic deterministic and stateless where possible.
  • Use the full inputs array as the source of truth, not temporary server memory.
  • Handle bad input by redisplaying the current menu instead of crashing.
  • Add structured logs for sessionId and inputs so failed sessions can be traced.
  • Put the app behind a reverse proxy or platform that supports health checks and restarts.
  • Add timeouts and rate limiting if the endpoint is exposed publicly.

Practical Hardening

  • Limit request body size.
  • Validate code if your service should only answer one shortcode.
  • Sanitize order numbers before echoing them back.
  • Use environment variables for deployment settings like port and environment mode.
  • Add tests for each menu branch:
    • home
    • order flow
    • back navigation
    • invalid input
    • confirm or cancel
    • track order