Skip to main content

Quick Start Guide

Get up and running with OLA USSD Gateway in under 10 minutes. This guide will walk you through deploying the gateway, registering your first backend, and testing a simple USSD interaction.

Prerequisites

Before you begin, ensure you have:

  • Docker (recommended) OR Go 1.23+ installed
  • curl or Postman for testing
  • Basic understanding of HTTP/REST APIs
  • Your backend application (or use our example below)

Step 1: Make sure you have access to the gateway

Base URL

The Base URL for the gateway server is:

https://ussd.ola.pavulla.com

Check if it's running

curl https://ussd.ola.pavulla.com/health

Expected response:

{
"status": "ok",
"service": "ola-ussd-gateway",
"version": "1.0.0"
}

Step 2: Create a Simple Backend

For this quickstart, we'll create a minimal backend that responds to USSD requests. Choose your preferred language:

Node.js Backend

Create a file named ussd-backend.js:

const express = require('express');
const app = express();
app.use(express.json());

// In-memory session storage (for demo purposes)
const sessions = {};

app.post('/ussd/callback', (req, res) => {
const { msisdn, session_id, transaction_id, input } = req.body;

console.log(`Received request: msisdn=${msisdn}, input="${input}"`);

// Get or initialize session
if (!sessions[transaction_id]) {
sessions[transaction_id] = { step: 'main' };
}

let menu;
let endSession = false;

// Handle user navigation
if (!input) {
// First dial (empty input)
menu = [
"Welcome to QuickStart USSD",
"",
"1. Check Balance",
"2. Get Info",
"0. Exit"
];
} else if (input === "1") {
menu = ["Your balance is 500.00 MZN", "", "Press 0 to exit"];
} else if (input === "2") {
menu = ["OLA USSD Gateway", "Version 1.0", "", "Press 0 to exit"];
} else if (input === "0") {
menu = ["Thank you for using our service!"];
endSession = true;
delete sessions[transaction_id];
} else {
menu = ["Invalid option. Please try again."];
}

res.json({
session_id,
transaction_id,
output: menu,
end_session: endSession
});
});

app.get('/health', (req, res) => {
res.json({ status: 'ok' });
});

const PORT = 8081;
app.listen(PORT, () => {
console.log(`Backend running on port ${PORT}`);
});

Run it:

# Install Express if needed
npm install express

# Start the backend
node ussd-backend.js

Python Backend

Create a file named ussd_backend.py:

from flask import Flask, request, jsonify

app = Flask(__name__)

# In-memory session storage (for demo purposes)
sessions = {}

@app.route('/ussd/callback', methods=['POST'])
def ussd_callback():
data = request.json
msisdn = data['msisdn']
session_id = data['session_id']
transaction_id = data['transaction_id']
user_input = data.get('input', '')

print(f"Received request: msisdn={msisdn}, input='{user_input}'")

# Get or initialize session
if transaction_id not in sessions:
sessions[transaction_id] = {'step': 'main'}

menu = []
end_session = False

# Handle user navigation
if not user_input:
# First dial (empty input)
menu = [
"Welcome to QuickStart USSD",
"",
"1. Check Balance",
"2. Get Info",
"0. Exit"
]
elif user_input == "1":
menu = ["Your balance is 500.00 MZN", "", "Press 0 to exit"]
elif user_input == "2":
menu = ["OLA USSD Gateway", "Version 1.0", "", "Press 0 to exit"]
elif user_input == "0":
menu = ["Thank you for using our service!"]
end_session = True
if transaction_id in sessions:
del sessions[transaction_id]
else:
menu = ["Invalid option. Please try again."]

return jsonify({
'session_id': session_id,
'transaction_id': transaction_id,
'output': menu,
'end_session': end_session
})

@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'ok'})

if __name__ == '__main__':
app.run(port=8081, debug=True)

Run it:

# Install Flask if needed
pip install flask

# Start the backend
python ussd_backend.py

Step 3: Register Your Backend

Now register your backend with the gateway:

curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "httsp://{your-domain-or-public-ip}/ussd/callback",
"service_code": "*365#",
"name": "QuickStart Backend",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}'

Expected response:

{
"id": 1,
"callback_url": "https://{your-domain-or-public-ip}/ussd/callback",
"service_code": "*365#",
"name": "QuickStart Backend",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active",
"created_at": "2025-01-20T10:30:00Z"
}

Verify the registration:

curl https://ussd.ola.pavulla.com/backends

Step 4: Test Your Integration

Simulate a USSD Session

Now simulate what happens when a user dials *365#:

1. Initial Dial (Empty Input)

curl -X POST https://ussd.ola.pavulla.com/ussd/test/callback \
-H "Content-Type: application/json" \
-d '{
"provider": "movitel",
"msisdn": "258823456789",
"session_id": "test-sess-001",
"transaction_id": "test-txn-001",
"service_code": "*365#",
"input": ""
}'

Expected response:

{
"session_id": "test-sess-001",
"transaction_id": "test-txn-001",
"output": [
"Welcome to QuickStart USSD",
"",
"1. Check Balance",
"2. Get Info",
"0. Exit"
],
"end_session": false
}

2. User Selects "1" (Check Balance)

curl -X POST https://ussd.ola.pavulla.com/ussd/test/callback \
-H "Content-Type: application/json" \
-d '{
"provider": "movitel",
"msisdn": "258823456789",
"session_id": "test-sess-001",
"transaction_id": "test-txn-002",
"service_code": "*365#",
"input": "1"
}'

Expected response:

{
"session_id": "test-sess-001",
"transaction_id": "test-txn-002",
"output": [
"Your balance is 500.00 MZN",
"",
"Press 0 to exit"
],
"end_session": false
}

3. User Selects "0" (Exit)

curl -X POST https://ussd.ola.pavulla.com/ussd/test/callback \
-H "Content-Type: application/json" \
-d '{
"provider": "movitel",
"msisdn": "258823456789",
"session_id": "test-sess-001",
"transaction_id": "test-txn-003",
"service_code": "*365#",
"input": "0"
}'

Expected response:

{
"session_id": "test-sess-001",
"transaction_id": "test-txn-003",
"output": [
"Thank you for using our service!"
],
"end_session": true
}

Step 5: Understand What Just Happened

Here's the flow that occurred:

Key Points:

  1. Gateway received your request
  2. Matched *365# to your backend
  3. Forwarded normalized JSON to "https://{your-domain-or-public-ip}/ussd/callback
  4. Your backend processed the request
  5. Gateway returned the response

What's Next?

Congratulations! You've successfully: ✅ Deployed the OLA Gateway ✅ Created a simple backend application ✅ Registered your backend with the gateway ✅ Tested a complete USSD flow

Next Steps

  1. Session Management - Handle complex multi-step flows
  2. Menu Navigation - Implement advanced menu logic
  3. API Reference - Complete API specification

Production Checklist

Before going to production, ensure you:

  • Use a database-backed session store (PostgreSQL)
  • Implement proper error handling in your backend
  • Add authentication/authorization
  • Set up monitoring and logging
  • Configure proper timeouts and retries
  • Test with real provider connections
  • Implement rate limiting
  • Set up SSL/TLS certificates

Troubleshooting

Backend Not Receiving Requests

Problem: Gateway can't reach your backend Solution: Ensure backend is running and URL is correct

# Check backend health
curl "https://{your-domain-or-public-ip}/health

# Verify registration
curl https://ussd.ola.pavulla.com/backends

Invalid Response Format

Problem: Gateway returns error Solution: Ensure your backend returns proper JSON format:

{
"session_id": "required",
"transaction_id": "required",
"output": ["array", "of", "strings"],
"end_session": true/false
}

Need Help?