List messages

GET /v1/messages

Send your API key as a bearer token: Authorization: Bearer ssms_sk_.... Test keys run this endpoint against the sandbox; see Authentication for key modes and scopes.

Query parameters

NameTypeRequiredDescription
limitintegerNoDefault 25. Maximum 100.
cursorstringNo
numberstringNoFilter to messages to or from this number
tostringNoExact destination number (E.164)
fromstringNoExact sending number (E.164)
statusqueued, sent, delivered, failed, receivedNo
directionoutbound, inboundNo
created_afterstringNoInclusive. ISO timestamp or epoch ms.
created_beforestringNoExclusive. ISO timestamp or epoch ms.
customer_idstringNoFilter to one customer's messages
schedule_idstringNoFilter to the occurrences of one recurring schedule (sch_...)

Results are paged. When has_more is true, pass next_cursor from the response as cursor to fetch the next page.

Responses

StatusMeaningBody
200Messages, newest firstPage of Message
401Missing, malformed, or revoked API keyError
402Billable live calls only: the prepaid credit balance cannot cover the call (insufficient_credits); nothing was done or chargedError
429Rate limit or quota exceededError

200: each item in data (Message)

The body is a page: data (the array), has_more, and next_cursor (null on the last page).

FieldTypeDescription
idstringExample: msg_a1B2c3D4e5F6g7H8.
objectmessage
tostringExample: +15005550006.
fromstringExample: +15005550100.
bodystring
directionoutbound, inbound
statusqueued, sent, delivered, failed, received
testboolean
simulatedbooleanTrue when nothing was handed to a carrier: every test-key message except one sent to your own verified phone. Always false on live messages. A simulated message still reaches delivered.
noticestringOnly on the response to POST /messages. Present when a test-key send to a real-looking number was simulated: says nothing was sent and how to send for real.
schedule_idstringThe recurring schedule this message is an occurrence of. Present only when set.
created_atstring (date-time)
mediaarray of string (uri)MMS attachments (inbound today).
sent_bystringConsole user or API key that composed it.
failure_reasonstringThe carrier's raw text for a failed send. Kept for compatibility; see failure.
attemptsintegerLive sends: carrier submissions so far. More than 1 means it was retried.
next_attempt_atstring (date-time)Present while queued for an automatic carrier retry.
receipt_statusmissingThe carrier accepted the message but sent no delivery report within 72 hours. status stays sent.
customer_idstringThe customer this is attributed to. Present only when set.
timelinearray of objectEvery status transition, oldest first. Inbound messages have a single received.
timeline[].statusaccepted, validated, queued, sent_to_carrier, carrier_accepted, retry_scheduled, delivered, failed, received
timeline[].atstring (date-time)
timeline[].attemptintegerCarrier attempt this step belongs to (from sent_to_carrier on).
segmentsintegerParts the body is split into (GSM-7: 160, then 153 each; UCS-2: 70, then 67). Example: 1.
encodinggsm7, ucs2
priceobjectWhat this message costs, in USD. One all-in rate per outbound message; carrier fees are included (a 0 line). Null on messages sent before prices were recorded. Nullable.
price.totalnumberExample: 0.009.
price.currencyusd
price.breakdownarray of object
price.breakdown[].labelstring
price.breakdown[].amountnumber
destination_carrierstringThe recipient's mobile carrier, when a cached lookup knows it. Nullable.
failureFailureNull unless status is failed. Nullable.

Errors

StatusWhen
401Missing, malformed, or revoked API key
402Billable live calls only: the prepaid credit balance cannot cover the call (insufficient_credits); nothing was done or charged
429Rate limit or quota exceeded

Every error has the same JSON shape, and request_id matches the X-Request-Id response header. Errors lists every code and what to do about it.

json
{
  "error": {
    "code": "invalid_request",
    "message": "What went wrong, in plain words.",
    "param": "the_field",
    "request_id": "req_a1B2c3D4e5F6g7H8"
  }
}

Examples

curl

bash
curl -X GET "https://api.joinsimplesms.com/v1/messages?limit=10" \
  -H "Authorization: Bearer $SIMPLESMS_API_KEY"

Node.js

javascript
import { SimpleSMS } from 'joinsimplesms'; // npm install joinsimplesms

const sms = new SimpleSMS(process.env.SIMPLESMS_API_KEY);

const page = await sms.messages.list({ limit: 10 });

for (const message of page.data) console.log(message.id, message.status);

Python

python
import os
from joinsimplesms import SimpleSMS  # pip install joinsimplesms

client = SimpleSMS(os.environ["SIMPLESMS_API_KEY"])

page = client.messages.list(limit=10)

for message in page["data"]:
    print(message["id"], message["status"])