Conerix

Conerix API

Home
Browse topics

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

FieldTypeDescription
to requiredstringRecipient in E.164 format, e.g. +12025550143.
from requiredstringApproved sender ID. Up to 11 alphanumeric characters, or a numeric long/short code.
body requiredstringMessage body, up to 1,600 characters. Long messages are auto-segmented.
route_idintegerOptional route assigned to your account. If omitted, Conerix selects the optimal path.
referencestringYour 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 cost field 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 reference so you can correlate sends with your own system.