DEVELOPERS
AtomMatrix API
One REST API for the whole platform — send an SMS, place a call, verify a phone number, deliver an email, or run an AI agent, all with the same authentication, conventions, and webhooks.
The API is organized around predictable, resource-oriented URLs. It accepts JSON request bodies, returns JSON responses, and uses standard HTTP verbs, status codes, and authentication. Every response includes a request ID so support can trace exactly what happened. If you can make an HTTPS request, you can use AtomMatrix — the official SDKs are thin wrappers over the same endpoints documented here.
Base URL & versioning
All requests go to a single base URL over HTTPS. Plain HTTP is not supported.
https://api.atommatrix.ai/v1
The API is versioned in the path (/v1). We add fields and endpoints without bumping the version; those are considered backward-compatible and your integration should ignore unknown fields. Breaking changes ship under a new version with advance notice and an overlap period. We recommend pinning to /v1 and reading the conventions below so additive changes never break you.
Authentication
Authenticate every request with an API key sent as a bearer token in the Authorization header. You create and rotate keys in the AtomMatrix console under Settings → API keys.
Authorization: Bearer sk_live_3f9c...your_key
Keys come in two flavors, distinguished by prefix:
sk_test_…— test keys. Requests are fully processed by the API but nothing is actually sent to a carrier or inbox, and you aren't billed. Use these in development and CI.sk_live_…— live keys. Real messages, real calls, real charges.
Requests without a valid key return 401 Unauthorized. See Errors & limits for the full list.
Quickstart: send your first message
The fastest way to see the API work is to send an SMS with a test key. Replace the key and the to number, then run it.
cURL
curl https://api.atommatrix.ai/v1/messages \
-H "Authorization: Bearer sk_test_your_key" \
-H "Content-Type: application/json" \
-d '{
"to": "+14155550123",
"from": "ATOMMTX",
"channel": "sms",
"body": "Your AtomMatrix code is 481920"
}'
Node.js
const res = await fetch("https://api.atommatrix.ai/v1/messages", {
method: "POST",
headers: {
"Authorization": "Bearer sk_test_your_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
to: "+14155550123",
from: "ATOMMTX",
channel: "sms",
body: "Your AtomMatrix code is 481920"
})
});
const message = await res.json();
console.log(message.id, message.status);
Python
import requests
res = requests.post(
"https://api.atommatrix.ai/v1/messages",
headers={"Authorization": "Bearer sk_test_your_key"},
json={
"to": "+14155550123",
"from": "ATOMMTX",
"channel": "sms",
"body": "Your AtomMatrix code is 481920",
},
)
print(res.json()["id"], res.json()["status"])
The response
A successful call returns 201 Created with the message resource. The message starts as queued; its final state arrives later by webhook or by polling the message.
{
"id": "msg_01HN9K7QophZ8",
"object": "message",
"channel": "sms",
"to": "+14155550123",
"from": "ATOMMTX",
"status": "queued",
"segments": 1,
"created_at": "2026-07-07T12:00:00Z"
}
From here, head to the Messaging reference for every field, or explore Voice, Verification, Email, and AI agents.
Conventions
These rules hold across every endpoint, so once you learn them for messaging they apply everywhere.
Requests & responses
- Send JSON bodies with
Content-Type: application/json. Responses are always JSON. - Every response carries an
X-Request-Idheader. Include it when you contact support — it lets us find the exact call in seconds. - Resource IDs are prefixed by type (
msg_,call_,vrf_,eml_,cnv_) so an ID is always self-describing in logs.
Timestamps
All timestamps are UTC, formatted as RFC 3339 / ISO 8601 (for example 2026-07-07T12:00:00Z). Send timestamps in the same format.
Phone numbers
Phone numbers are always in E.164 format — a leading +, country code, then the national number, no spaces or dashes (for example +14155550123). Numbers in other formats are rejected with a 422.
Idempotency
Write requests (anything that creates a resource) accept an Idempotency-Key header. Send a unique key per logical operation; if the same key is replayed within 24 hours — say, after a network timeout and retry — the API returns the original result instead of creating a duplicate. Use a UUID per attempt.
Idempotency-Key: 5f2b9c1e-9d3a-4b8e-8a1c-2f6d0e4a7b31
Pagination
List endpoints are cursor-paginated. Pass limit (1–100, default 25) and, to page forward, starting_after set to the last ID you saw. Responses include has_more and the data array.
GET /v1/messages?limit=50&starting_after=msg_01HZ...
{
"object": "list",
"data": [ { "id": "msg_01J0...", "object": "message" } ],
"has_more": true
}
Errors & rate limits
Errors use standard HTTP status codes and a consistent JSON body with a machine-readable code. Requests are rate limited per key, with limits returned in response headers. Both are documented in full on Errors & limits.