# 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` (use `voip.ms`, **not** `www.voip.ms` — the `www` host 302-redirects and drops POST bodies, producing `missing_method`). - **Auth (every request):** `api_username`, `api_password`, `method`. - `api_username` is the **portal login email** — *not* the 6-digit account ID. - `api_password` is 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-data` for 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":}`. 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`, `getDID` are **not** valid methods — use `getDIDsInfo`. ## 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_username` is the portal **email**, not the account ID. - Empty `getSMS`/`getMMS` results report `status: no_sms` (even for MMS) — return `[]`. - SMS must be enabled per-DID (`setSMS enable=1`) before sending, else `sms_failed`. - `sendSMS`/`sendMMS` reuse the `sms` response key for the new message id (int); `getSMS` uses `sms` for the row list; `getMMS` uses `mms`. - No `markSMSRead` method 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 syntax `dst.seccode.fromdid`. - **SMPP:** `smpp.voip.ms:2775` (plain) / `:3550` (TLS, scheme `ssmpp`); 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-To` header on receive. --- *Source: voip.ms official API docs (`/m/apidocs.php`) + SMS/MMS wiki article, verified live.*