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.
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.
| Parameter | Required | Meaning |
|---|---|---|
secret | yes | Your API secret. |
mode | yes | devices to send from one of your paired Android phones (the usual case). credits to send through a shared gateway, deducted from your balance. |
device | with devices | The device ID from your Devices list. |
sim | no | 1 or 2. Which SIM slot to send from. Defaults to the first. |
gateway | with credits | Gateway ID or global device ID. |
phone | yes | Recipient in international format, e.g. +15551234567. |
message | yes | The text. Must clear the site's minimum length. |
priority | no | 1 sends immediately, 2 queues (default). |
shortener | no | A 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.
| Parameter | Required | Meaning |
|---|---|---|
secret | yes | Your API secret. |
account | yes | Unique ID of one of your linked WhatsApp accounts (WhatsApp → Queue, or GET /api/get/wa.accounts). |
recipient | yes | A phone number in international format, or a full group ID ending in @g.us. |
type | no | text (default), media or document. |
message | yes | The text, or the caption for media. |
priority | no | 1 sends now, otherwise queued. |
media_url / media_file | with media | URL, or multipart upload, plus media_type: image, audio or video. |
document_url / document_file | with document | URL, 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
status | Meaning |
|---|---|
| 200 | Success. |
| 400 | Missing or invalid parameters: an unparsable phone number, a message shorter than the minimum, an unknown media type. |
| 401 | The secret does not match any API key. |
| 403 | Recognised secret, but not allowed: the key lacks the permission, your plan does not include the service, or a quota is reached. |
| 404 | The device, gateway, WhatsApp account or message ID does not belong to this account. |
| 500 | Something 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.
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.