Send a text
POST /sms
One text to a US or Canadian phone, now or later.
Headers
Idempotency-KeystringMakes the send exactly-once for 24 hours. Derive it from what you are sending, such as an order ID.
Body
tostringRequiredA US or Canadian phone in E.164 form,
+14155550123.textstringRequiredThe text. Required unless
media_urlshas an image. Over 10 messages is422 validation_error.fromstringOne of your active numbers, or its ID. Absent: your default number for the destination's country.
categorystringtransactional(the default) ormarketing. A marketing text needs SMS consent and keeps to quiet hours.
3 more fields (media_urls, scheduled_at, tags)
media_urlsstring[]Up to 10 images for a picture message, US numbers only. Billed as 3 messages.
scheduled_atstringAn ISO 8601 time up to 30 days ahead.
tagsobjectString values you want back on the text and its webhooks.
Request
curl -X POST "https://api.rasket.com/sms" \
-H "Authorization: Bearer $RASKET_API_KEY" \
-H "User-Agent: acme-billing/1.0" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-shipped" \
-d '{
"to": "+14155550123",
"text": "Your order #1042 has shipped.",
"category": "transactional",
"tags": {
"order": "1042"
}
}'const response = await fetch("https://api.rasket.com/sms", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RASKET_API_KEY}`,
"User-Agent": "acme-billing/1.0",
"Content-Type": "application/json",
"Idempotency-Key": "order-1042-shipped",
},
body: JSON.stringify({
to: "+14155550123",
text: "Your order #1042 has shipped.",
category: "transactional",
tags: {
order: "1042"
}
}),
});
const { id } = await response.json();import os
import requests
response = requests.post(
"https://api.rasket.com/sms",
headers={
"Authorization": f"Bearer {os.environ['RASKET_API_KEY']}",
"User-Agent": "acme-billing/1.0",
"Idempotency-Key": "order-1042-shipped",
},
json={
"to": "+14155550123",
"text": "Your order #1042 has shipped.",
"category": "transactional",
"tags": {
"order": "1042"
}
},
)
id = response.json()["id"]Response 200
{
"object": "sms",
"id": "01928c3e-5b7a-7c1e-9a2f-3d4e5f60718a",
"status": "queued",
"from": "+18335550199",
"to": "+14155550123",
"text": "Acme: Your order #1042 has shipped.",
"category": "transactional",
"encoding": "gsm7",
"segments": 1,
"price_each": "0.015",
"cost": "0.015",
"currency": "usd",
"included": true,
"scheduled_at": null,
"created_at": "2026-10-19T20:41:00.000Z",
"tags": {
"order": "1042"
}
}segmentsis how many messages the text is billed as: up to 160 characters each, or 70 with an emoji or another special character.- A destination outside the US and Canada is
422 unsupported_destination. - The month's texts used up is
429 sms_quota_exceeded. It is never worth retrying. - Until a number is approved, texts go only to your verified test phones, from our shared test number, with
[Test]in front.