Skip to main content

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:

  1. Running and accessible from the gateway
  2. Exposing an HTTP endpoint (e.g., /ussd/callback)
  3. 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​

FieldTypeDescriptionExample
callback_urlstringYour backend's webhook URLhttp://api.example.com/ussd
service_codestringUSSD short code*365#
namestringHuman-readable nameBanking Service
typestringBackend typehttp
methodstringHTTP methodPOST
statusstringActive statusactive or inactive

Optional Fields​

FieldTypeDefaultDescription
timeoutinteger5Request timeout in seconds
retriesinteger2Number 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 services
  • webhook - Webhook-style callbacks
  • lambda - 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:

  1. Gateway stops waiting after timeout
  2. Triggers retry (if configured)
  3. 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 requests
  • inactive - 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:

  1. Find your backend by service code (*365#)
  2. Forward request to your callback URL
  3. 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:

  1. Verify registration:
curl https://ussd.ola.pavulla.com/backends
  1. Check service code match:
curl "https://ussd.ola.pavulla.com/backends/service?code=*365%23"
  1. Verify backend status:
{
"status": "active" // Must be active
}
  1. Test connectivity:
# From gateway server
curl http://your-backend:8081/health

Registration Fails​

Problem: POST /backends returns error.

Common issues:

  1. Invalid URL:
# ❌ Missing protocol
"callback_url": "localhost:8081/ussd"

# ✅ Correct
"callback_url": "https://{your-domain-or-public-ip}/ussd"
  1. Invalid service code:
# ❌ Missing # or *
"service_code": "365"

# ✅ Correct
"service_code": "*365#"
  1. Duplicate service code:
Error: service code *365# already registered

Solution: Delete existing or use different code.

Timeout Issues​

Problem: Requests timing out.

Solutions:

  1. Increase timeout:
{
"timeout": 15 // Increase from 5 to 15 seconds
}
  1. Optimize backend:

    • Cache frequent queries
    • Use async processing
    • Reduce external API calls
  2. 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​

Need Help?​