Products
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.
All requests require an API key in the request body. You have two API keys:
Generate keys in your dashboard Settings → API Keys.
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).
POST https://reachng.com/api/functions/partnerGetBalance
GET alternative: https://reachng.com/api/functions/partnerGetBalance?api_key=your_api_key_here
{
"api_key": "your_api_key_here"
}{
"status": "ok",
"partner_id": "prt_abc123",
"company_name": "AcmeCorp",
"mode": "live",
"wallet_balance": 482.30,
"currency": "NGN",
"retrieved_at": "2026-07-14T10:00:00Z"
}curl -X POST https://reachng.com/api/functions/partnerGetBalance \
-H "Content-Type: application/json" \
-d '{
"api_key": "live_abc123xyz"
}'Send individual OTP or transactional messages to a single recipient.
POST https://reachng.com/api/functions/partnerSendSms
⚠️ 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.
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."
Your sender ID is configured by ReachNG support and determines how messages appear on recipients' phones. Available sender IDs:
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.
📌 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.
{
"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"
}{
"status": "ok",
"description": "OTP submitted successfully",
"transaction_id": "txn_abc123",
"msg_id": "rmsg_1717420800000_abc123def",
"sender_id_used": "ReachNG"
}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"
}'Poll for delivery status using transaction_id or your request_id.
POST https://reachng.com/api/functions/checkTransactionStatus
{
"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"
}{
"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"
}These are all possible statuses you will receive via webhook or polling, with their meanings.
| Status | Meaning |
|---|---|
| delivered | The SMS was delivered successfully to the recipient. |
| sent | The SMS has been submitted to the network and is awaiting delivery confirmation. |
| pending | The SMS is queued and not yet submitted to the network. |
| expired | The SMS could not be delivered — the operator was unable to reach the recipient after multiple attempts. |
| rejected | Delivery failed because the recipient is inactive, on DND, barred by the network, or has a full inbox. |
| undelivered | The SMS could not be delivered. Common causes: inactive/invalid number, unregistered sender ID, or operator block. |
| failed | The message failed to send — typically due to a system or network error. |
curl -X POST https://reachng.com/api/functions/checkTransactionStatus \
-H "Content-Type: application/json" \
-d '{
"api_key": "live_abc123xyz",
"transaction_id": "txn_abc123"
}'Set your webhook URL in Settings for real-time push notifications instead of polling.
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