HTTP Specification
The SMS HTTP specification defines how to exchange SMS messages with DIDWW over HTTP. It includes information about inbound SMS delivery to your systems and outbound SMS submission to the DIDWW network, covering request formats, authentication, failover handling, and callback mechanisms.
Technical details for receiving inbound SMS from DIDWW via HTTP.
API reference for sending outbound SMS to the DIDWW network.
Inbound SMS Specification
The Inbound SMS service lets you receive text messages by having DIDWW forward them to your HTTP endpoint. Find out how requests are sent, which variables you can use, the formats supported for the request body, and key technical details such as retries and failover.
HTTP Request Details from DIDWW
When a message is received on one of your DIDs, DIDWW will send an HTTP request to the Request URL configured in your SMS to HTTP IN Trunk.
Property |
Description |
---|---|
HTTP Methods |
Supported methods are |
Source IP |
All requests originate from |
Connection Type |
HTTPS (recommended) and HTTP are supported. |
Note
Allow requests from 46.19.209.214 in your firewall.
Available Variables
Variable |
Description |
---|---|
|
The unique ID of the received message. |
|
The sender’s phone number (source address), for more information see RFC 3986 . |
|
The DID number that received the SMS (destination address), for more information see RFC 3986 . |
|
The raw text of the SMS message body. |
|
The SMS message body, encoded using Base64 . |
|
The date and time the message was received, for more information see RFC 1123 . |
Note
You can use these variables to construct the Request URL, Query Parameters, Headers, and Body of the request in your trunk configuration.
Request Body Formats
When DIDWW forwards an inbound SMS to your HTTP endpoint, the SMS data is placed in the body of the HTTP request. The format is selected in your trunk settings and determines how your server should parse the data.
- Available formats:
RAW
JSON (
application/json
)URL encoded (
application/x-www-form-urlencoded
)Multipart (
multipart/form-data
)
Note
Choose the format that matches how your endpoint is designed. For example, if your system expects JSON but receives URL encoded data, it will not parse correctly.
Technical Details
If your endpoint does not respond with a 2xx
status code, DIDWW will re-attempt to deliver the message until its Time To Live (TTL) of 3600 seconds (1 hour) expires.
The maximum size of an inbound SMS message is 64 KB.
Concatenated messages will be reassembled using User Data Header (UDH) before being delivered to your endpoint. Information about fragmentation will not be transmitted.
Outbound SMS Specification
DIDWW supports both Person-to-Person (P2P) and Application-to-Person (A2P) messaging. Outbound SMS can be sent using the DIDWW REST API, which follows the JSON:API specification , or via SMPP, which follows the standard SMPP specifications.
Authentication
API requests are secured with two layers: IP whitelisting and HTTP Basic Authentication. Both must be valid for a request to succeed.
1. IP Whitelisting (Network Layer)
In your HTTP OUT trunk configuration, specify the Allowed IP addresses. The API rejects requests from any other source.
2. Basic Authentication (Application Layer)
After IP validation, the system checks your credentials with HTTP Basic Authentication. The following tabs show two ways to provide credentials in a cURL command: a convenient shortcut and a manual method.
The easiest way to send credentials with cURL is the -u
flag. It automatically combines your username and password, Base64-encodes them, and adds the required Authorization
header.
curl -u username:password \
-X POST \
-H "Content-Type: application/vnd.api+json" \
https://sms-out.didww.com/outbound_messages \
-d '{
"data": {
"type": "outbound_messages",
"attributes": {
"destination": "15551234567",
"source": "12125551234",
"content": "Hello World!"
}
}
}'
This method shows what the -u flag does behind the scenes.
Combine credentials:
username:password
Base64 encode the string:
dXNlcm5hbWU6cGFzc3dvcmQ=
Add the result as an
Authorization
header:Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
curl -X POST \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Basic am9objpkb2U=" \
https://sms-out.didww.com/outbound_messages \
-d '{
"data": {
"type": "outbound_messages",
"attributes": {
"destination": "15551234567",
"source": "12125551234",
"content": "Hello World!"
}
}
}'
Endpoints & Headers
All API requests use the POST
method and must be sent to a valid API endpoint with the required headers.
Component |
Value |
---|---|
Global Endpoint |
|
Regional Endpoints |
Use a regional endpoint for potentially lower latency:
|
Request Paths |
Append to your chosen endpoint:
|
Content-Type Header |
|
Authorization Header |
|
Outbound SMS Examples
Note
When source
is present with a sender ID from the registered campaign, campaign_id
is not required.
http
POST /outbound_messages HTTP/1.1
Host: sms-out.didww.com
Content-Type: application/vnd.api+json
Authorization: Basic
{
"data": {
"type": "outbound_messages",
"attributes": {
"destination": "37041654321",
"source": "37041123456",
"content": "Hello World!"
}
}
}
curl
curl -i -X POST https://sms-out.didww.com/outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"content": "Hello World!", "destination": "37041654321", "source": "37041123456"}, "type": "outbound_messages"}}'
response
HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
"data": {
"type": "outbound_messages",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Note
When campaign_id
is present but source
is absent, the sender ID value will be assigned randomly from the registered campaign.
http
POST /outbound_messages HTTP/1.1
Host: sms-out.didww.com
Content-Type: application/vnd.api+json
Authorization: Basic
{
"data": {
"type": "outbound_messages",
"attributes": {
"destination": "37041654321",
"content": "Hello World!",
"campaign_id": "1111aaa-1a1a-a1a1-aaaa-11aaaaa1111"
}
}
}
curl
curl -i -X POST https://sms-out.didww.com/outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"campaign_id": "1111aaa-1a1a-a1a1-aaaa-11aaaaa1111", "content": "Hello World!", "destination": "37041654321"}, "type": "outbound_messages"}}'
response
HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
"data": {
"type": "outbound_messages",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
}
http
POST /bulk_outbound_messages HTTP/1.1
Host: sms-out.didww.com
Content-Type: application/vnd.api+json
Authorization: Basic
{
"data": {
"type": "bulk_outbound_messages",
"attributes": {
"destination": ["37041654321", "37041654322"],
"source": "37041123456",
"content": "Hello World!"
}
}
}
curl
curl -i -X POST https://sms-out.didww.com/bulk_outbound_messages -H "Content-Type: application/vnd.api+json" -H "Authorization: Basic" --data-raw '{"data": {"attributes": {"content": "Hello World!", "destination": ["37041654321", "37041654322"], "source": "37041123456"}, "type": "bulk_outbound_messages"}}'
response
HTTP/1.1 201 Created
Content-Type: application/vnd.api+json
{
"data": {
"type": "bulk_outbound_messages",
"id": "2C4807D1-74E4-4639-BBC4-057402F052FF",
"relationships": {
"outbound_messages": {
"data": [
{"type": "outbound_messages", "id": "E34C1810-434B-4E64-AFD9-EC0568F324A9"},
{"type": "outbound_messages", "id": "B6A48E34-3219-407D-99E6-770CF524F611"}
]
}
}
}
}
Outbound SMS Attributes
Attribute |
Required? |
Description |
---|---|---|
|
Required |
Recipient’s number in E.164 format. For bulk requests, use an array of numbers. Note If the destination region is not in your price list, you’ll receive a callback with code_id: 2. |
|
Optional |
DID number to use as the sender ID (E.164 format). Note The source DID must be authorized in your trunk’s Source Address Settings. |
|
Required |
Message text (UTF-8). A single SMS supports up to 160 characters. |
|
Optional |
ID of a registered A2P campaign. |
Status Callbacks
You can receive events related to your message processing status using the Callback mechanism. See the Callback URL configuration in Outbound SMS trunk settings.
Note
Configure your firewall to allow requests from the DIDWW callback IP ranges:
IPv4:
46.19.208.0/21
IPv6:
2a01:ad00::/32
Sent after processing an outbound SMS.
Payload Example:
{
"data": {
"type": "outbound_message_callbacks",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"time_start": "2025-08-12T12:24:30.45Z",
"time_end": "2025-08-12T12:24:31.15Z",
"destination": "15551234567",
"source": "12125551234",
"status": "Success",
"code_id": null,
"fragments_sent": 1,
"price": 0.0075
}
}
}
Attributes:
Attribute |
Description |
---|---|
|
Time message routing started (ISO 8601 ). |
|
Time message processing finished (ISO 8601 ). |
|
Sender ID of the message. |
|
Recipient’s number. |
|
Processing status: |
|
Number of fragments used. |
|
Cost per message fragment. |
|
Error code if status is not |
Sent from the carrier with the final delivery status (for example, DELIVERED
, FAILED
, or EXPIRED
).
Note
To enable DLR event notifications, contact support@didww.com .
Payload Example:
{
"data": {
"type": "dlr_event",
"id": "550e8400-e29b-41d4-a716-446655440000",
"attributes": {
"status": "DELIVERED",
"time_start": "2025-08-12T12:24:32.00Z"
}
}
}
Attributes:
Attribute |
Description |
---|---|
|
ID of the related outbound message |
|
Final carrier status (e.g., |
|
Time the DLR event was generated (ISO 8601 ). |
Callback Examples
If you configure callbacks for your endpoint, the following attributes are returned for each outbound SMS. In some cases, a DLR event callback may also be sent with additional status information.
Unique ID |
Time Start |
Time End |
Source |
Destination |
Status |
Fragments Sent |
Price |
---|---|---|---|---|---|---|---|
83950010-3954-43A6-8419-C1417807672F |
2023-04-11 09:07:35 |
2023-04-11 09:07:35 |
447418350728 |
447418356937 |
Success |
5 |
0.0375 |
When sending bulk SMS, you receive callbacks for every destination number with a unique ID. A DLR event callback may also be sent with final delivery details.
Unique ID |
Time Start |
Time End |
Source |
Destination |
Status |
Fragments Sent |
Price |
---|---|---|---|---|---|---|---|
DC38AA6B-C454-438F-9761-E3BDEA13BEE0 |
2023-04-11 09:14:30 |
2023-04-11 09:14:31 |
447418350728 |
37067738955 |
Success |
1 |
0.0075 |
8075CECO-9FB9-41B6-8580-DABBBB41F0E9 |
2023-04-11 09:14:30 |
2023-04-11 09:14:31 |
447418350728 |
447418356937 |
Success |
1 |
0.0075 |
Handling Errors
API Error Responses
If your API request is malformed or unauthorized, the service returns an immediate error response.
Returned when the Authorization
header is missing/invalid or the request comes from a non-allowed IP. See Authentication.
{
"errors": [
{
"title": "Unauthorized",
"detail": "Authorization failed",
"code": "401",
"status": "401"
}
]
}
Returned when the request payload does not follow JSON:API .
{
"errors": [
{
"title": "Bad Request",
"detail": "Invalid request",
"code": "400",
"status": "400"
}
]
}
Callback Error Codes and Retry Logic
The code_id
in a status callback provides specific details about a message failure.
Code |
Description |
---|---|
null |
Message was sent successfully |
1, 3 |
No routes found |
2 |
No rate found |
4, 6 |
Internal error |
5 |
SMS trunk is blocked |
7 |
Origination account is blocked |
8 |
SMS source address is not allowed |
9 |
SMS destination address is not allowed |
10, 11 |
SMS Campaign not found or blocked |
100 |
Insufficient balance |
101 |
All delivery attempts failed within the TTL |
102 |
No encoding available |
103 |
Max balance attempts reached |
104 |
Message defragmentation failed |
105 |
Routing failed |
If your callback endpoint returns a non-2xx HTTP response or times out (60 seconds), the system will retry delivery up to 9 more times.
Callback Attempt |
Wait Interval |
---|---|
2 |
1 minute |
3 |
10 minutes |
4 |
30 minutes |
5 |
1 hour |
6 |
3 hours |
7 |
6 hours |
8 |
12 hours |
9 |
1 day |
10 |
2 days |