Backend Registration
Learn how to register your backend application with the OLA USSD Gateway.
Overview
Before your backend can receive USSD requests, you must register it with the gateway. Registration tells the gateway:
- Where to send requests (your callback URL)
- Which service code to route (
*365#,*105#, etc.) - How to handle errors (timeouts, retries)
Registration Process
Step 1: Prepare Your Backend
Ensure your backend is:
- Running and accessible from the gateway
- Exposing an HTTP endpoint (e.g.,
/ussd/callback) - Implementing the API contract (see API Contract)
Test your backend:
curl -X POST "https://{your-domain-or-public-ip}/ussd/callback \
-H "Content-Type: application/json" \
-d '{
"provider": "movitel",
"msisdn": "258823456789",
"session_id": "test_123",
"transaction_id": "txn_123",
"input": ""
}'
Step 2: Register with Gateway
Use the gateway's REST API to register your backend:
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "http://your-backend.com:8081/ussd/callback",
"service_code": "*365#",
"name": "MyBank USSD Service",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}'
Response:
{
"id": 1,
"callback_url": "http://your-backend.com:8081/ussd/callback",
"service_code": "*365#",
"name": "MyBank USSD Service",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active",
"created_at": "2025-01-20T10:30:00Z",
"updated_at": "2025-01-20T10:30:00Z"
}
Step 3: Verify Registration
List all registered backends:
curl https://ussd.ola.pavulla.com/backends
Get backend by service code:
curl "https://ussd.ola.pavulla.com/backends/service?code=*365%23"
Registration Fields
Required Fields
| Field | Type | Description | Example |
|---|---|---|---|
callback_url | string | Your backend's webhook URL | http://api.example.com/ussd |
service_code | string | USSD short code | *365# |
name | string | Human-readable name | Banking Service |
type | string | Backend type | http |
method | string | HTTP method | POST |
status | string | Active status | active or inactive |
Optional Fields
| Field | Type | Default | Description |
|---|---|---|---|
timeout | integer | 5 | Request timeout in seconds |
retries | integer | 2 | Number of retry attempts |
Field Details
callback_url
The full URL where your backend receives requests.
Format: http(s)://host:port/path
Examples:
// Local development
"callback_url": "https://{your-domain-or-public-ip}/ussd/callback"
// Production
"callback_url": "https://api.mybank.com/ussd/callback"
// Internal network
"callback_url": "http://ussd-backend.internal:8080/webhook"
Important:
- Must be accessible from the gateway
- Use HTTPS in production
- Include full path
- Don't include query parameters
service_code
The USSD short code that triggers this backend.
Format: * + digits + #
Examples:
"service_code": "*365#" // Simple code
"service_code": "*105#" // Another code
"service_code": "*123*456#" // With sub-code
Rules:
- Must start with
* - Must end with
# - Can include digits and additional
* - Case-sensitive
- One backend per service code
URL Encoding: When querying by service code, URL-encode the #:
# ✅ Correct
curl "https://ussd.ola.pavulla.com/backends/service?code=*365%23"
# ❌ Wrong
curl "https://ussd.ola.pavulla.com/backends/service?code=*365#"
name
A descriptive name for your backend.
Purpose: Human-readable identification in logs and admin UIs.
Examples:
"name": "Mobile Banking Service"
"name": "Utility Bill Payments"
"name": "Airtime Top-up - Production"
type
The backend type (currently only http is supported).
Future types may include:
grpc- gRPC serviceswebhook- Webhook-style callbackslambda- Serverless functions
timeout
Maximum time (in seconds) to wait for your backend's response.
Default: 5 seconds
Recommendations:
- Development: 10-30 seconds (for debugging)
- Production: 5-10 seconds
- Fast operations: 3-5 seconds
- External API calls: 10-15 seconds
Example:
{
"timeout": 10, // Wait up to 10 seconds
//...
}
What happens on timeout:
- Gateway stops waiting after timeout
- Triggers retry (if configured)
- Eventually returns error to user
retries
Number of retry attempts if your backend fails or times out.
Default: 2
Retry Strategy: Exponential backoff
- Attempt 1: Immediate
- Attempt 2: Wait 1 second
- Attempt 3: Wait 2 seconds
Recommendations:
- Idempotent operations: 2-3 retries
- Non-idempotent operations: 0-1 retries
- Critical services: 3-5 retries
Example:
{
"retries": 3, // Try up to 3 times
// ...
}
method
HTTP method for requests to your backend.
Supported: POST, GET, PUT
Recommendation: Use POST (standard for webhooks)
{
"method": "POST", // Recommended
// ...
}
status
Whether the backend is active.
Values:
active- Backend receives requestsinactive- Backend disabled, requests fail
Use cases:
- Disable backend during maintenance
- A/B testing (activate/deactivate alternates)
- Gradual rollout
Managing Backends
List All Backends
curl https://ussd.ola.pavulla.com/backends
Response:
[
{
"id": 1,
"callback_url": "http://backend1.com/ussd",
"service_code": "*365#",
"name": "Banking Service",
"status": "active"
},
{
"id": 2,
"callback_url": "http://backend2.com/ussd",
"service_code": "*105#",
"name": "Utility Payments",
"status": "inactive"
}
]
Get Specific Backend
By ID:
curl https://ussd.ola.pavulla.com/backends/1
By service code:
curl "https://ussd.ola.pavulla.com/backends/service?code=*365%23"
Update Backend
curl -X PUT https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"id": 1,
"callback_url": "http://new-backend.com/ussd",
"service_code": "*365#",
"name": "Banking Service v2",
"type": "http",
"timeout": 10,
"retries": 3,
"method": "POST",
"status": "active"
}'
Delete Backend
curl -X DELETE "https://ussd.ola.pavulla.com/backends?id=1"
Activate/Deactivate Backend
Update status only:
# Deactivate
curl -X PUT https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"id": 1,
"status": "inactive",
"callback_url": "http://backend.com/ussd",
"service_code": "*365#",
"name": "Banking Service",
"type": "http",
"method": "POST"
}'
# Reactivate
curl -X PUT https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"id": 1,
"status": "active",
...
}'
Registration Examples
Example 1: Development Setup
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://{your-domain-or-public-ip}/ussd/callback",
"service_code": "*365#",
"name": "Dev Banking Service",
"type": "http",
"timeout": 30,
"retries": 1,
"method": "POST",
"status": "active"
}'
Example 2: Production Setup
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://api.mybank.com/ussd/callback",
"service_code": "*365#",
"name": "MyBank Production",
"type": "http",
"timeout": 8,
"retries": 3,
"method": "POST",
"status": "active"
}'
Example 3: Multiple Services
Register different backends for different service codes:
# Banking service
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://banking.example.com/ussd",
"service_code": "*365#",
"name": "Banking Service",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}'
# Utility payments
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://utilities.example.com/ussd",
"service_code": "*105#",
"name": "Utility Payments",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}'
# Airtime top-up
curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "https://airtime.example.com/ussd",
"service_code": "*150#",
"name": "Airtime Service",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}'
Testing Registration
Test 1: Verify Backend is Reachable
From the gateway server:
curl -X POST http://your-backend:8081/ussd/callback \
-H "Content-Type: application/json" \
-d '{
"provider": "movitel",
"msisdn": "258823456789",
"session_id": "test_sess",
"transaction_id": "test_txn",
"input": ""
}'
Test 2: Simulate USSD Request
After registration, simulate a USSD session:
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": ""
}'
The gateway should:
- Find your backend by service code (
*365#) - Forward request to your callback URL
- Return your backend's response
Test 3: Check Gateway Logs
Monitor gateway logs to see routing:
# Docker
docker logs -f ola-gateway
# Binary
tail -f /var/log/ola-gateway/app.log
Look for:
INFO Routing request to backend: MyBank USSD Service
INFO Backend responded in 120ms
Troubleshooting
Backend Not Receiving Requests
Problem: Gateway doesn't forward requests to your backend.
Solutions:
- Verify registration:
curl https://ussd.ola.pavulla.com/backends
- Check service code match:
curl "https://ussd.ola.pavulla.com/backends/service?code=*365%23"
- Verify backend status:
{
"status": "active" // Must be active
}
- Test connectivity:
# From gateway server
curl http://your-backend:8081/health
Registration Fails
Problem: POST /backends returns error.
Common issues:
- Invalid URL:
# ❌ Missing protocol
"callback_url": "localhost:8081/ussd"
# ✅ Correct
"callback_url": "https://{your-domain-or-public-ip}/ussd"
- Invalid service code:
# ❌ Missing # or *
"service_code": "365"
# ✅ Correct
"service_code": "*365#"
- Duplicate service code:
Error: service code *365# already registered
Solution: Delete existing or use different code.
Timeout Issues
Problem: Requests timing out.
Solutions:
- Increase timeout:
{
"timeout": 15 // Increase from 5 to 15 seconds
}
-
Optimize backend:
- Cache frequent queries
- Use async processing
- Reduce external API calls
-
Check backend logs:
- Is it receiving requests?
- How long does processing take?
Best Practices
1. Use HTTPS in Production
{
"callback_url": "https://api.example.com/ussd" // Not http://
}
2. Set Appropriate Timeouts
{
"timeout": 5, // 5 seconds for most operations
"retries": 2 // Retry twice on failure
}
3. Use Descriptive Names
{
"name": "Banking Service - Production v2.1" // Clear and versioned
}
4. Test Before Activating
{
"status": "inactive" // Test first, then activate
}
Then update to active after testing.
5. Monitor Registrations
Keep a record of your registrations:
#!/bin/bash
# save-registration.sh
RESPONSE=$(curl -X POST https://ussd.ola.pavulla.com/backends \
-H "Content-Type: application/json" \
-d '{
"callback_url": "'"$CALLBACK_URL"'",
"service_code": "'"$SERVICE_CODE"'",
"name": "'"$NAME"'",
"type": "http",
"timeout": 5,
"retries": 2,
"method": "POST",
"status": "active"
}')
echo "$RESPONSE" > registration-$(date +%Y%m%d-%H%M%S).json
6. Use Environment Variables
export GATEWAY_URL="http://localhost:8080"
export BACKEND_URL="http://localhost:8081"
export SERVICE_CODE="*365#"
curl -X POST $GATEWAY_URL/backends \
-H "Content-Type: application/json" \
-d "{
\"callback_url\": \"$BACKEND_URL/ussd/callback\",
\"service_code\": \"$SERVICE_CODE\",
...
}"
Next Steps
- API Contract - Understand request/response formats
- Session Management - Handle user sessions
- Menu Flows - Build menu navigation
- Examples - See real-world implementations