Quickstart
From no account to a delivered email: create a key and make your first send.
Create an account
If you don’t already have an organization, create an account — it’s free to start, and everything you create inside it (members, templates, API keys) lives within that organization.
Create an API key
From Settings → API keys, create a key with the Send messages permission. The Create key button shows you the token exactly once — copy it right then. The authentication guide has the full detail, with screenshots of the panel.
Send your first email
The public surface — the only part of the API an external integrator calls — lives under
/v1 and reads the organization from the key itself, not from the URL. from has to name a
sender already registered in your organization — the address you signed up with is already
one, verified from the moment your account was created, so it works here with nothing further
to set up:
curl -X POST https://api.e-comms.dev/v1/email \
-H "Authorization: Bearer ek_live_<your-key>" \
-H "Content-Type: application/json" \
-d '{
"idempotencyKey": "quickstart-2026-09-19",
"to": ["you@example.com"],
"from": "you@example.com",
"content": {
"type": "raw",
"subject": "My first email",
"html": "<p>It works!</p>",
"text": "It works!"
}
}'const response = await fetch("https://api.e-comms.dev/v1/email", {
method: "POST",
headers: {
Authorization: "Bearer ek_live_<your-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({
idempotencyKey: "quickstart-2026-09-19",
to: ["you@example.com"],
from: "you@example.com",
content: {
type: "raw",
subject: "My first email",
html: "<p>It works!</p>",
text: "It works!",
},
}),
})
const body = await response.json()import requests
response = requests.post(
"https://api.e-comms.dev/v1/email",
headers={"Authorization": "Bearer ek_live_<your-key>"},
json={
"idempotencyKey": "quickstart-2026-09-19",
"to": ["you@example.com"],
"from": "you@example.com",
"content": {
"type": "raw",
"subject": "My first email",
"html": "<p>It works!</p>",
"text": "It works!",
},
},
)
body = response.json()Sending from a different address — your own domain, once you’ve verified it — is a matter of registering a new sender in Settings → Sending, no code change here.
Confirm it was sent
A 202 response means the email was admitted — not that it has arrived yet. Each addressee
shows up with its own outcome in results:
{
"results": [
{
"address": "you@example.com",
"messageId": "01a0ba31-3fe4-7cc4-a1c6-64bdaaa5d99c",
"status": "claimed"
}
]
}claimed is the only status this response can carry — the provider has not been called yet
when it is built. Keep the messageId: it is what you
retrieve to learn whether the send actually arrived, and
what correlates a webhook event with this same email. An error
carries a code from a closed set — check the
error reference to see which code answers which situation.