Standalone mock API for the Sarufi USSD Engine. Provides realistic endpoints that demonstrate every node type in the flow builder — no database, no authentication, purely in-memory.
# 1. Create virtual environment python -m venv .venv source .venv/bin/activate # macOS/Linux # .venv\Scripts\activate # Windows # 2. Install dependencies pip install -r requirements.txt # 3. Copy env config cp .env.example .env # 4. Run the service python main.pyThe service starts on http://localhost:9000. Interactive API docs are available at http://localhost:9000/docs.
All endpoints are prefixed with /api/v1/demo.
| Method | Endpoint | Description | Flow Builder Node |
|---|---|---|---|
POST | /verify-user | Verify a user by phone number | API Action (conditional branching) |
POST | /register-user | Register a new user | Input + API Call |
GET | /balance/{phone} | Get account balance | API Call (display response) |
POST | /validate-account | Validate recipient account | API Action (conditional branching) |
POST | /transfer | Execute money transfer | API Call (success/error display) |
GET | /services | List available services | Dynamic Menu |
POST | /webhook-log | Log a webhook event | Webhook |
GET | /webhook-log | Retrieve logged webhooks | Debugging |
curl -X POST http://localhost:9000/api/v1/demo/verify-user \ -H "Content-Type: application/json" \ -d '{"phone": "255712345678"}'Response (known user):
{ "data": { "verified": true, "name": "John Doe", "account_number": "1001234567", "tier": "premium" } }Response (unknown user):
{ "data": { "verified": false, "name": "", "account_number": "", "tier": "" } }curl -X POST http://localhost:9000/api/v1/demo/register-user \ -H "Content-Type: application/json" \ -d '{"phone": "255700000000", "name": "Alice", "pin": "1234"}'Response:
{ "data": { "success": true, "message": "Welcome Alice! Your account has been created.", "name": "Alice", "account_number": "1005839271" } }curl http://localhost:9000/api/v1/demo/balance/255712345678Response:
{ "data": { "balance": 1250000.0, "available": 1200000.0, "currency": "TZS", "account_number": "1001234567" } }curl http://localhost:9000/api/v1/demo/servicesResponse:
{ "data": { "services": [ {"id": "airtime", "name": "Buy Airtime", "price": "Varies"}, {"id": "electricity", "name": "Pay Electricity", "price": "Varies"}, {"id": "water", "name": "Pay Water Bill", "price": "Varies"}, {"id": "tv", "name": "TV Subscription", "price": "15,000 TZS"}, {"id": "insurance", "name": "Insurance", "price": "From 5,000 TZS"} ] } }curl -X POST http://localhost:9000/api/v1/demo/validate-account \ -H "Content-Type: application/json" \ -d '{"account_number": "1001234567"}'Response:
{ "data": { "valid": true, "name": "John Doe", "account_number": "1001234567" } }curl -X POST http://localhost:9000/api/v1/demo/transfer \ -H "Content-Type: application/json" \ -d '{"from_account": "1001234567", "to_account": "1009876543", "amount": 50000}'Response:
{ "data": { "success": true, "transaction_id": "TXN482917", "amount": 50000.0, "new_balance": 1150000.0, "currency": "TZS", "timestamp": "2025-02-11T10:30:00+00:00" } }# Send a webhook event curl -X POST http://localhost:9000/api/v1/demo/webhook-log \ -H "Content-Type: application/json" \ -d '{"event": "session_complete", "session_id": "abc123"}' # Retrieve logs curl http://localhost:9000/api/v1/demo/webhook-log?limit=5The service comes with two pre-loaded users:
| Phone | Name | Account | Tier | Balance |
|---|---|---|---|---|
255712345678 | John Doe | 1001234567 | premium | 1,250,000 TZS |
255787654321 | Jane Smith | 1009876543 | standard | 750,000 TZS |
New users registered via /register-user are added to the in-memory store and persist until the service restarts.
The USSD engine backend needs to reach this service over the network. Running on localhost alone won't work — you need a tunnel to get a public URL.
# Install ngrok (https://ngrok.com) ngrok http 9000ngrok gives you a public URL like https://a1b2c3d4.ngrok-free.app. Use that as your base URL in the flow builder.
# Install cloudflared (https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/) cloudflared tunnel --url http://localhost:9000npx localtunnel --port 9000Tip: Any tunnel provider works. Pick whichever you prefer — the only requirement is that the demo service is reachable via a public HTTPS URL.
Once your tunnel is running, copy the public URL and use it when configuring API nodes in the Sarufi USSD Flow Builder:
https://<your-tunnel-url>/api/v1/demo/<endpoint> For example, in an API Action node for user verification:
- URL:
https://<your-tunnel-url>/api/v1/demo/verify-user - Method:
POST - Body:
{"phone": "{{phone}}"} - Condition:
data.verified == true
For a Dynamic Menu node:
- URL:
https://<your-tunnel-url>/api/v1/demo/services - Method:
GET - List path:
data.services - Label key:
name - Value key:
id
| Variable | Default | Description |
|---|---|---|
PORT | 9000 | Server port |
LOG_LEVEL | INFO | Logging level (DEBUG, INFO, WARNING, ERROR) |