Skip to content
BitSMS
Menu

Developers

SMS API for developers

A small, predictable REST API. Send your first SMS in two minutes with cURL, Node.js, PHP, Python or Go.

Base URL: https://sms-api.bitcommerz.com/v1API referenceDownload the OpenAPI specAPI status

Quick start

  1. 1

    Create an account

    Sign up and verify your mobile number to get trial credit.

  2. 2

    Create an API key

    In the dashboard, open API keys and create a key with the messages:send scope. It is shown once; store it as BITSMS_API_KEY.

  3. 3

    Send a message

    POST /v1/messages with the number and text. You get 202 and a message ID; follow its status by API or webhook.

Send an SMS

Numbers can be 01XXXXXXXXX, 8801XXXXXXXXX or +8801XXXXXXXXX. Omit sender_id to use the default non-masking sender.

curl https://sms-api.bitcommerz.com/v1/messages \
  -H "Authorization: Bearer $BITSMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-5521-shipped" \
  -d '{"to": "01712345678", "text": "Your order #5521 has shipped."}'

Check a message

Statuses move forward only: queued, sent, then delivered, failed or expired. Webhooks are the better way to follow them.

curl https://sms-api.bitcommerz.com/v1/messages/$MESSAGE_ID \
  -H "Authorization: Bearer $BITSMS_API_KEY"

Send and verify an OTP

BitSMS generates the code and never returns it. Verify returns verified: true or false; after 5 wrong codes or expiry the OTP is closed.

# 1. Send: BitSMS generates the code and never returns it.
curl https://sms-api.bitcommerz.com/v1/otp \
  -H "Authorization: Bearer $BITSMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: login-7f3a91" \
  -d '{"to": "01712345678", "app_name": "MyShop"}'
# → 202 {"otp_id": "…", "message_id": "…", "expires_at": "…"}

# 2. Verify what the user typed.
curl https://sms-api.bitcommerz.com/v1/otp/$OTP_ID/verify \
  -H "Authorization: Bearer $BITSMS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code": "482913"}'
# → 200 {"verified": true}

Verify webhook signatures

Each delivery carries a BitSMS-Signature header. Check it against the raw body with your endpoint secret before trusting the event.

# Each delivery is signed:
#   BitSMS-Signature: t=1730000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
# v1 = hex(HMAC-SHA256(webhook_secret, "<t>.<raw request body>"))
# Reject if t is more than 5 minutes old. During secret rotation there are
# two v1= values; accept either.

How the API behaves

Authentication

Send your key as Authorization: Bearer bsk_live_…. Keys have scopes and can be limited to your server IPs. Never put a key in a browser or mobile app.

Idempotency

Every send needs an Idempotency-Key. Retrying with the same key and body returns the original result, so a network timeout never causes a duplicate SMS or a double charge.

Errors

Errors share one shape: a stable code such as insufficient_credit or invalid_destination, a readable message and a request ID to quote to support.

Rate limits

Each key has a request rate. Responses include X-RateLimit headers; when you go over, you get 429 with Retry-After.

Send your first SMS in minutes

Sign up, verify your mobile number and get ৳25 free credit to test with. No card needed.