152
sms/docs/voipms-sms-api.md
Normal file
152
sms/docs/voipms-sms-api.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 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":<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`, `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.*
|
||||
Reference in New Issue
Block a user