One authenticated endpoint, scoped keys you set the permissions on, and events that come to you so nothing has to poll.
Bearer-auth an API key, POST a number and a body. Add an Idempotency-Key header and a retry after a timeout can never double-send.
curl -X POST https://app.sms365.com.au/v1/messages \ -H "Authorization: Bearer sk_live_…" \ -H "Content-Type: application/json" \ -d '{"to":"0412345678","body":"Your order is on its way."}'
await fetch("https://app.sms365.com.au/v1/messages", { method: "POST", headers: { Authorization: `Bearer ${process.env.SMS365_KEY}`, "Content-Type": "application/json", "Idempotency-Key": order.id, }, body: JSON.stringify({ to: "0412345678", body: "Your order is on its way." }), });
import requests requests.post( "https://app.sms365.com.au/v1/messages", headers={"Authorization": f"Bearer {KEY}", "Idempotency-Key": order_id}, json={"to": "0412345678", "body": "Your order is on its way."}, )
$ch = curl_init("https://app.sms365.com.au/v1/messages"); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer $key", "Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode(["to" => "0412345678", "body" => "…"]), ]); curl_exec($ch);
Give each key exactly the permissions it needs — 25 scopes across seven groups. Secrets are stored only as a hash.
SMS365 pushes message.sent, link.clicked and more to your endpoint, HMAC-signed and retried — so nothing polls.
Send a key with a request and a retry returns the first result — a double-charge is impossible by design.
A spec you can read or generate a client from, and an in-app reference that never drifts from the code.
Outbound events resolve a host, refuse private and link-local addresses, and connect to the address they checked. No redirects.
A sendAt on any send, charged when scheduled and refunded on cancel — the same engine behind appointment reminders.
Subscribe an endpoint and SMS365 posts a signed event for each change — delivery, failure, cancellation, and link clicks — so your systems stay in step without polling /v1/messages.
{
"type": "message.sent",
"data": { "message": {
"id": "…",
"to": "+61412345678",
"status": "sent",
"segments": 1
} }
}{
"type": "link.clicked",
"data": { "link": {
"code": "a1B2c3D4",
"url": "https://acme.example/offer",
"messageId": "…"
} }
}Grab a scoped key, read the reference, and send your first message.
Get an API key →