W3 SMS API Documentation

Integrate W3 SMS into your application with a few HTTP requests - send single and bulk SMS, check your balance and receive delivery reports.

  • Simple IntegrationPlain HTTP, GET or POST
  • Secure CredentialsClient ID and Secret
  • Delivery ReportsPushed to your server
  • Safe RetriesIdempotency keys
Home API Documentation Getting Started

1. Getting Started

Welcome to the W3 SMS API Documentation

W3 SMS gives you a simple HTTP API to send SMS from your own software. This guide takes you from your credentials to your first message, then covers bulk sending, balance checks and delivery reports.

Fast IntegrationOne endpoint to send
Secure APIClient ID and Secret
Delivery ReportsReal-time DLR push
Developer FriendlyExamples in 5 languages

2. API Endpoints

Send your requests to these URLs:

GETPOST https://w3sms.com/send-message

Send SMS - use GET with query parameters, or POST with a form-urlencoded or JSON body. Both behave identically.

GET https://w3sms.com/check-balance

Check balance.

Use HTTPS in production, and keep your credentials out of URLs that get logged - prefer POST for server-to-server calls.

3. Authentication

Pass your Client ID and Client Secret with every request. You can find them in your W3 SMS account, under Manage API Key.

clientIdYOUR_CLIENT_ID
clientSecretYOUR_CLIENT_SECRET
Keep your API credentials secure. Do not share them with anyone, and never put them in code that runs in a browser or a mobile app.

4. Send SMS

Use the following endpoint to send a single SMS, or several in one call.

Request Parameters

ParameterTypeDescription
clientIdrequiredstringYour unique client ID.
clientSecretrequiredstringYour client secret.
senderIdrequiredstringAn approved sender ID assigned to your account.
numbersrequiredstringRecipient number(s). For bulk SMS, separate numbers with commas. Example: 8801711578523,8801912345678
contentsrequiredstringMessage body. ASCII up to 160 chars per SMS, Unicode (e.g. Bangla) up to 70 chars per SMS. URL-encode it.
idempotency_keyoptionalstringYour own reference for this send, e.g. an order number. Repeat a call with the same key and the original answer is returned instead of the message going out twice - the safe way to retry after a timeout. May also be sent as the Idempotency-Key header. Remembered for 24 hours.
asyncoptional0 / 1Send 1 to queue the batch instead of waiting for the gateway. The balance is checked and charged straight away, and the call returns 202 with a reference. Recommended for large batches.
Rate limit: 60 requests per minute
SMS sent through the API are delivered immediately. Scheduling is not supported through the API - use the Quick SMS panel in the dashboard for scheduled delivery.

Example

Placeholder credentials are shown - sign in to your account for your own. Replace the number and text and it runs as it stands.

curl -G "https://w3sms.com/send-message" \
  --data-urlencode "clientId=YOUR_CLIENT_ID" \
  --data-urlencode "clientSecret=YOUR_CLIENT_SECRET" \
  --data-urlencode "senderId=YOUR_SENDER_ID" \
  --data-urlencode "numbers=8801711578523" \
  --data-urlencode "contents=Hello from W3SMS"

Success Response

{
  "status": 200,
  "message": "Message submitted successfully. Delivery status will update via DLR."
}

"Submitted" means the gateway accepted it. Whether each number actually received it arrives later as a delivery report - see Delivery Reports below.

Success Response - queued (async=1)

{
  "status": 202,
  "reference": "batch_20260911105732_RXfjnh",
  "accepted": 250,
  "charged": 200.0,
  "message": "Batch accepted. Delivery status will update via DLR."
}
One call carries at most 1,000 recipients. A larger list is rejected with 422 rather than partly sent - split it into batches.

5. Bulk SMS

Send the same message to many recipients in one call - just provide a comma-separated list of numbers.

Example - Bulk SMS

https://w3sms.com/send-message?clientId=YOUR_CLIENT_ID&clientSecret=YOUR_CLIENT_SECRET&senderId=YOUR_SENDER_ID&numbers=8801XXXXXXXXX%2C8801YYYYYYYYY&contents=Hello+from+W3SMS
Charge is calculated as numbers x SMS parts x rate. Long ASCII messages (over 160 chars) and long Unicode messages (over 70 chars) count as multiple SMS parts.

Sending a large batch

  • Keep each call to 1,000 recipients or fewer; a longer list is refused with 422 rather than partly sent.
  • Add async=1 so the call returns as soon as the batch is charged and queued, instead of waiting for the gateway. A big batch can otherwise outlast your HTTP timeout, leaving you unsure whether it went.
  • Add an idempotency_key so that if the connection drops and you retry, the batch is not sent - and charged - a second time.
  • The batch is all or nothing: if your balance will not cover every recipient, none are sent.

6. Check Balance

GET https://w3sms.com/check-balance

Required parameters: clientId, clientSecret.

Rate limit: 30 requests per minute

Example

https://w3sms.com/check-balance?clientId=YOUR_CLIENT_ID&clientSecret=YOUR_CLIENT_SECRET

Success Response

{
  "status": 200,
  "balance": 500.00
}

7. Delivery Reports (DLR Push)

Instead of polling for status, we push a real-time webhook to your server whenever an SMS is delivered or fails. Set your Success and Fail URLs under DLR Push Config in your account.

How it works

  • SMS delivered - we send a request to your Success URL
  • SMS failed - we send a request to your Fail URL
  • Method (GET / POST) is configurable in the DLR settings.

Webhook Payload

FieldDescription
message_idUnique message id returned when the SMS was sent.
numberRecipient phone number.
statusdelivered or failed
raw_statusRaw status string from the upstream gateway.
sent_atWhen the SMS was submitted (ISO 8601).
reported_atWhen the delivery report was received (ISO 8601).

Example payload (POST JSON)

{
  "message_id": "296334",
  "number": "8801XXXXXXXXX",
  "status": "delivered",
  "raw_status": "success",
  "sent_at": "2026-05-31T18:05:45+06:00",
  "reported_at": "2026-05-31T18:12:10+06:00"
}
Your webhook URL must be publicly reachable (not localhost). Respond with HTTP 200 to acknowledge receipt.

8. Status Codes

HTTP / StatusMeaningWhen it happens
200AcceptedThe gateway took the message and your balance was charged. Delivery itself is reported later by DLR.
202QueuedOnly with async=1. Charged and queued; the response carries a reference.
404User not foundInvalid clientId or clientSecret.
404Sender ID not foundThe senderId is not assigned to your account.
406Insufficient balanceYour account balance is less than the calculated charge.
406Gateway unavailableNo active SMS gateway is configured. Contact support.
406Invalid phone numberThe gateway rejected the destination number.
406Sender does not match your packageA masking package cannot send through a non-masking sender ID, or the other way round. The message names which.
409Duplicate in flightAn earlier call with the same idempotency_key is still running. Wait for it rather than retrying.
422Validation errorA required parameter is missing or malformed, or the list held more than 1,000 recipients.
502Gateway refusedEvery gateway turned the batch down. Nothing was sent and the charge was returned to your balance.
503No gateway availableNo SMS gateway is active. Contact support.
How charging works. The whole batch is priced before anything is sent - if your balance will not cover all of it, nothing goes and you get 406. If a gateway then refuses the batch the charge is put straight back; if a delivery report later says a message never arrived, that message is refunded; and if no delivery report arrives within 48 hours, it is settled as undelivered and refunded then. Every movement appears in your transaction history.

9. WordPress Plugin

Sending from a WordPress site? Skip the code above - install the official plugin instead: a Settings screen for the same credentials, a one-function API (w3sms_send_sms()), and optional automatic SMS on WooCommerce order updates and Contact Form 7 submissions.

Installation

  • wp-admin - Plugins - Add New - Upload Plugin, choose the downloaded zip, then Install and Activate.
  • Open Settings - W3 SMS and enter your Client ID, Client Secret and Default Sender ID.
  • Use the Send Test SMS tool on the same screen to confirm it works.

Function reference

FunctionReturnsNotes
w3sms_send_sms( $numbers, $message, $sender = null )true | WP_Error$numbers accepts one MSISDN or several comma-separated. $sender overrides the saved default.
w3sms_check_balance()float | WP_ErrorThe account balance, in the currency the API reports it in.
A failed WooCommerce or Contact Form 7 notification never blocks checkout or the form submission - it is written to the PHP error log only. Full reference: DOCUMENTATION.md in the zip.

10. WHMCS Module

Running a hosting or billing business on WHMCS? This addon texts your clients automatically - new invoice, payment received, a staff reply on their ticket, or a service suspension - each one an independent on/off switch in the module's settings.

Installation

  • Extract the zip so the path is modules/addons/w3sms/w3sms.php on your WHMCS install.
  • Admin area - Setup - Addon Modules - find W3 SMS - Activate.
  • Click Configure: enter your Client ID, Client Secret and Default Sender ID, tick the events you want, and grant your admin role access.
  • Open Addons - W3 SMS and use the Send Test SMS tool to confirm it works.

Notification events

SettingWHMCS hookClient is texted when...
SMS on new invoiceInvoiceCreatedan invoice is generated for them (recurring or one-off).
SMS on payment receivedInvoicePaidone of their invoices is marked Paid.
SMS on staff ticket replyTicketAdminReplya staff member replies to their open support ticket.
SMS on service suspensionAfterModuleSuspendone of their hosting services is suspended.
A failed notification never blocks the invoice, payment, ticket reply or suspension it was about - it is written to the WHMCS Activity Log only. Full reference: DOCUMENTATION.md in the zip.