Sending SMS
Send one message or many with the same endpoint shape. Conerix handles encoding, segmentation, routing, and fallback — you handle the content.
Send a single message
post /v1/messages/send
curl https://conerix.com/api/v1/messages/send \
-H "Authorization: Bearer ds_live_..." \
-H "Content-Type: application/json" \
-d '{
"to": "+12025550143",
"from": "Conerix",
"body": "Your verification code is 482194",
"reference": "signup-9214"
}'
const res = await fetch("https://conerix.com/api/v1/messages/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CONERIX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+12025550143",
from: "Conerix",
body: "Your verification code is 482194",
reference: "signup-9214",
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`Conerix error: ${err.error.code} — ${err.error.message}`);
}
const { data: message } = await res.json();
console.log(message.id, message.status);
import os, requests
resp = requests.post(
"https://conerix.com/api/v1/messages/send",
headers={
"Authorization": f"Bearer {os.environ['CONERIX_API_KEY']}",
"Content-Type": "application/json",
},
json={
"to": "+12025550143",
"from": "Conerix",
"body": "Your verification code is 482194",
"reference": "signup-9214",
},
timeout=15,
)
resp.raise_for_status()
message = resp.json()["data"]
print(message["id"], message["status"])
Parameters
| Field | Type | Description |
|---|---|---|
to required | string | Recipient in E.164 format, e.g. +12025550143. |
from required | string | Approved sender ID. Up to 11 alphanumeric characters, or a numeric long/short code. |
body required | string | Message body, up to 1,600 characters. Long messages are auto-segmented. |
route_id | integer | Optional route assigned to your account. If omitted, Conerix selects the optimal path. |
reference | string | Your correlation id, echoed back in webhooks. |
Response
On success returns 201 Created with the new message object:
{
"success": true,
"data": {
"id": "msg_VyB2pNkX0wnA9aTrLqDh1Z3Fc",
"object": "message",
"to": "+12025550143",
"from": "Conerix",
"body": "Your verification code is 482194",
"status": "sent",
"cost": 0.0500,
"currency": "USD",
"route_id": 12,
"provider_message_id": "SM3f2c...",
"attempts": 1,
"created_at": "2026-05-12T11:34:21+00:00",
"sent_at": "2026-05-12T11:34:21+00:00"
},
"meta": { "request_id": "req_dXp9k..." }
}
How routing works. Conerix routes each message through your assigned delivery paths.
Retryable upstream errors trigger automatic failover; hard errors (validation, billing, blocklist) stop immediately
so you don't get duplicate sends.
Send to many recipients
post /v1/messages/bulk
Send the same body to up to 1,000 recipients in a single request. Each recipient is created as an independent message and reported back in the response.
curl https://conerix.com/api/v1/messages/bulk \
-H "Authorization: Bearer ds_live_..." \
-H "Content-Type: application/json" \
-d '{
"from": "Conerix",
"recipients": ["+12025550143", "+447700900100", "+4748640969"],
"body": "Tickets for tonight are still available — bit.ly/lens-friday"
}'
const res = await fetch("https://conerix.com/api/v1/messages/bulk", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CONERIX_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "Conerix",
recipients: ["+12025550143", "+447700900100", "+4748640969"],
body: "Tickets for tonight are still available — bit.ly/lens-friday",
}),
});
const { data } = await res.json();
console.log(`${data.sent} sent, ${data.failed} failed`);
import os, requests
resp = requests.post(
"https://conerix.com/api/v1/messages/bulk",
headers={"Authorization": f"Bearer {os.environ['CONERIX_API_KEY']}"},
json={
"from": "Conerix",
"recipients": ["+12025550143", "+447700900100", "+4748640969"],
"body": "Tickets for tonight are still available — bit.ly/lens-friday",
},
)
data = resp.json()["data"]
print(f"{data['sent']} sent, {data['failed']} failed")
Returns a bulk_result:
{
"success": true,
"data": {
"object": "bulk_result",
"total": 3,
"sent": 3,
"failed": 0,
"messages": [
{ "id": "msg_...", "to": "+12025550143", "status": "sent", "cost": 0.05 },
{ "id": "msg_...", "to": "+447700900100", "status": "sent", "cost": 0.05 },
{ "id": "msg_...", "to": "+4748640969", "status": "sent", "cost": 0.05 }
]
},
"meta": { "request_id": "req_dXp9k..." }
}
Per-recipient errors. A bulk request can partially succeed. Always inspect each
item's
status and error field instead of trusting the top-level HTTP
code alone.
Segmentation & encoding
- GSM-7 messages fit 160 chars per segment, then 153 per additional segment.
- Unicode (UCS-2) — when the body contains any character outside GSM-7 — fits 70 chars per segment, then 67 per additional segment.
- Each segment is billed individually. The
costfield reflects the total.
Best practices
- Use E.164 phone numbers (with the leading
+). Local formats are rejected. - Pre-validate high-volume lists with HLR lookup before bulk sends.
- Include an opt-out string on marketing messages — "Reply STOP to unsubscribe" — per local regulation.
- Set a
referenceso you can correlate sends with your own system.