You are viewing public documentation. The code samples below show placeholder credentials. Log in or register to see your real API key pre-filled in every example.

API Documentation

Complete guide to integrating SMESS WhatsApp API into your application

Queue-Based Delivery Auto-Retry Logic Real-time Processing
API Key SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Create and reveal keys from your client portal.

Quick Start Guide

1
Connect Your WhatsApp

Messages are sent from your own WhatsApp number. Link it once by scanning a QR code on the Connections page (WhatsApp → Linked Devices). Until a number is connected, sends can't deliver.

2
Get Your API Key

Register or log in, then create a key at API Keys.

SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3
Make Your First Request

Send messages via POST to /api/send using apikey, recipient and text — or try it without writing code in the API Tester, the fastest way to a first successful send.

4
Track & Handle Responses

The API returns HTTP 202 with a queue_id; errors carry an error_code. Watch delivery in Messages / Queue, or get push notifications via Delivery Webhooks.

Authentication

All API requests require your API key. You can authenticate in three ways (in priority order):

Method How Notes
POST field apikey=SM-... Recommended for server-to-server integrations.
Header X-API-Key: SM-... Preferred for cleaner logs.
Bearer Authorization: Bearer SM-... Standard OAuth-style header.
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Hello World!"

JSON request bodies are supported. Send Content-Type: application/json with the same parameter names — form-encoded and JSON behave identically:

curl -X POST https://smess.io/api/send \
  -H "Content-Type: application/json" \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d '{"recipient": "+233244123456", "text": "Hello World!"}'
Security Tip: Keep your API key secure and never expose it in client-side code. Always make API calls from a server. If a key is leaked, revoke it immediately from API Keys.

Sender Identity & Fallback

Messages are delivered from your own WhatsApp number — recipients see your number, your business name, and your profile photo. You link the number once by scanning a QR code on the Connections page; it stays linked as a companion device.

TierChannelSender the recipient sees
Primary Your linked WhatsApp session Your number, name & photo
Fallback Email alert to you If your session drops, nothing is sent from any other number — you're alerted immediately so you can re-link (takes seconds). One number, one channel, maximum account safety.
Interactive messages adapt automatically. Buttons, copy-code, and list messages are delivered as clear numbered text ("Reply with a number to choose", codes highlighted for easy copying) — so they work for every recipient on every device through your single direct connection. Keep your phone online — a linked device whose phone disappears for extended periods is eventually unlinked by WhatsApp.
Using a brand-new number? Warm it up first

WhatsApp aggressively flags newly registered numbers that immediately start sending automated traffic — that can get a number restricted or banned regardless of which API or tool you use. Before going live:

1–2 weeks of normal use Use the number in the WhatsApp app like a human first: real two-way conversations, a group or two, complete business profile (name, photo, category, description).
Ramp volumes gradually Start low, prioritise recipients who have saved your number or messaged you first, and grow over weeks — never launch a fresh number straight into a campaign.
Automatic protection SMESS paces every newly connected number with a warm-up ramp during its first week (shorter sending intervals unlock as the number matures). Slower early delivery is deliberate protection, not a malfunction.
Meta Verified Recommended: subscribe to Meta Verified in the WhatsApp Business app (Settings → Meta Verified, ∼US$11/month). You get the verified badge — stronger recipient trust — plus access to Meta support channels if your number is ever flagged.

Send Message

POST https://smess.io/api/send

Messages are submitted to a queue and delivered by the background worker. The API returns HTTP 202 Accepted on success, not 200.

Core Parameters
Name Type Required Description
apikey string Yes Your API authentication key. Also accepted as X-API-Key or Authorization: Bearer header. Not api_key.
recipient string Yes Phone number with country code (e.g., +233244123456). Not phone.
text string Yes* Message text or media caption. Not message. *At least one content field is required.
priority string/int No otp / urgent / high / normal (default) / bulk / low
idempotency_key string No Unique key per send attempt. Replaying the same key within 5 minutes returns the original response without sending a duplicate. Recommended for OTPs.
Message Type Auto-Detection

The endpoint detects the message type from the parameters you provide. Include only the parameters for the type you want to send:

TypeRequired parameter(s)
Texttext
Imagefile (image URL)
Documentdocument (file URL) + optional filename
Videovideo
Audioaudio
Locationlatitude + longitude + optional label
Contact cardcontact_name + contact_phone
Buttonsbutton1 + button1id (up to 3)
Copy code (OTP)copycode + optional copytext
List menulist_title + list_button + list_sections (JSON)
Example Request
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Hello from SMESS!"
Success Response (HTTP 202)
Success Response
{
    "success": true,
    "message": "Message queued successfully. It will be sent by the queue worker.",
    "data": {
        "queue_id": 42,
        "recipient": "+233244123456",
        "message_type": "text",
        "priority": 5,
        "priority_label": "normal",
        "status": "queued",
        "timestamp": "2026-06-16 10:30:00",
        "remaining_quota": 999,
        "note": "Message will be sent by queue worker with rate limiting and spam prevention"
    }
}

Message Types

All message types use the same POST /api/send endpoint. The type is auto-detected from the parameters you send.

Document
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "document=https://example.com/invoice.pdf" \
  -d "filename=Invoice-2026.pdf" \
  -d "text=Here is your invoice."
Image
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "file=https://example.com/photo.jpg" \
  -d "text=Check this out!"
Buttons (up to 3)
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Confirm your delivery?" \
  -d "button1=Yes" \
  -d "button1id=confirm" \
  -d "button2=No" \
  -d "button2id=cancel"
Copy Code (OTP)
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Your verification code is:" \
  -d "copycode=482916" \
  -d "copytext=Tap to Copy" \
  -d "priority=otp" \
  -d "idempotency_key=otp-user-123-1785287393"
Location
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "latitude=5.6037" \
  -d "longitude=-0.1870" \
  -d "label=Accra Mall"
List Menu
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Please select a department:" \
  -d "list_title=Contact Us" \
  -d "list_button=View Departments" \
  -d 'list_sections=[{"title":"Sales","rows":[{"title":"New Orders","description":"Place a new order","rowId":"sales_new"}]}]'

Bulk Sending

For campaigns, submit many messages in one call with POST /api/bulk Growth & Enterprise plans. The queue worker paces delivery automatically (smart-sending gaps and caps still apply per recipient).

curl -X POST https://smess.io/api/bulk \
  -d "apikey=SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d 'messages=[
        {"recipient": "+233244123456", "text": "Hello Ama!"},
        {"recipient": "+233209876543", "text": "Hello Kojo!", "document": "https://example.com/invoice.pdf"}
      ]'
ParameterTypeDescription
messages JSON array Array of {recipient, text, document} objects. Alternative: upload a CSV file as csv_file with header recipient, text, document.
campaign_id optional Your identifier for the batch — returned in the response and attached to every queued message. Auto-generated if omitted.
scheduled_at optional YYYY-MM-DD HH:MM:SS — queue now, deliver later. Great for campaigns timed to business hours.
priority optional Defaults to bulk priority (paced slower than transactional sends so they never block OTPs or receipts).

Response:

{
  "success": true,
  "queued": 2,
  "total_submitted": 2,
  "campaign_id": "spring-promo-01",
  "message": "2 messages queued for delivery"
}
Per-message failures don't abort the batch — invalid rows are reported in an errors array while the rest queue normally. Delivery outcomes arrive per message via Delivery Webhooks or the Queue page.

Track Messages

After queuing, track message status in the client portal or via the message detail API:

ResourceURLPurpose
Queue /my-queue Pending / processing / sent / failed messages
Message History /my-messages Delivered messages and delivery receipts
Note: Save the queue_id returned in the 202 response and use it to correlate with status updates in your dashboard or webhooks.

Delivery-Status Webhooks

Prefer push over polling? Register a delivery-status webhook on your account (contact support to enable it) and SMESS will POST a JSON event to your HTTPS endpoint whenever one of your messages reaches a final state:

{
  "event":     "message.status",
  "queue_id":  12345,
  "status":    "sent",
  "recipient": "233244123456",
  "error":     null,
  "attempts":  1,
  "timestamp": "2026-07-24T15:04:05+00:00"
}
DetailBehaviour
status sent or failed — on failure, error carries the reason (delivery error, spam-rule block, recipient cap, …)
Signature With a signing secret configured, every request carries X-SMESS-Signature: sha256=<hex> — the HMAC-SHA256 of the raw body. Verify it before trusting the payload.
Delivery 5-second timeout, one automatic retry, best-effort — a webhook outage never delays your messages. Respond with any 2xx quickly; process async.
Held messages Gap/cap delays don't fire events — only final sent / failed outcomes do. Correlate using the queue_id from your send response.

Error Handling

The API returns JSON error responses with an HTTP status code and an error_code when available:

400 Bad Request — missing or invalid parameters (e.g., wrong phone format)
401 Unauthorized — API key missing or invalid (INVALID_KEY)
402 Payment Required — quota exceeded (QUOTA_EXCEEDED) or subscription/trial expired
403 Forbidden — key inactive/revoked (KEY_INACTIVE) or account suspended
413 Payload Too Large — media file exceeds your plan limit
429 Too Many Requests — per-minute rate limit or per-recipient cooldown (OTP_COOLDOWN)
503 Service Unavailable — WhatsApp connection not ready (WHATSAPP_DISCONNECTED / NOT_ACTIVATED)
Error Response Example
{
    "success": false,
    "error": "Invalid API key",
    "error_code": "INVALID_KEY",
    "code": 401
}

Rate Limits & Safeguards

Limits are per API key and depend on your plan:

LimitStarterGrowthEnterprise
API submissions / minute 60 300 1000
Document/media max size 25 MB 50 MB 100 MB
Per-recipient minimum gap 60 seconds (configurable 0–600s per key)
Per-recipient daily cap 50 / day (default — raisable per API key on request, e.g. for event-day alert streams)
Bulk sending: For campaigns, use priority=bulk and submit via POST /api/bulk (Growth+). The queue worker spaces out delivery automatically.

Troubleshooting

Common mistakes that cause API errors:

HTTP 401 — "API key is required" / "Invalid API key"

The server did not receive a valid key. Common causes:

❌ Wrong (will fail)✅ Correct
api_key (with underscore)apikey
key or tokenapikey / X-API-Key / Authorization: Bearer
JSON body (Content-Type: application/json)application/x-www-form-urlencoded or multipart
Query string ?apikey=...POST field or header (query string is deprecated and logged)
HTTP 400 — Missing Parameters
❌ Wrong (will fail)✅ Correct
phone, number, torecipient
message, msg, bodytext
image, photofile (images) or document (any file)
✅ Correct Example
curl -X POST https://smess.io/api/send \
  -H "X-API-Key: SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -d "recipient=+233244123456" \
  -d "text=Hello, this works!"
❌ Incorrect Example (will return 401)
# WRONG - these parameter names are NOT accepted
curl -X POST https://smess.io/api/send \
  -H "Content-Type: application/json" \
  -d '{"api_key":"SM-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","phone":"+233244123456","message":"This will fail"}'