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);
One populated Markdown file, base URL, auth, the rules to respect, a ready client, error handling and every endpoint. Hand it to Claude Code, Cursor or Copilot and SMS365 is integrated in one pass. It's generated from the live API, so it never goes stale.
# point your assistant at the guide, that's the whole setup Integrate SMS365 into this project. Read the setup guide at https://app.sms365.com.au/v1/integration.md and follow it end to end. I'll add my API key to SMS365_API_KEY.
Or grab it in the console under Integrations → AI setup, with a key generated for you.
Give each key exactly the permissions it needs, 25 scopes across seven groups. Secrets are stored only as a hash.
SMS365 pushes message.sentlink.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.
A test key (sk_test_…) runs the whole pipeline but sends nothing and costs nothing, build and test an integration end to end before a single real text.
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": "…"
} }
}/messages.Every feature in the console is an endpoint too, documented in the same OpenAPI spec, behind the same scoped keys.
POST /v1/verify/start and /check, send a code and validate it. The code is never returned or stored.
POST /v1/ai/draft and /variations, turn a brief into a message, or a set to test.
POST /v1/appointments, a visit date fans out into scheduled reminders, idempotent on your booking reference.
GET /v1/billing/statement, opening balance, every credit and charge, running balance, closing. JSON or CSV.
POST /v1/messages/bulk, personalise from each contact, priced with a /preview first.
GET /v1/insights, send-rate, top failure reasons and link click-through, period-scoped.
/v1/schedules for recurring sends/v1/data/forget for erasure, and CSV exports for audit and contacts.
Grab a scoped key, read the reference, and send your first message.
Get an API key →