API reference · v1
API documentation
The FasterMessage REST API lets you send messages across every channel — SMS, WhatsApp, email and voice — manage OTP verification and receive each message's status in real time.
URL convention: each channel exposes a send endpoint /v1/<channel>/send (e.g. /v1/sms/send). All examples use the base https://api.fastermessage.com.
Introduction
All requests are made over HTTPS to the API base. Request and response bodies are in JSON format (Content-Type: application/json). The API follows REST conventions: standard HTTP verbs, explicit status codes and resources identified by an id.
Base URL
Authentication
Authenticate each request with your secret API key, sent in the Authorization header as a Bearer token. Keep the key server-side; never expose it in a web or mobile client.
Authorization: Bearer fm_live_xxxxxxxxxxxxxxxxxxxxxxxx
A request without a valid key returns 401 Unauthorized. You can generate, revoke and rotate your keys from the dashboard.
Environments
Two isolated environments, each with its own keys:
| Environment | Key prefix | Behavior |
|---|---|---|
| test | fm_test_… | Simulates sends, with no cost or real delivery. |
| production | fm_live_… | Real sends, billed, with carrier delivery. |
Quickstart
Send your first SMS in a single request. Replace $FM_API_KEY with your secret key.
curl https://api.fastermessage.com/v1/sms/send \ -H "Authorization: Bearer $FM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+221770000000", "from": "FasterMsg", "text": "Your code is 480912. Valid for 5 min." }'
Recommended headers
Authorization— your API key (required);Content-Type: application/json— for requests with a body;Idempotency-Key— unique key to replay a request without double-sending.
Timestamps are in ISO 8601 UTC format (2026-06-27T12:44:01Z). Every creation response returns an id and a status.
SMS — Send
Sends an SMS. The fallback field defines a cascade: if the SMS fails, the message is re-sent on the next channel.
Body parameters
| Field | Type | Description |
|---|---|---|
| torequired | string | Recipient in E.164 format (+221770000000). Accepts an array for bulk sending. |
| textrequired | string | Message content (160 characters / segment; 70 in UCS-2). |
| fromrequired | string | Declared sender identifier (Sender ID), approved on the account. No default sender is applied. |
| fallbackoptional | array | Fallback channels, e.g. ["whatsapp","voice"]. |
| referenceoptional | string | Free reference attached to the message. |
| callback_urloptional | string | Message-specific DLR webhook. |
curl https://api.fastermessage.com/v1/sms/send \ -H "Authorization: Bearer $FM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+221770000000", "from": "FasterMsg", "text": "Your code is 480912.", "fallback": ["whatsapp"] }'
{
"id": "msg_8a1c2e",
"channel": "sms",
"status": "queued",
"to": "+221770000000",
"segments": 1,
"created_at": "2026-06-27T12:44:01Z"
}
WhatsApp — Send
Sends a WhatsApp message. Outside the 24-hour window, use an approved template; within it, you can send session text.
| Field | Type | Description |
|---|---|---|
| torequired | string | WhatsApp number in E.164 format. |
| fromoptional | string | Sending WhatsApp Business number. |
| templateoptional | object | Approved template: name, language, variables. |
| textoptional | string | Session message (only within the 24-hour window). |
| mediaoptional | object | Attachment: type (image/document/video) and url. |
curl https://api.fastermessage.com/v1/whatsapp/send \ -H "Authorization: Bearer $FM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+221770000000", "template": { "name": "order_confirm", "language": "en", "variables": ["Awa", "#1042"] } }'
Voice — Send
Triggers an automated call. Provide an audio_url (hosted file) or a tts object (text-to-speech).
| Field | Type | Description |
|---|---|---|
| torequired | string | Number to call (E.164). |
| ttsoptional | object | Text-to-speech: text, language, voice. |
| audio_urloptional | string | URL of an audio file to play. |
| retriesoptional | integer | Number of attempts on no answer (default 1). |
| fallbackoptional | array | Fallback, e.g. ["sms"] if the call does not get through. |
curl https://api.fastermessage.com/v1/voice/send \ -H "Authorization: Bearer $FM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "+221770000000", "tts": { "text": "Your code is 4 8 0 9 1 2.", "language": "en" }, "fallback": ["sms"] }'
Email — Send
Sends a transactional or marketing email from a verified sending address (SPF/DKIM).
| Field | Type | Description |
|---|---|---|
| torequired | string | Recipient email address (or array). |
| fromrequired | string | Verified sending address. |
| subjectrequired | string | Email subject. |
| htmloptional | string | HTML content. At least html or text. |
| textoptional | string | Plain-text version. |
| attachmentsoptional | array | Attachments: filename and url (or base64). |
curl https://api.fastermessage.com/v1/email/send \ -H "Authorization: Bearer $FM_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": "[email protected]", "from": "[email protected]", "subject": "Your receipt #1042", "html": "<h1>Thank you!</h1>" }'
Message status
Returns the current state and status history of a message from its id.
{
"id": "msg_8a1c2e",
"channel": "sms",
"status": "delivered",
"to": "+221770000000",
"created_at": "2026-06-27T12:44:01Z",
"delivered_at": "2026-06-27T12:44:03Z"
}
List messages
Returns a paginated list of messages, sorted from newest to oldest. Pagination is cursor-based.
Query parameters
| Field | Type | Description |
|---|---|---|
| channel | string | Filter by channel. |
| status | string | Filter by status, e.g. failed. |
| limit | integer | Number of items (default 20, max 100). |
| starting_after | string | Cursor: id of the last item on the previous page. |
{
"object": "list",
"has_more": true,
"data": [
{ "id": "msg_8a1c2e", "status": "delivered" }
]
}
Account balance
Returns the available balance per channel (in units).
{
"sms": 7733,
"whatsapp": 0,
"email": 1250,
"currency": "XOF"
}
Send an OTP
Generates and sends a one-time code. FasterMessage handles generation, expiry and validation: you do not have to store the code.
| Field | Type | Description |
|---|---|---|
| torequired | string | Recipient number in E.164 format. |
| channeloptional | string | Channel: sms (default), whatsapp or voice. |
| lengthoptional | integer | Code length (default 6). |
| expiryoptional | integer | Validity in seconds (default 300). |
{
"id": "vrf_3f9a01",
"to": "+221770000000",
"channel": "sms",
"status": "pending",
"expires_at": "2026-06-27T12:49:01Z"
}
Verify an OTP
Validates the code entered by the user. The code is invalidated after a successful verification or after expiry.
{ "to": "+221770000000", "code": "480912" }
{
"id": "vrf_3f9a01",
"status": "approved"
}
An incorrect code returns status: "failed"; an expired code returns a 410 Gone error.
Webhooks & DLR
Configure a webhook URL in the dashboard (or per message via callback_url) to receive each status change in real time. FasterMessage sends a JSON POST request to your endpoint.
Example event
{
"id": "evt_55b7",
"event": "message.delivered",
"message_id": "msg_8a1c2e",
"status": "delivered",
"channel": "sms",
"delivered_at": "2026-06-27T12:44:03Z"
}
Security & best practices
- Verify the signature of each payload: the
X-Fastermessage-Signatureheader holdssha256=HMAC-SHA256(raw body, your signing secret). Generate the secret from your account, under “Integration & API”; - Respond
2xxquickly; process asynchronously; - Handle idempotency: the same event may be delivered several times.
Message statuses
| Status | Meaning |
|---|---|
| queued | Accepted and queued for sending. |
| sent | Handed off to the carrier / provider. |
| delivered | Delivered to the recipient (positive DLR). |
| read | Read by the recipient (WhatsApp / email). |
| failed | Failed; see the reason in error. |
| expired | Not delivered within the allotted window. |
Errors
The API uses standard HTTP status codes. The error body specifies a machine code and a human-readable message.
| HTTP code | Meaning |
|---|---|
| 400 | Invalid request (missing or malformed parameter). |
| 401 | Missing or invalid API key. |
| 402 | Insufficient balance. |
| 404 | Resource not found. |
| 409 | Conflict (e.g. idempotency key already used). |
| 429 | Too many requests (rate limit reached). |
| 500 | Internal error; retry with a backoff. |
{
"error": {
"code": "invalid_recipient",
"message": "The 'to' field must be in E.164 format."
}
}
Rate limits
Requests are limited per API key. On exceeding the limit, the API returns 429 with a Retry-After header indicating the delay before retrying.
X-RateLimit-Limit— quota for the current window;X-RateLimit-Remaining— remaining requests;Retry-After— seconds to wait after a429.
Exact thresholds depend on your plan — values to be specified.
SDKs
Libraries wrap authentication, requests and webhook signature verification. The source code of each SDK is provided in the repository, in the sdks/<language> folder.
| Language | Installation | Folder |
|---|---|---|
| Node.js | npm i fastermessage | sdks/node |
| PHP | composer require fastermessage/sdk | sdks/php |
| Python | pip install fastermessage | sdks/python |
| Java | Maven / Gradle | sdks/java |
import { FasterMessage } from "fastermessage"; const fm = new FasterMessage(process.env.FM_API_KEY); await fm.sms.send({ to: "+221770000000", from: "FasterMsg", text: "Your code is 480912" });
use FasterMessage\Client; $fm = new Client(getenv("FM_API_KEY")); $fm->sms->send(["to" => "+221770000000", "from" => "FasterMsg", "text" => "Your code is 480912"]);
from fastermessage import FasterMessage fm = FasterMessage(os.environ["FM_API_KEY"]) fm.sms.send(to="+221770000000", sender="FasterMsg", text="Your code is 480912")
CMS plugins
Ready-made extensions connect your store or website to FasterMessage (order notifications, OTP at checkout, campaigns). The code for each plugin is provided in plugins/<cms>.
| Platform | Use | Folder |
|---|---|---|
| WordPress | Login OTP, admin notifications, forms. | plugins/wordpress |
| WooCommerce | SMS/WhatsApp on every order status change. | plugins/woocommerce |
| PrestaShop | Order and delivery notifications. | plugins/prestashop |
| Shopify | Notification app via order webhooks. | plugins/shopify |