Hosted SIM API

Messages

Send, read, redact and delete the texts on your line.

GET /Accounts/{AccountSid}/Messages.json

List texts.

Lists the account's texts, sent and received, one page at a time. An incoming text over 1600 characters arrives as consecutive Messages of ≤ 1600 characters each, never truncated. A filter value that isn't valid, or a query parameter not listed here, answers 400 with code 790005.

Parameters

NameInRequiredDescription
To query

Only texts to this number (E.164).

From query

Only texts from this number (E.164).

DateSent query

Only texts sent on this date (YYYY-MM-DD).

DateSent< query

Only texts sent on or before this date (YYYY-MM-DD; in a URL it reads DateSent<=2026-11-02).

DateSent> query

Only texts sent on or after this date (YYYY-MM-DD; in a URL it reads DateSent>=2026-11-01).

PageSize query

Items per page, ≤ 1000, default 50. List pages with PageSize over 50 are rate-limited at 2/s per account.

Page query

The page number, from 0. Use the *_page_uri values rather than building it yourself.

PageToken query

An opaque paging token. It comes inside next_page_uri / previous_page_uri.

Responses

StatusMeaning
200

One page of texts.

400

A list filter value that isn't valid, or a query parameter the list doesn't take (790005, naming it in parameter).

401

Authentication failed (20003), or the account isn't active (20005). This comes before any lookup.

429

Over a rate (20429, with Retry-After in seconds): per account, GET 10/s (burst 30), list pages with PageSize over 50 at 2/s, POST/DELETE 5/s (burst 10); per source IP before auth, 20/s; a gateway-wide ceiling with a fair share per account. Failed auth from one source IP (10/min) also answers 429 with code 20429, for 15 min.

500

An internal error (799999).

Response fields

FieldTypeAlways thereDescription
page integer

The page number, from 0.

page_size integer
uri string
first_page_uri string
next_page_uri string or null

The next page, or null.

previous_page_uri string or null

The previous page, or null.

messages array of object

The texts on this page.

messages[].sid stringrequired

SM + 32 hex.

messages[].account_sid stringrequired
messages[].to stringrequired

E.164.

messages[].from stringrequired

E.164.

messages[].body stringrequired

The text. It's "" after a redaction.

messages[].num_segments stringrequired

The number of parts, as a string. GSM-7 is 153 characters per part, UCS-2 is 67.

messages[].num_media stringrequired

Always "0" (no MMS in v1).

messages[].error_code integer or nullrequired
messages[].error_message string or nullrequired
messages[].date_created stringrequired

RFC 2822.

messages[].date_sent string or nullrequired

RFC 2822.

messages[].date_updated stringrequired

RFC 2822.

messages[].price nullrequired

Always null: billing is in the console.

messages[].api_version stringrequired
messages[].uri stringrequired
messages[].status string: queued, sent, delivered, undelivered, failed, receivedrequired

There's no sending status: your dongle reports no such step. delivered / undelivered arrive only once SMS status reports are built. Until then, sent is the last status.

messages[].direction string: outbound-api, inbound, outbound-replyrequired

outbound-reply is a reply sent by TwiML <Message>.

Example request

curl -X GET "https://api.dongleswithwings.com/2010-04-01/Accounts/{AccountSid}/Messages.json" \
  -u "$ACCOUNT_SID:$AUTH_TOKEN"

Example response

{
  "page": 0,
  "page_size": 50,
  "uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages.json?To=%2B61491570156&DateSent=2026-11-02&PageSize=50&Page=0",
  "first_page_uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages.json?To=%2B61491570156&DateSent=2026-11-02&PageSize=50&Page=0",
  "next_page_uri": null,
  "previous_page_uri": null,
  "messages": [
    {
      "sid": "SM2e501f7cf7d4db3bf2f2a062d558b817",
      "account_sid": "ACa61cd972830fc5bc41386edc0a9f8463",
      "to": "+61491570156",
      "from": "+61491570158",
      "body": "Can we move it to 10am instead?",
      "num_segments": "1",
      "num_media": "0",
      "error_code": null,
      "error_message": null,
      "date_created": "Mon, 02 Nov 2026 05:41:30 +0000",
      "date_sent": "Mon, 02 Nov 2026 05:41:28 +0000",
      "date_updated": "Mon, 02 Nov 2026 05:41:30 +0000",
      "price": null,
      "api_version": "2010-04-01",
      "uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages/SM2e501f7cf7d4db3bf2f2a062d558b817.json",
      "status": "received",
      "direction": "inbound"
    }
  ]
}

POST /Accounts/{AccountSid}/Messages.json

Send a text from your line.

Texts report sent, not delivered, until SMS status reports ship. No MMS, messaging services or scheduling in v1.

Sends a text from your line. The answer is 201, with status queued and num_segments (GSM-7 is 153 characters per part, UCS-2 is 67).

  • Refused parameters: MessagingServiceSid, ContentSid, ContentVariables, SendAt, ScheduleType, ShortenUrls, ValidityPeriod, and any parameter not listed here (e.g. MaxPrice, Attempt) each give 400, code 710003, naming it in parameter. MediaUrl gives 711001 (no MMS in v1).
  • Per-line limits: texts per hour and per day (your line's send policy). Past one of these limits the answer is 710001.
  • Statuses: delivered / undelivered arrive only once SMS status reports are built. Until then, sent is the last status.

Request body

Form-encoded (application/x-www-form-urlencoded).

FieldTypeRequiredDescription
To stringrequired

The number to text, E.164. Not a valid number gives 21211.

Errors: 21211

From stringrequired

The line's number. A number that isn't one of your lines gives 21606; an invalid number gives 21212.

Errors: 21212, 21606

Body stringrequired

1-1600 characters. Missing gives 21602; over 1600 gives 21617.

Errors: 21602, 21617

StatusCallback string

Where the messageStatus webhook and runtime errors go.

Errors: 21205, 790001

MessagingServiceSid not in v1 (710003)

Refused in v1 (710003).

ContentSid not in v1 (710003)

Refused in v1 (710003).

ContentVariables not in v1 (710003)

Refused in v1 (710003).

SendAt not in v1 (710003)

Refused in v1 (710003).

ScheduleType not in v1 (710003)

Refused in v1 (710003).

ShortenUrls not in v1 (710003)

Refused in v1 (710003).

ValidityPeriod not in v1 (710003)

Refused in v1 (710003).

MediaUrl not in v1 (711001)

MMS isn't supported in v1 (711001).

Any parameter not listed here is refused with 710003, naming it in parameter: v1 never ignores one.

Responses

StatusMeaning
201

The text is accepted, and status is queued.

400

A parameter or the text was refused: 21205, 21211, 21212, 21602, 21606, 21617, 710002, 710003, 711001 or 790001.

401

Authentication failed (20003), or the account isn't active (20005). This comes before any lookup.

413

The request body is over 64 KiB (790006). It's refused before parsing.

429

Too many requests (20429), or the line's text limit is reached (710001).

500

An internal error (799999).

Response fields

FieldTypeAlways thereDescription
sid string

SM + 32 hex.

account_sid string
to string

E.164.

from string

E.164.

body string

The text. It's "" after a redaction.

num_segments string

The number of parts, as a string. GSM-7 is 153 characters per part, UCS-2 is 67.

num_media string

Always "0" (no MMS in v1).

error_code integer or null
error_message string or null
date_created string

RFC 2822.

date_sent string or null

RFC 2822.

date_updated string

RFC 2822.

price null

Always null: billing is in the console.

api_version string
uri string
status string: queued, sent, delivered, undelivered, failed, received

There's no sending status: your dongle reports no such step. delivered / undelivered arrive only once SMS status reports are built. Until then, sent is the last status.

direction string: outbound-api, inbound, outbound-reply

outbound-reply is a reply sent by TwiML <Message>.

Example request

curl -X POST "https://api.dongleswithwings.com/2010-04-01/Accounts/{AccountSid}/Messages.json" \
  --data-urlencode "To=+61491570158" \
  --data-urlencode "From=+61491570156" \
  --data-urlencode "Body=Your appointment is tomorrow at 9:30am. Reply C to cancel." \
  --data-urlencode "StatusCallback=https://hooks.example.com/sms/status" \
  -u "$ACCOUNT_SID:$AUTH_TOKEN"

Example response

{
  "sid": "SM376a448e3788676f35200c0f74bec592",
  "account_sid": "ACa61cd972830fc5bc41386edc0a9f8463",
  "to": "+61491570158",
  "from": "+61491570156",
  "body": "Your appointment is tomorrow at 9:30am. Reply C to cancel.",
  "num_segments": "1",
  "num_media": "0",
  "error_code": null,
  "error_message": null,
  "date_created": "Mon, 02 Nov 2026 05:20:11 +0000",
  "date_sent": null,
  "date_updated": "Mon, 02 Nov 2026 05:20:11 +0000",
  "price": null,
  "api_version": "2010-04-01",
  "uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages/SM376a448e3788676f35200c0f74bec592.json",
  "status": "queued",
  "direction": "outbound-api"
}

GET /Accounts/{AccountSid}/Messages/{SMSid}.json

Read one text.

Returns one text. A Sid that isn't on this account gives 404 (code 20404).

Responses

StatusMeaning
200

The text. This one is a reply sent by TwiML <Message>, so its direction is outbound-reply.

401

Authentication failed (20003), or the account isn't active (20005). This comes before any lookup.

404

Not found (20404). That includes a Sid that isn't on the path's account; the answer never hints at another tenant.

429

Over a rate (20429, with Retry-After in seconds): per account, GET 10/s (burst 30), list pages with PageSize over 50 at 2/s, POST/DELETE 5/s (burst 10); per source IP before auth, 20/s; a gateway-wide ceiling with a fair share per account. Failed auth from one source IP (10/min) also answers 429 with code 20429, for 15 min.

500

An internal error (799999).

Response fields

FieldTypeAlways thereDescription
sid string

SM + 32 hex.

account_sid string
to string

E.164.

from string

E.164.

body string

The text. It's "" after a redaction.

num_segments string

The number of parts, as a string. GSM-7 is 153 characters per part, UCS-2 is 67.

num_media string

Always "0" (no MMS in v1).

error_code integer or null
error_message string or null
date_created string

RFC 2822.

date_sent string or null

RFC 2822.

date_updated string

RFC 2822.

price null

Always null: billing is in the console.

api_version string
uri string
status string: queued, sent, delivered, undelivered, failed, received

There's no sending status: your dongle reports no such step. delivered / undelivered arrive only once SMS status reports are built. Until then, sent is the last status.

direction string: outbound-api, inbound, outbound-reply

outbound-reply is a reply sent by TwiML <Message>.

Example request

curl -X GET "https://api.dongleswithwings.com/2010-04-01/Accounts/{AccountSid}/Messages/{SMSid}.json" \
  -u "$ACCOUNT_SID:$AUTH_TOKEN"

Example response

{
  "sid": "SM3a823f1447314a11c6bea88be87b2b0c",
  "account_sid": "ACa61cd972830fc5bc41386edc0a9f8463",
  "to": "+61491570158",
  "from": "+61491570156",
  "body": "Sure, 10am works. See you then.",
  "num_segments": "1",
  "num_media": "0",
  "error_code": null,
  "error_message": null,
  "date_created": "Mon, 02 Nov 2026 05:41:31 +0000",
  "date_sent": "Mon, 02 Nov 2026 05:41:34 +0000",
  "date_updated": "Mon, 02 Nov 2026 05:41:34 +0000",
  "price": null,
  "api_version": "2010-04-01",
  "uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages/SM3a823f1447314a11c6bea88be87b2b0c.json",
  "status": "sent",
  "direction": "outbound-reply"
}

POST /Accounts/{AccountSid}/Messages/{SMSid}.json

Redact a text (Body="").

Redacts the text's body (privacy). The only update is Body="". Any other Body answers 710004, and any other parameter answers 710003. Records are kept for 3 months (90 days), then deleted with their bodies, and never backed up beyond that.

Request body

Form-encoded (application/x-www-form-urlencoded).

FieldTypeRequiredDescription
Body stringrequired

Must be empty, which redacts the body. Anything else gives 710004.

Errors: 710004

Any parameter not listed here is refused with 710003, naming it in parameter: v1 never ignores one.

Responses

StatusMeaning
200

The text, with its body redacted.

400

Not a redaction: 710004 (a Body other than empty) or 710003 (another parameter).

401

Authentication failed (20003), or the account isn't active (20005). This comes before any lookup.

404

Not found (20404). That includes a Sid that isn't on the path's account; the answer never hints at another tenant.

413

The request body is over 64 KiB (790006). It's refused before parsing.

429

Over a rate (20429, with Retry-After in seconds): per account, GET 10/s (burst 30), list pages with PageSize over 50 at 2/s, POST/DELETE 5/s (burst 10); per source IP before auth, 20/s; a gateway-wide ceiling with a fair share per account. Failed auth from one source IP (10/min) also answers 429 with code 20429, for 15 min.

500

An internal error (799999).

Response fields

FieldTypeAlways thereDescription
sid string

SM + 32 hex.

account_sid string
to string

E.164.

from string

E.164.

body string

The text. It's "" after a redaction.

num_segments string

The number of parts, as a string. GSM-7 is 153 characters per part, UCS-2 is 67.

num_media string

Always "0" (no MMS in v1).

error_code integer or null
error_message string or null
date_created string

RFC 2822.

date_sent string or null

RFC 2822.

date_updated string

RFC 2822.

price null

Always null: billing is in the console.

api_version string
uri string
status string: queued, sent, delivered, undelivered, failed, received

There's no sending status: your dongle reports no such step. delivered / undelivered arrive only once SMS status reports are built. Until then, sent is the last status.

direction string: outbound-api, inbound, outbound-reply

outbound-reply is a reply sent by TwiML <Message>.

Example request

curl -X POST "https://api.dongleswithwings.com/2010-04-01/Accounts/{AccountSid}/Messages/{SMSid}.json" \
  --data-urlencode "Body=" \
  -u "$ACCOUNT_SID:$AUTH_TOKEN"

Example response

{
  "sid": "SMa6b1a15fa6aac00bb3439addd9a53b87",
  "account_sid": "ACa61cd972830fc5bc41386edc0a9f8463",
  "to": "+61491570156",
  "from": "+61491570158",
  "body": "",
  "num_segments": "1",
  "num_media": "0",
  "error_code": null,
  "error_message": null,
  "date_created": "Sun, 01 Nov 2026 22:15:40 +0000",
  "date_sent": "Sun, 01 Nov 2026 22:15:38 +0000",
  "date_updated": "Mon, 02 Nov 2026 06:30:00 +0000",
  "price": null,
  "api_version": "2010-04-01",
  "uri": "/2010-04-01/Accounts/ACa61cd972830fc5bc41386edc0a9f8463/Messages/SMa6b1a15fa6aac00bb3439addd9a53b87.json",
  "status": "received",
  "direction": "inbound"
}

DELETE /Accounts/{AccountSid}/Messages/{SMSid}.json

Delete a text's record.

Deletes the text's record (privacy).

Responses

StatusMeaning
204

Deleted. The body is empty.

401

Authentication failed (20003), or the account isn't active (20005). This comes before any lookup.

404

Not found (20404). That includes a Sid that isn't on the path's account; the answer never hints at another tenant.

429

Over a rate (20429, with Retry-After in seconds): per account, GET 10/s (burst 30), list pages with PageSize over 50 at 2/s, POST/DELETE 5/s (burst 10); per source IP before auth, 20/s; a gateway-wide ceiling with a fair share per account. Failed auth from one source IP (10/min) also answers 429 with code 20429, for 15 min.

500

An internal error (799999).

Example request

curl -X DELETE "https://api.dongleswithwings.com/2010-04-01/Accounts/{AccountSid}/Messages/{SMSid}.json" \
  -u "$ACCOUNT_SID:$AUTH_TOKEN"

Example response

HTTP/1.1 204 No Content (empty body)