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?