6.5 KiB
voip.ms SMS/MMS REST API
Reference for the voip.ms SMS/MMS REST API. Sanitized — no account credentials or phone numbers. Account-specific values (API username/password, DID numbers, etc.) are kept local and supplied at runtime via environment variables.
Endpoint & authentication
- Base URL:
https://voip.ms/api/v1/rest.php(usevoip.ms, notwww.voip.ms— thewwwhost 302-redirects and drops POST bodies, producingmissing_method). - Auth (every request):
api_username,api_password,method.api_usernameis the portal login email — not the 6-digit account ID.api_passwordis set under Main Menu → SOAP / REST API → API Security and is distinct from the portal login password.- The calling server's public IP must be whitelisted on the same API Security page.
- Transport: GET with query params for SMS; POST
multipart/form-datafor MMS with base64 images. - A separate bearer token / API key exists for the 3CX webhook flow — it is not
used by
rest.php.
Limits & pricing
- API sending cap: 100 SMS/MMS per day (portal is unlimited). Raise via support ticket.
- SMS: $0.0075 each way. MMS: $0.02 each way.
- US/Canada 10-digit DIDs only; short codes and 2FA codes aren't guaranteed; public URL shorteners (bit.ly etc.) may be blocked.
- MMS attachments: types
JPG, GIF, JPEG, PNG, MP3, WAV, MIDI, MP4, 3GP; ≤1300 KB each; up to 3 files; text ≤2048 chars.
Methods
sendSMS — send a text
| Param | Req | Notes |
|---|---|---|
did |
yes | Sender DID, e.g. 5551234567 |
dst |
yes | Destination number |
message |
yes | Max 160 chars |
Returns {"status":"success","sms":<new id>}. Requires SMS enabled on the DID
(see setSMS below), else {"status":"sms_failed","message":"The SMS message was not sent"}.
sendMMS — send media/text
| Param | Req | Notes |
|---|---|---|
did |
yes | Sender DID |
dst |
yes | Destination |
message |
yes | Max 2048 chars |
media1 |
no | URL to a media file |
media2 |
no | Base64 image (data:image/png;base64,...) |
media3 |
no | Reserved/empty |
- POST + base64 → up to 1.2 MB/file; GET + base64 → ~160 KB (~512-char URL limit). File-URL submissions have no size limit either way.
getSMS — list/retrieve texts
| Param | Req | Notes |
|---|---|---|
sms |
no | ID for a specific SMS |
from |
no | Start date YYYY-MM-DD (default: today) |
to |
no | End date (default: today) |
type |
no | 1=received, 0=sent |
did |
no | Filter by DID |
contact |
no | Filter by contact number |
limit |
no | Records to return (default 50) |
timezone |
no | Numeric -12 to 13 |
all_messages |
no | 1 = SMS + MMS combined, 0 = SMS only (id must be 0 when set) |
Returns {"status":"success","sms":[ ...rows... ]}. Empty result returns
{"status":"no_sms","message":"There are no SMS messages"} — treat as [], not an error.
getMMS — list/retrieve media messages
Same shape as getSMS but the id param is mms. all_messages=1 returns MMS+SMS
combined (id must be 0). Empty result also reports status: no_sms.
getMediaMMS — fetch attachments for a message
| Param | Req | Notes |
|---|---|---|
id |
yes | MMS id |
media_as_array |
no | 1=array, 0=JSON object (default) |
Returns {"status":"success","id":...,"date":...,"media":[url,...]} (up to 3 slots).
deleteSMS / deleteMMS — delete one message
| Param | Req | Notes |
|---|---|---|
id |
yes | Message id |
Returns {"status":"success"}.
setSMS — enable/disable SMS on a DID
| Param | Req | Notes |
|---|---|---|
did |
yes | DID to update |
enable |
yes | 1 to enable, 0 to disable |
email_enabled |
no | bool — forward inbound SMS to email |
email_address |
no | email address(es), comma-separated |
sms_forward_enable |
no | bool — forward inbound SMS to another number |
sms_forward |
no | forwarding number |
url_callback_enable |
no | bool — GET callback on inbound |
url_callback |
no | callback URL (variables below) |
url_callback_retry |
no | bool — require ok response, retry every 30 min |
SMS must be enabled on a DID (enable=1) before sendSMS works.
getDIDsInfo — list DIDs on the account
Returns {"status":"success","dids":[ ... ]}. Each DID includes sms_available,
sms_enabled, mms_available, and the full SMS config fields — use this to find a
SMS-capable DID and check whether SMS is enabled.
Note:
getDIDs,getDIDInfo,getDIDare not valid methods — usegetDIDsInfo.
Inbound via URL Callback (per-DID)
Configure on the DID (portal Manage DID, or setSMS):
https://your.host/sms?to={TO}&from={FROM}&message={MESSAGE}&id={ID}&date={TIMESTAMP}&media={MEDIA}
Variables: {ID}, {TIMESTAMP}, {FROM}, {TO}, {MESSAGE}, {MEDIA} (comma-separated
media list, for MMS).
Retry: if "URL Callback Retry" is enabled, your endpoint must respond with the literal
body ok. Without it, voip.ms re-sends the same message every 30 minutes.
Dialing mode (per-DID, for 3CX/API)
Choose NANPA (10-digit, no country code) or E164 (+1 + 10 digits). Affects what you send
to the API and what arrives in callbacks — normalize on your side.
Gotchas
api_usernameis the portal email, not the account ID.- Empty
getSMS/getMMSresults reportstatus: no_sms(even for MMS) — return[]. - SMS must be enabled per-DID (
setSMS enable=1) before sending, elsesms_failed. sendSMS/sendMMSreuse thesmsresponse key for the new message id (int);getSMSusessmsfor the row list;getMMSusesmms.- No
markSMSReadmethod exists. - SIP/SMS over SIP MESSAGE is text-only (no MMS) and uses a separate SIP sub-account, not the REST API.
- DID POP must match the registered SIP server or inbound calls won't ring.
- Transient transport errors occur; clients should retry with backoff.
Other ingestion channels (non-REST)
- Email to SMS: mail
sms@voip.ms, subject = recipient 10-digit number; security-code / from-DID overrides via dot syntaxdst.seccode.fromdid. - SMPP:
smpp.voip.ms:2775(plain) /:3550(TLS, schemessmpp); bind as transceiver;source_addr= SMS-enabled DID. Bypasses the 100/day REST cap. - SIP MESSAGE (RFC 3428): SMS only, user/pass-auth trunks; original destination in
X-Sms-Toheader on receive.
Source: voip.ms official API docs (/m/apidocs.php) + SMS/MMS wiki article, verified live.