ReachNG API Documentation

SMS & OTP Service API Reference for Partners

Base URL

https://reachng.com/api/functions/

All API requests are made to this base URL. Use HTTPS only.

Authentication

All requests require an API key in the request body. You have two API keys:

  • Test Key — For development (no cost, messages are simulated)
  • Live Key — For production (real charges apply)

Generate keys in your dashboard Settings → API Keys.

Get Wallet Balance

Fetch your current wallet balance programmatically. Ideal for monitoring funds before sending — e.g. polling every hour to trigger a low-balance alert on your side.

Supports both POST (api_key in body) and GET (api_key as query param).

Endpoint

POST https://reachng.com/api/functions/partnerGetBalance

GET alternative: https://reachng.com/api/functions/partnerGetBalance?api_key=your_api_key_here

Request Body

{
  "api_key": "your_api_key_here"
}

Response (Success)

{
  "status": "ok",
  "partner_id": "prt_abc123",
  "company_name": "AcmeCorp",
  "mode": "live",
  "wallet_balance": 482.30,
  "currency": "NGN",
  "retrieved_at": "2026-07-14T10:00:00Z"
}

Example cURL

curl -X POST https://reachng.com/api/functions/partnerGetBalance \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "live_abc123xyz"
  }'

Send Transactional SMS (OTP)

Send individual OTP or transactional messages to a single recipient.

Endpoint

POST https://reachng.com/api/functions/partnerSendSms

Content Guidelines

⚠️ Content Filter Enforced

This endpoint enforces a keyword content filter. Messages containing promotional or marketing keywords, discount offers, call-to-action phrases, or similar marketing language will be automatically rejected before sending — protecting your sender ID reputation and transactional route integrity.

Use this endpoint strictly for: OTP, verification codes, PIN resets, password resets, account alerts, appointment reminders, and other transactional communications.

Need to send marketing or promotional content? Use the promotional endpoint instead — it is purpose-built for campaigns and does not apply the transactional keyword filter.

Rejected Content Examples

The following types of content will be rejected by the filter:

❌ Rejected — Promotional

"Get 50% off this weekend! Shop now."

❌ Rejected — Marketing

"Limited offer! Buy now and save big."

✅ Accepted — Transactional

"Your AcmeCorp OTP is 123456. Expires in 5 mins."

✅ Accepted — Alert

"AcmeCorp: Your account was logged in successfully."

Sender ID

Your sender ID is configured by ReachNG support and determines how messages appear on recipients' phones. Available sender IDs:

  • ReachNG — Transactional route (default)
  • R Alert — Promotional route (default)
  • NGReach — Supports both transactional and promotional routes

Custom Branding? To use your own custom sender ID, email business@reachng.com with your business licenses and we'll activate custom branding for you.

Message Format Recommendation

📌 Best Practice — Include Your Company Name

Since all messages are sent with the ReachNG sender ID, we strongly recommend including your company name in the message body so recipients know who the OTP is from.

Recommended format:

Your [YourCompanyName] verification code is XXXX. It expires in X minutes. Do not share this code with anyone.

Note: Messages that do not contain your company name may confuse recipients and lead to lower OTP completion rates.

Request Body

{
  "api_key": "your_api_key_here",
  "recipients": "+2348012345678",
  "msg": "Your AcmeCorp verification code is 123456. It expires in 5 minutes. Do not share this code.",
  "request_id": "optional-unique-id-from-your-side"
}

Response (Success)

{
                  "status": "ok",
                  "description": "OTP submitted successfully",
                  "transaction_id": "txn_abc123",
                  "msg_id": "rmsg_1717420800000_abc123def",
                  "sender_id_used": "ReachNG"
                  }

Example cURL

curl -X POST https://reachng.com/api/functions/partnerSendSms \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "live_abc123xyz",
    "recipients": "+2348012345678",
    "msg": "Your OTP is 123456",
    "request_id": "req_12345"
  }'

Check Status (Polling)

Poll for delivery status using transaction_id or your request_id.

Endpoint

POST https://reachng.com/api/functions/checkTransactionStatus

Request Body

{
                "api_key": "your_api_key_here",
                "transaction_id": "txn_abc123"
                }

                OR

                {
                "api_key": "your_api_key_here",
                "request_id": "req_12345"
                }

                OR

                {
                "api_key": "your_api_key_here",
                "msg_id": "rmsg_1717420800000_abc123def"
                }

Response

{
                "transaction_id": "txn_abc123",
                "request_id": "req_12345",
                "msg_id": "rmsg_1717420800000_abc123def",
                "recipient": "+2348012345678",
                "status": "delivered",
                "cost": 5.9,
                "sent_at": "2026-06-02T10:30:00Z"
                }

Status Values

  • pending — Just created, not yet sent
  • submitted — Sent to provider, awaiting delivery
  • delivered — Successfully delivered
  • rejected — Provider rejected (invalid number, etc.)
  • undelivered — Could not reach recipient
  • expired — Message expired without delivery
  • failed — Failed to send

Delivery Status Reference

These are all possible statuses you will receive via webhook or polling, with their meanings.

StatusMeaning
deliveredThe SMS was delivered successfully to the recipient.
sentThe SMS has been submitted to the network and is awaiting delivery confirmation.
pendingThe SMS is queued and not yet submitted to the network.
expiredThe SMS could not be delivered — the operator was unable to reach the recipient after multiple attempts.
rejectedDelivery failed because the recipient is inactive, on DND, barred by the network, or has a full inbox.
undeliveredThe SMS could not be delivered. Common causes: inactive/invalid number, unregistered sender ID, or operator block.
failedThe message failed to send — typically due to a system or network error.

Example cURL

curl -X POST https://reachng.com/api/functions/checkTransactionStatus \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "live_abc123xyz",
    "transaction_id": "txn_abc123"
  }'

Webhooks (Optional)

Set your webhook URL in Settings for real-time push notifications instead of polling.

Webhook Payload

POST https://your-webhook-url.com/webhooks/sms

                {
                "transaction_id": "txn_abc123",
                "partner_request_id": "req_12345",
                "msg_id": "rmsg_1717420800000_abc123def",
                "recipient": "+2348012345678",
                "status": "delivered",
                "updated_at": "2026-06-02T10:35:00Z"
                }

Need help? Contact support@reachng.com