Skip to main content
N

Developer API

API Reference

Send SMS, verify phone numbers with OTP, deliver voice and WhatsApp messages, and manage your contacts — all from one REST API. Get your API key from the developer dashboard and start building.

SMS

1x rate per message

OTP

3x rate — premium

Voice

2x rate per recipient

WhatsApp

5x rate — premium

Authentication

All API requests require a Bearer token. Get your API key from the developer dashboard.

# All API requests require a Bearer token in the Authorization header.
curl https://notifymore.com/api/v1/account \
  -H "Authorization: Bearer sfgh_live_your_api_key"

Rate limit: 60 requests per minute per API key (configurable).

Key format: sfgh_live_… — keys are hashed at rest and shown only once at creation.

Billing: every send deducts from your wallet. Top up via Paystack or buy a plan from the dashboard.

SMS

Send single, bulk, and group-targeted SMS messages.

POST/api/v1/sms/send

Send SMS

Send a single SMS to one recipient. Bills 1 SMS unit from your wallet.

Request body

{
  "to": "0244123456",
  "from": "MYBRAND",
  "message": "Hello from Notifymore"
}

Response

{
  "success": true,
  "data": {
    "messageId": "507f1f77bcf86cd799439011",
    "to": "233244123456",
    "status": "SENT",
    "smsParts": 1,
    "costPesewas": 5,
    "costFormatted": "GHS 0.05",
    "walletBalance": 4500
  }
}
POST/api/v1/sms/bulk

Bulk SMS

Send up to 100 SMS messages in one request. Each message is billed independently.

Request body

{
  "messages": [
    { "to": "0244123456", "from": "MYBRAND", "message": "Hello A" },
    { "to": "0209876543", "from": "MYBRAND", "message": "Hello B" }
  ]
}
POST/api/v1/sms/send-groupFast

Send SMS to a contact group

Fan-out an SMS to an entire contact group in one upstream call. The group must exist in your dashboard (auto-mirrored to Arkesel). Billing is based on the local contact count.

Request body

{
  "group_name": "Loyal Customers",
  "sender": "MYBRAND",
  "message": "Hi everyone, new offers just dropped!"
}

OTP (Phone Verification)

Send and verify one-time passwords — a sellable verification service at 3x the SMS rate.

POST/api/v1/otp/send3x rate

Send OTP

Send a one-time password. The %otp_code% placeholder is required. Bills 3x the SMS rate (OTP premium).

Request body

{
  "number": "0244123456",
  "message": "Your verification code is %otp_code%. Expires in 5 minutes.",
  "sender_id": "MYBRAND",
  "expiry": 5,
  "length": 6,
  "medium": "sms",
  "type": "numeric"
}
POST/api/v1/otp/verify

Verify OTP

Verify an OTP code against a phone number. Returns 422 if the code is wrong or expired.

Request body

{
  "number": "0244123456",
  "code": "123456"
}

Response

{
  "success": true,
  "data": { "status": "verified", "number": "233244123456", "verified": true }
}
GET/api/v1/otp/balance

OTP balance

Returns available SMS credits. SMS OTP spends those credits. Voice OTP price is the cedi amount charged from the wallet.

Voice SMS

Send spoken messages via text-to-speech or audio upload. 2x the SMS rate per recipient.

POST/api/v1/voice/send2x rate

Send Voice SMS

Send a TTS (or audio upload) voice message to one or more recipients. Bills 2x the SMS rate per recipient.

Request body

{
  "recipients": ["0541234567", "0241234567"],
  "message": "Hello, this is a voice reminder.",
  "voiceId": "0540000000"
}

WhatsApp Business

Send pre-approved WhatsApp template messages. 5x the SMS rate — premium channel.

POST/api/v1/whatsapp/send5x rate

Send WhatsApp template message

Send a pre-approved WhatsApp template message. Bills 5x the SMS rate.

Request body

{
  "to": "0244123456",
  "template_id": "5203df1f-814c-4fc8-a912-5b0c2669be7c",
  "parameters": ["Ama", "PROMO-001"]
}
GET/api/v1/whatsapp/templates

List WhatsApp templates

Lists all approved WhatsApp templates available for sending.

Contacts

Full CRUD for managing your contact book.

GET/api/v1/contacts

List contacts

List your contacts with optional pagination, search, and group filter. Query: page, limit, search, groupId.

POST/api/v1/contacts

Create contact

Create a new contact. Returns 409 if a contact with the same phone already exists.

Request body

{
  "name": "Ama Mensah",
  "phone": "0244123456",
  "email": "ama@example.com",
  "groupId": "507f1f77bcf86cd799439011"
}
GET/api/v1/contacts/{id}

Get contact

Fetch a single contact by ID.

PATCH/api/v1/contacts/{id}

Update contact

Partially update a contact. Only include fields you want to change.

Request body

{ "name": "Ama K. Mensah", "groupId": "607f1f77bcf86cd799439022" }
DELETE/api/v1/contacts/{id}

Delete contact

Permanently delete a contact.

Contact Groups

Create and manage audience groups. Groups auto-mirror to Arkesel for fast group sends.

GET/api/v1/contact-groups

List contact groups

List all your contact groups, including Arkesel sync status.

POST/api/v1/contact-groups

Create contact group

Create a new group. Auto-mirrored to Arkesel so it can be targeted via /api/v1/sms/send-group immediately.

Request body

{ "name": "Loyal Customers", "description": "Repeat buyers" }
GET/api/v1/contact-groups/{id}

Get contact group

Fetch a single contact group by ID.

PATCH/api/v1/contact-groups/{id}

Update contact group

Partially update a contact group's name or description.

DELETE/api/v1/contact-groups/{id}

Delete contact group

Delete a group. Contacts in the group are ungrouped, not deleted.

POST/api/v1/contact-groups/{id}/contacts

Add contacts to group

Upsert contacts into a group by phone number. New contacts are created; existing contacts are moved. Max 1000 phones per request.

Request body

{ "phones": ["0244123456", "0541234567", "0551234567"] }

Account & Reports

Account info, SMS credits, sender IDs, and delivery reports.

GET/api/v1/account

Account info

Returns your account, available SMS credits, the cedi wallet used for voice and WhatsApp, and approved sender IDs.

Response

{
  "success": true,
  "data": {
    "account": { "name": "Ama Mensah", "email": "ama@example.com" },
    "balance": {
      "smsCredits": 1680,
      "smsCreditsFormatted": "1,680 SMS",
      "walletPesewas": 4500,
      "currency": "GHS"
    },
    "pricing": {
      "smsBilling": "credits",
      "otpSmsBilling": "credits",
      "otpVoicePricePesewas": 15,
      "whatsappUnitPricePesewas": 25
    },
    "senderIds": { "approved": ["MYBRAND"], "total": 1 }
  }
}
GET/api/v1/balance

SMS credits

Returns available SMS credits. balance is the credit count and currency is SMS.

GET/api/v1/sender-ids

List sender IDs

Lists your sender IDs (approved, pending, rejected). New requests require Ghana Card verification — submit via the dashboard.

GET/api/v1/reports

Delivery reports

List your SMS history with filters (status, source, date range, campaign, sender ID). Paginated.

POST/api/v1/validate

Validate phone

Validate a Ghana phone number before sending.

Request body

{ "phone": "0244123456" }

USSD (inbound)

Arkesel calls your USSD endpoint when a user dials a code. Register the URL in your Arkesel dashboard. Users can check their wallet balance from any feature phone. No API key needed (uses USSD_WEBHOOK_SECRET).

POST/api/ussd

USSD session (inbound)

Arkesel calls this endpoint when a user dials a USSD code. Register the URL in your Arkesel dashboard. Users can check their wallet balance from any feature phone.

Request body (from Arkesel)

{
  "sessionID": "abc123",
  "userID": "user1",
  "newSession": true,
  "msisdn": "233244123456",
  "userData": "*928*92#"
}

Error codes

Standard HTTP status codes returned by the API.

CodeMeaning
200Success — the request was completed.
201Created — a new resource was created.
400Bad Request — invalid input or validation error.
401Unauthorized — missing or invalid API key.
402Payment Required — not enough SMS credits or wallet balance for this channel.
404Not Found — the resource does not exist.
409Conflict — a duplicate resource already exists.
422Unprocessable — channel not configured or OTP wrong.
429Rate Limit Exceeded — too many requests. Slow down.
502Bad Gateway — the upstream SMS provider failed.