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

https://api.fastermessage.com/v1

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.

Authentication header
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:

EnvironmentKey prefixBehavior
testfm_test_…Simulates sends, with no cost or real delivery.
productionfm_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
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.

post/v1/sms/send

Body parameters

FieldTypeDescription
torequiredstringRecipient in E.164 format (+221770000000). Accepts an array for bulk sending.
textrequiredstringMessage content (160 characters / segment; 70 in UCS-2).
fromrequiredstringDeclared sender identifier (Sender ID), approved on the account. No default sender is applied.
fallbackoptionalarrayFallback channels, e.g. ["whatsapp","voice"].
referenceoptionalstringFree reference attached to the message.
callback_urloptionalstringMessage-specific DLR webhook.
cURL
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"]
  }'
201 Created
{
  "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.

post/v1/whatsapp/send
FieldTypeDescription
torequiredstringWhatsApp number in E.164 format.
fromoptionalstringSending WhatsApp Business number.
templateoptionalobjectApproved template: name, language, variables.
textoptionalstringSession message (only within the 24-hour window).
mediaoptionalobjectAttachment: type (image/document/video) and url.
cURL
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).

post/v1/voice/send
FieldTypeDescription
torequiredstringNumber to call (E.164).
ttsoptionalobjectText-to-speech: text, language, voice.
audio_urloptionalstringURL of an audio file to play.
retriesoptionalintegerNumber of attempts on no answer (default 1).
fallbackoptionalarrayFallback, e.g. ["sms"] if the call does not get through.
cURL
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).

post/v1/email/send
FieldTypeDescription
torequiredstringRecipient email address (or array).
fromrequiredstringVerified sending address.
subjectrequiredstringEmail subject.
htmloptionalstringHTML content. At least html or text.
textoptionalstringPlain-text version.
attachmentsoptionalarrayAttachments: filename and url (or base64).
cURL
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.

get/v1/messages/{id}
200 OK
{
  "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.

get/v1/messages

Query parameters

FieldTypeDescription
channelstringFilter by channel.
statusstringFilter by status, e.g. failed.
limitintegerNumber of items (default 20, max 100).
starting_afterstringCursor: id of the last item on the previous page.
200 OK
{
  "object": "list",
  "has_more": true,
  "data": [
    { "id": "msg_8a1c2e", "status": "delivered" }
  ]
}

Account balance

Returns the available balance per channel (in units).

get/v1/balance
200 OK
{
  "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.

post/v1/otp/send
FieldTypeDescription
torequiredstringRecipient number in E.164 format.
channeloptionalstringChannel: sms (default), whatsapp or voice.
lengthoptionalintegerCode length (default 6).
expiryoptionalintegerValidity in seconds (default 300).
201 Created
{
  "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.

post/v1/otp/verify
Request
{ "to": "+221770000000", "code": "480912" }
200 OK
{
  "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

POST · your endpoint
{
  "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-Signature header holds sha256=HMAC-SHA256(raw body, your signing secret). Generate the secret from your account, under “Integration & API”;
  • Respond 2xx quickly; process asynchronously;
  • Handle idempotency: the same event may be delivered several times.

Message statuses

StatusMeaning
queuedAccepted and queued for sending.
sentHanded off to the carrier / provider.
deliveredDelivered to the recipient (positive DLR).
readRead by the recipient (WhatsApp / email).
failedFailed; see the reason in error.
expiredNot 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 codeMeaning
400Invalid request (missing or malformed parameter).
401Missing or invalid API key.
402Insufficient balance.
404Resource not found.
409Conflict (e.g. idempotency key already used).
429Too many requests (rate limit reached).
500Internal error; retry with a backoff.
400 Bad Request
{
  "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 a 429.

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.

LanguageInstallationFolder
Node.jsnpm i fastermessagesdks/node
PHPcomposer require fastermessage/sdksdks/php
Pythonpip install fastermessagesdks/python
JavaMaven / Gradlesdks/java
Node.js
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" });
PHP
use FasterMessage\Client;
$fm = new Client(getenv("FM_API_KEY"));
$fm->sms->send(["to" => "+221770000000", "from" => "FasterMsg", "text" => "Your code is 480912"]);
Python
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>.

PlatformUseFolder
WordPressLogin OTP, admin notifications, forms.plugins/wordpress
WooCommerceSMS/WhatsApp on every order status change.plugins/woocommerce
PrestaShopOrder and delivery notifications.plugins/prestashop
ShopifyNotification app via order webhooks.plugins/shopify
Need an API key? Get test access and start sending in minutes.
Get access