saperly
Guides

Messaging

Send and list SMS from your Saperly numbers over the v2 API — consent and disclosures are enforced automatically.

Send and list SMS from your Saperly numbers. Consent and disclosures are enforced automatically on every send — see Compliance. Inbound messages are delivered to your webhook.

Endpoints

Base URL https://api.saperly.com. Authenticate with Authorization: Bearer sk_live_...; the workspace is resolved from the token.

MethodPathReturnsScope
POST/messagesMessage (201)messages:create
GET/messagesMessage[]

GET /messages accepts an optional numberId query parameter to filter by sending number.

Send an SMS

POST /messages takes the following payload:

FieldTypeNotes
fromNumberIdstringThe Saperly number to send from.
tostringRecipient in E.164 format (e.g. +15555550123).
bodystring1–1600 characters.
import { Saperly } from '@saperly/sdk'

const saperly = new Saperly({ apiKey: process.env.SAPERLY_API_KEY! })

const message = await saperly.messages.send({
  fromNumberId: 'num_...',
  to: '+15555550123',
  body: 'Your code is 123456.',
})

console.log(message.id)
curl -X POST https://api.saperly.com/messages \
  -H "Authorization: Bearer $SAPERLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fromNumberId": "num_...",
    "to": "+15555550123",
    "body": "Your code is 123456."
  }'

If the carrier rejects the send, the call fails with MessageSendFailed (502).

Outbound SMS requires consent

Sending to a peer requires recorded consent first. Saperly enforces this automatically and will block uncompliant sends — record explicit_outbound consent before messaging a number you initiated contact with. See Compliance.

List messages

const messages = await saperly.messages.list({ numberId: 'num_...' })
curl "https://api.saperly.com/messages?numberId=num_..." \
  -H "Authorization: Bearer $SAPERLY_API_KEY"

Inbound, STOP, and HELP

Inbound SMS is delivered to your configured webhook. The STOP and HELP keywords are handled automatically:

  • STOP revokes the sender's consent — subsequent outbound sends to that number are blocked.
  • HELP replies with the standard help message.

Body length and segmentation

The body limit is 1600 characters. Longer messages are segmented by the carrier into multiple SMS parts and reassembled on the recipient's device; you are billed per segment.

v1 SDK equivalents

If you're on the published @saperly/sdk / saperly v1 surface, the equivalents are:

saperly.messages.send({ lineId, to, text })
saperly.lines.sendSms(lineId, { toNumber, message })

See the Node SDK for the full v1 client.

On this page