Developers

API reference

Send SMS from your own apps using the FlyMySMS API.

API key

Authenticates every request to the API below.

Sign in to generate your API key.

Send an SMS

One request, one message, sent immediately.

Endpoint

POST https://flymysms.com/api/v1/messages

Authentication

Every request needs your API key as a Bearer token. Generate one above - it's shown once, so store it somewhere safe (an environment variable, a secrets manager) rather than in code.

Authorization: Bearer YOUR_API_KEY

Request body

JSON, with two fields:

FieldTypeDescription
tostringRecipient phone number. E.164 (+2348012345678) or local format - local numbers are interpreted using your account's default country.
messagestringMessage text, up to 2000 characters.

Example request

curl -X POST https://flymysms.com/api/v1/messages \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+2348012345678",
    "message": "Your OTP is 482913"
  }'

Response

200 once the message has actually been sent and its outcome is known - this call waits for that, it doesn't just queue the message and return early. A rejected send (e.g. an invalid or unreachable number) returns 422 with the same shape, so check status rather than only the HTTP code.

{
  "id": "cmXXXXXXXXXXXXXXXXXXXXXXX",
  "status": "SENT",
  "to": "+2348012345678",
  "segments": 1,
  "cost": { "amount": 4.5, "currencyCode": "NGN" }
}

On failure, an error object instead:

{
  "error": {
    "code": "insufficient_balance",
    "message": "Wallet balance is insufficient to send this message."
  }
}

Error codes

HTTPcodeMeaning
401missing_api_key / invalid_api_keyNo Bearer token, or the key isn't valid/was rotated.
400invalid_request / invalid_phone_numberMalformed request body, or the phone number couldn't be parsed.
402insufficient_balanceTop up your wallet.
403email_not_verifiedVerify your account email before sending.
403otp_device_requiredThis account has no active OTP device. Pair one on the Devices page.
429rate_limitedMore than 60 requests in a minute - back off and retry.
500internal_errorSomething went wrong on our side - safe to retry.

Billing

Messages sent through your own paired OTP device are free - included in your device subscription. If your device doesn't pick up a message in time and our platform's own backup device sends it on your behalf instead, that one send is billed from your wallet at your account's current per-segment rate. If a send fails outright, nothing is charged.

Sending OTPs

This endpoint requires an active OTP-mode device on your account - subscribe to one on the Devices page first. Once paired, every message sent through this endpoint is offered to your own always-on phone, no extra parameter needed. Without an OTP device, requests to this endpoint are rejected.

Recipient opt-out

If you use this endpoint to run bulk/campaign-style sends (not just OTPs), we automatically append To opt out: www.flymysms.com/u/... to the message whenever there's room to do so without increasing the SMS segment count - and to a recipient's very first message from your account regardless, even if that costs one extra segment, so every recipient gets a working way to stop receiving your messages. This never affects the message text you send - it's a suffix added after your own content, and only ever removed by the recipient themselves clicking the link. Opting out only stops future campaign-style sends - OTPs and other one-off transactional messages to that number keep working normally.