Developer docs

SMS and WhatsApp REST API

Send SMS through the Android phone you paired, send WhatsApp through the account you linked, check delivery and read your usage. One base URL, one secret, form-encoded parameters, JSON back.

Base URL https://sharksms.com/api

lang_undefined

lang_undefined

lang_undefined

Authentication

Create a key under Tools → API Keys in your dashboard. Each key has a name and a set of permissions; every endpoint below names the permission it needs, and a key without it gets 403. The secret is a 40-character random string, shown once from the copy button on the key's row. Treat it like a password: server side only, never in a browser or an app you distribute.

There is no Authorization header. Pass the secret as a parameter named secret, as a form field on POST or a query parameter on GET. A missing or unknown secret returns status 401 before any endpoint logic runs.

Every response is HTTP 200. Even a rejected call comes back HTTP/1.1 200 OK. Branch on the JSON status field, never on the HTTP status line. Codes.
{"status": 403, "message": "This API key doesn't have permission to use this endpoint!", "data": false}

Send an SMS

POST /api/send/sms. Permission sms_send. Requires the SMS service on your plan.

ParameterRequiredMeaning
secretyesYour API secret.
modeyesdevices to send from one of your paired Android phones (the usual case). credits to send through a shared gateway, deducted from your balance.
devicewith devicesThe device ID from your Devices list.
simno1 or 2. Which SIM slot to send from. Defaults to the first.
gatewaywith creditsGateway ID or global device ID.
phoneyesRecipient in international format, e.g. +15551234567.
messageyesThe text. Must clear the site's minimum length.
priorityno1 sends immediately, 2 queues (default).
shortenernoA shortener ID; any URL in message is shortened first.
curl -X POST "https://sharksms.com/api/send/sms" \
  -d "secret=YOUR_API_SECRET" \
  -d "mode=devices" \
  -d "device=00000000-0000-0000-d57d-f30cb6a89289" \
  -d "sim=1" \
  -d "phone=+15551234567" \
  -d "priority=2" \
  -d "message=Hi Maria, reminder: your cut with Dani is tomorrow at 3:30pm. Reply C to cancel."

Success:

{"status":200,"message":"Message has been queued for sending!","data":{"messageId":123}}

Keep messageId; it is what you pass to check delivery. Send the parameters as a form body (application/x-www-form-urlencoded) or query string, not as a JSON document.

Send a WhatsApp message

POST /api/send/whatsapp. Permission wa_send. Requires the WhatsApp service on your plan and a linked WhatsApp account. Note the recipient parameter is recipient, not phone.

ParameterRequiredMeaning
secretyesYour API secret.
accountyesUnique ID of one of your linked WhatsApp accounts (WhatsApp → Queue, or GET /api/get/wa.accounts).
recipientyesA phone number in international format, or a full group ID ending in @g.us.
typenotext (default), media or document.
messageyesThe text, or the caption for media.
priorityno1 sends now, otherwise queued.
media_url / media_filewith mediaURL, or multipart upload, plus media_type: image, audio or video.
document_url / document_filewith documentURL, or multipart upload, plus document_type (pdf, xml, xls, xlsx, doc, docx) and optional document_name.
curl -X POST "https://sharksms.com/api/send/whatsapp" \
  -d "secret=YOUR_API_SECRET" \
  -d "account=YOUR_WA_ACCOUNT_ID" \
  -d "recipient=+15551234567" \
  -d "type=document" \
  -d "document_url=https://example.com/quote-4471.pdf" \
  -d "document_type=pdf" \
  -d "document_name=quote-4471.pdf" \
  -d "message=Your Civic is done. Total is $214, we close at 6."
{"status":200,"message":"WhatsApp chat has been queued for sending!","data":{"messageId":456}}

Bulk sends

POST /api/send/sms.bulk (permission sms_send_bulk) and POST /api/send/whatsapp.bulk (permission wa_send_bulk) take the same parameters as the single-send endpoints, except that instead of one recipient you pass a campaign name plus numbers (comma-separated, SMS) or recipients (comma-separated numbers and/or group IDs, WhatsApp) and/or groups (comma-separated contact group IDs). At least one recipient source is required.

curl -X POST "https://sharksms.com/api/send/sms.bulk" \
  -d "secret=YOUR_API_SECRET" \
  -d "mode=devices" \
  -d "device=YOUR_DEVICE_ID" \
  -d "campaign=Friday special" \
  -d "groups=12" \
  -d "message=Friday special: half rack of ribs, $18, until we run out. Kitchen opens at 5."

Check delivery status

GET /api/get/sms.message and GET /api/get/wa.message. Pass id (the messageId you got back) and type: sent or received. Sent lookups need get_sms_sent / get_wa_sent; received lookups need get_sms_received / get_wa_received. sms.message also always requires get_message.

curl -G "https://sharksms.com/api/get/sms.message" \
  -d "secret=YOUR_API_SECRET" \
  -d "id=123" \
  -d "type=sent"

data.status for a sent SMS is one of queued, pending, sent or failed; for WhatsApp pending, queued, sent or failed. The record also carries sender, recipient, message and created (Unix time). For a status that changes without polling, use a webhook for the reply and poll only the sends you care about.

Read your usage

GET /api/get/subscription returns your plan as used/limit pairs (usage.sms_send, usage.wa_send, usage.apikeys, and so on). It is the definitive way to see how close you are to a limit before a send fails.

curl -G "https://sharksms.com/api/get/subscription" -d "secret=YOUR_API_SECRET"

USSD (balance checks and top-ups)

POST /api/send/ussd (permission ussd, Android 8 or newer) with device, sim and code, e.g. your carrier's balance code. The request is queued against the phone; the carrier's answer arrives asynchronously as a ussd webhook event. GET /api/get/ussd lists past requests and their responses.

Errors and limits

statusMeaning
200Success.
400Missing or invalid parameters: an unparsable phone number, a message shorter than the minimum, an unknown media type.
401The secret does not match any API key.
403Recognised secret, but not allowed: the key lacks the permission, your plan does not include the service, or a quota is reached.
404The device, gateway, WhatsApp account or message ID does not belong to this account.
500Something failed on our side or a downstream service (a disconnected WhatsApp session, a phone that rejected the send). Safe to retry later; not a problem with your request.

There is no per-second rate limit. What looks like one is your plan's message quota: once sms_send or wa_send is used up, sends fail with 403 and "Maximum allowed number of sent messages has been reached!". Quotas reset on your plan's cycle, not on a rolling window, so there is no retry-after; check usage when you are close.

Idempotency. The API does not deduplicate. If your client times out and retries, the customer can get the message twice. Record the messageId on the first success and do not resend on a timeout without checking status first.

Next: Webhooks, for the replies. Or jump straight to a Python or Node.js example.