BliboSMS API (1.0.0)

Download OpenAPI specification:

Send SMS, check message status, manage sender IDs, and check your balance programmatically.

Introduction

The BliboSMS API is a JSON REST API. All requests go to the base URL below, must be made over HTTPS, and should send Accept: application/json (plus Content-Type: application/json on requests with a body).

https://sms.blibosolutions.com/api/v1

Authentication

Every endpoint requires an API key, sent as a bearer token:

Authorization: Bearer bsms_YOUR_API_KEY

Generate a key from Settings → API Keys in your BliboSMS dashboard. A missing, invalid, revoked or expired key returns 401 with the error code unauthorized.

Responses and errors

Successful responses wrap the result in a data object:

{ "data": { "sms_balance": 4200 } }

Failed requests return an error object with a machine-readable code, a human-readable message, and — for validation failures — per-field details:

{
  "error": {
    "code": "validation_error",
    "message": "The sender id field is required.",
    "details": { "sender_id": ["The sender id field is required."] }
  }
}
Status Meaning
200 / 201 Success
401 Missing or invalid API key
404 The message or OTP reference doesn't exist on your account
422 Validation failed, or the request can't be processed as sent
429 Rate limit, OTP cooldown or OTP daily limit reached

Rate limits

Requests are limited to 60 per minute per API key. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining headers; once the limit is exceeded you receive 429 with a Retry-After header giving the number of seconds to wait.

Idempotency

POST /messages, POST /otp/generate and POST /otp/resend accept an optional Idempotency-Key header. Replaying a request with the same key and the same body returns the original response instead of sending again, so it is safe to retry after a network failure. Reusing a key with a different body returns 422 with the code idempotency_key_reused.

Messages

Send SMS and check message status.

Send an SMS

Sends to one recipient, or many when recipient is an array (the same message is queued individually for each; duplicates are removed).

Pass scheduled_at to send later instead of immediately. Supports the Idempotency-Key header.

Authorizations:
apiKey
header Parameters
Idempotency-Key
string
Example: 7c1d1a52-0a55-4d2b-9f0e-3a4d7a2c9b10

A unique value (for example a UUID) identifying this request. Replaying the same key with the same body returns the original response instead of sending twice.

Request Body schema: application/json
required
sender_id
required
string <= 11 characters

Must be an approved sender ID on your account.

required
Single recipient (string) or Array of Multiple recipients (strings)

One phone number, or an array of phone numbers.

message
required
string <= 500 characters

The message body.

scheduled_at
string or null <date-time>

An ISO 8601 datetime in the future. Omit to send right away.

Responses

Response Schema: application/json
object

Request samples

Content type
application/json
Example
{
  • "sender_id": "BLIBO",
  • "recipient": "+233241234567",
  • "message": "Your order has shipped."
}

Response samples

Content type
application/json
Example
{
  • "data": {
    • "messages": [
      ]
    }
}

List sent messages

Paginated history of sent messages, newest first, 20 per page.

Messages that are still waiting to be sent (queued or scheduled) aren't included here — check those individually with GET /messages/{reference}.

Authorizations:
apiKey
query Parameters
status
string
Enum: "queued" "submitted" "processing" "delivered" "failed" "expired" "rejected"
Example: status=delivered

Only return messages with this status.

search
string
Example: search=233241234567

Filter by recipient, message text, or sender ID.

page
integer >= 1
Default: 1
Example: page=1

Page number.

Responses

Response Schema: application/json
Array of objects (MessageSummary)
object (Pagination)

Request samples

curl -G "https://sms.blibosolutions.com/api/v1/messages" \
  -H "Authorization: Bearer bsms_YOUR_API_KEY" \
  -H "Accept: application/json" \
  -d status=delivered \
  -d page=1

Response samples

Content type
application/json
{
  • "data": [
    • {
      }
    ],
  • "meta": {
    • "current_page": 1,
    • "per_page": 20,
    • "total": 1,
    • "last_page": 1
    }
}

Get message status

Looks up a message by the message_id returned when it was sent. The ID is stable across the message's whole lifecycle — while it is waiting to be sent, and once the network reports back.

Authorizations:
apiKey
path Parameters
reference
required
string <uuid>
Example: 9b2f6c1e-4d1a-4c57-9d0a-6f3f0c1e8a21

The message_id from the send response.

Responses

Response Schema: application/json
object (Message)

Request samples

curl "https://sms.blibosolutions.com/api/v1/messages/9b2f6c1e-4d1a-4c57-9d0a-6f3f0c1e8a21" \
  -H "Authorization: Bearer bsms_YOUR_API_KEY" \
  -H "Accept: application/json"

Response samples

Content type
application/json
Example
{
  • "data": {
    • "message_id": "9b2f6c1e-4d1a-4c57-9d0a-6f3f0c1e8a21",
    • "status": "delivered",
    • "sender_id": "BLIBO",
    • "recipient": "+233241234567",
    • "scheduled_at": null,
    • "cost": "0.0350",
    • "sent_at": "2026-07-19T10:00:00+00:00",
    • "delivered_at": "2026-07-19T10:00:05+00:00",
    • "error_message": null
    }
}

OTP

Generate and verify one-time passcodes. Codes are sent immediately (not queued) and are never returned in any API response — only a reference for status lookups. A code can only be verified against the phone number it was sent to.

Generate and send an OTP

Generates a code and texts it to the recipient straight away. Generating a new OTP for the same recipient and purpose replaces any that is still pending.

To protect recipients, a number can only be sent one OTP every 60 seconds and 5 OTPs per day. Supports the Idempotency-Key header.

Authorizations:
apiKey
header Parameters
Idempotency-Key
string
Example: 7c1d1a52-0a55-4d2b-9f0e-3a4d7a2c9b10

A unique value (for example a UUID) identifying this request. Replaying the same key with the same body returns the original response instead of sending twice.

Request Body schema: application/json
required
recipient
required
string

The phone number to send the code to.

sender_id
required
string <= 11 characters

Must be an approved sender ID on your account.

purpose
string <= 100 characters
Default: "default"

A tag that lets one number hold separate OTPs for different flows at the same time.

message
string <= 500 characters

Custom message template. Must contain the %otp_code% placeholder; :expiry_minutes is also replaced if present. Defaults to a standard message.

length
integer [ 4 .. 10 ]
Default: 6

Code length. Values outside 4–10 are clamped to the nearest bound.

type
string
Default: "numeric"
Enum: "numeric" "alphanumeric"
expiry_minutes
integer [ 1 .. 60 ]
Default: 10

How long the code is valid for.

max_attempts
integer [ 3 .. 10 ]
Default: 5

Verify attempts allowed before the code is locked.

Responses

Response Schema: application/json
object (OtpIssued)

Request samples

Content type
application/json
{
  • "recipient": "233241234567",
  • "sender_id": "BLIBO",
  • "purpose": "login"
}

Response samples

Content type
application/json
{
  • "data": {
    • "reference": "5a8e0f3c-7b1d-4f6a-8c2e-1d9b7a4e6f30",
    • "recipient": "233241234567",
    • "status": "pending",
    • "expires_at": "2026-07-19T21:30:00+00:00"
    }
}

Resend an OTP

Invalidates any still-pending OTP for the same recipient and purpose and issues a new one. Accepts the same body as Generate and send an OTP and is subject to the same cooldown and daily limit. Supports the Idempotency-Key header.

Authorizations:
apiKey
header Parameters
Idempotency-Key
string
Example: 7c1d1a52-0a55-4d2b-9f0e-3a4d7a2c9b10

A unique value (for example a UUID) identifying this request. Replaying the same key with the same body returns the original response instead of sending twice.

Request Body schema: application/json
required
recipient
required
string

The phone number to send the code to.

sender_id
required
string <= 11 characters

Must be an approved sender ID on your account.

purpose
string <= 100 characters
Default: "default"

Must match the purpose of the OTP being replaced.

Responses

Response Schema: application/json
object (OtpIssued)

Request samples

Content type
application/json
{
  • "recipient": "233241234567",
  • "sender_id": "BLIBO",
  • "purpose": "login"
}

Response samples

Content type
application/json
{
  • "data": {
    • "reference": "5a8e0f3c-7b1d-4f6a-8c2e-1d9b7a4e6f30",
    • "recipient": "233241234567",
    • "status": "pending",
    • "expires_at": "2026-07-19T21:30:00+00:00"
    }
}

Verify an OTP

Checks the code your user entered against the most recent OTP sent to that recipient for the given purpose. Each incorrect attempt counts towards the OTP's max_attempts.

Authorizations:
apiKey
Request Body schema: application/json
required
recipient
required
string

The phone number the code was sent to. A leading + is optional.

code
required
string

The code the end-user entered.

purpose
string or null <= 100 characters
Default: "default"

Must match the purpose used when generating.

Responses

Response Schema: application/json
object

Request samples

Content type
application/json
{
  • "recipient": "233241234567",
  • "code": "482913",
  • "purpose": "login"
}

Response samples

Content type
application/json
{
  • "data": {
    • "status": "verified",
    • "message": "OTP verified successfully."
    }
}

Get OTP status

Looks up an OTP by the reference returned when it was generated. The code itself is never returned.

Authorizations:
apiKey
path Parameters
reference
required
string <uuid>
Example: 5a8e0f3c-7b1d-4f6a-8c2e-1d9b7a4e6f30

The reference from the generate response.

Responses

Response Schema: application/json
object (Otp)

Request samples

curl "https://sms.blibosolutions.com/api/v1/otp/5a8e0f3c-7b1d-4f6a-8c2e-1d9b7a4e6f30" \
  -H "Authorization: Bearer bsms_YOUR_API_KEY" \
  -H "Accept: application/json"

Response samples

Content type
application/json
{
  • "data": {
    • "reference": "5a8e0f3c-7b1d-4f6a-8c2e-1d9b7a4e6f30",
    • "recipient": "233241234567",
    • "purpose": "default",
    • "status": "pending",
    • "attempts_used": 1,
    • "expires_at": "2026-07-19T21:30:00+00:00"
    }
}

Sender IDs

List and request Sender IDs. A message can only be sent once its sender ID has status approved.

List sender IDs

Every sender ID requested on your account, newest first.

Authorizations:
apiKey

Responses

Response Schema: application/json
Array of objects (SenderId)

Request samples

curl "https://sms.blibosolutions.com/api/v1/sender-ids" \
  -H "Authorization: Bearer bsms_YOUR_API_KEY" \
  -H "Accept: application/json"

Response samples

Content type
application/json
{
  • "data": [
    • {
      }
    ]
}

Request a new sender ID

Submits a sender ID for review. New sender IDs always start as pending and can be used to send once they are approved. The ID is stored in upper case.

Authorizations:
apiKey
Request Body schema: application/json
required
sender_id
required
string <= 11 characters ^[A-Za-z0-9]+$

Up to 11 letters and digits, no spaces.

purpose
required
string <= 500 characters

What this sender ID will be used for.

Responses

Response Schema: application/json
object

Request samples

Content type
application/json
{
  • "sender_id": "BLIBO",
  • "purpose": "OTP and account alerts"
}

Response samples

Content type
application/json
{
  • "data": {
    • "sender_id": "BLIBO",
    • "purpose": "OTP and account alerts",
    • "status": "pending"
    }
}

Balance

Check your remaining SMS credits.

Get SMS balance

Returns the SMS credits remaining on your account.

Authorizations:
apiKey

Responses

Response Schema: application/json
object (Balance)

Request samples

curl "https://sms.blibosolutions.com/api/v1/balance" \
  -H "Authorization: Bearer bsms_YOUR_API_KEY" \
  -H "Accept: application/json"

Response samples

Content type
application/json
{
  • "data": {
    • "sms_balance": 4200,
    • "low_credits": false,
    • "credits_expiry": null
    }
}

Webhooks

Get events pushed to your own systems instead of polling. Register a callback URL under Settings → WebHook Settings in your dashboard.

Each delivery is a POST with a JSON body, signed so you can verify it came from BliboSMS: the X-Blibo-Signature header is the hex-encoded HMAC-SHA256 of the raw request body, keyed with your webhook's secret. Compute the same value on your side and compare it before trusting the payload.

Respond with any 2xx status within 5 seconds. Failed deliveries are not retried, so treat webhooks as a notification and use GET /messages/{reference} as the source of truth.

Delivery report Webhook

Sent to your callback URL whenever the network reports a new status for a message. Subscribe a webhook to Delivery Report or All Events to receive it.

header Parameters
X-Blibo-Signature
required
string
Example: 3f1c0b6e9a4d2f7c8b5e1a0d9c3f6b2e7a4d1c8f5b2e9a6d3c0f7b4e1a8d5c2f

Hex-encoded HMAC-SHA256 of the raw request body, keyed with your webhook's secret.

Request Body schema: application/json
required
event
string
Value: "delivery_report"
object
timestamp
string <date-time>

When the event was sent.

Responses

Request samples

Content type
application/json
{
  • "event": "delivery_report",
  • "data": {
    • "message_id": "9b2f6c1e-4d1a-4c57-9d0a-6f3f0c1e8a21",
    • "status": "delivered",
    • "recipient": "+233241234567",
    • "sender_id": "BLIBO"
    },
  • "timestamp": "2026-07-19T10:00:05+00:00"
}