Quickstart
Your first ScaiSend email in five minutes. Assumes you already have a ScaiSend instance (managed or self-hosted) and a user account with mail.send permission.
1. Get an API key
From the admin UI: API Keys → Create. Pick a name (my-first-integration) and an environment:
Live keys (sg_live_*) send real email.
Test keys (sg_test_*) enable sandbox mode — requests are fully validated but no email is delivered.
Start with a test key. Copy it; the full secret is shown exactly once.
If you don't have admin UI access, ask your tenant admin to create one, or POST to /v3/api_keys if you have admin.api_keys permission.
2. Add and verify a sender domain
Live keys will only deliver mail from a verified sender domain. Test keys skip this check.
| curl -X POST https://scaisend.scailabs.ai/api/admin/domains \
-H "Authorization: Bearer $SCAISEND_JWT" \
-H "Content-Type: application/json" \
-d '{"domain": "mail.example.com"}'
|
ScaiSend generates a DKIM keypair and returns the DNS records you need to publish:
| {
"id": "dom_abc123",
"domain": "mail.example.com",
"verified": false,
"dkim_selector": "scaisend",
"dns_records": [
{"type": "TXT", "host": "scaisend._domainkey.mail.example.com", "value": "v=DKIM1; k=rsa; p=MIIBIj..."},
{"type": "TXT", "host": "mail.example.com", "value": "v=spf1 include:scaisend.scailabs.ai ~all"},
{"type": "TXT", "host": "_dmarc.mail.example.com", "value": "v=DMARC1; p=none; rua=mailto:dmarc@example.com"}
]
}
|
Publish the records. Then verify:
| curl -X POST https://scaisend.scailabs.ai/api/admin/domains/dom_abc123/verify \
-H "Authorization: Bearer $SCAISEND_JWT"
|
For this quickstart, you can skip the domain step if you're using a test key.
3. Send an email
Request
1
2
3
4
5
6
7
8
9
10
11
12
13 | curl -X POST https://scaisend.scailabs.ai/v3/mail/send \
-H "Authorization: Bearer $SCAISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"personalizations": [
{"to": [{"email": "you@example.com"}]}
],
"from": {"email": "hello@mail.example.com", "name": "ScaiSend Quickstart"},
"subject": "Hello from ScaiSend",
"content": [
{"type": "text/plain", "value": "It works."}
]
}'
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | import os
import httpx
resp = httpx.post(
"https://scaisend.scailabs.ai/v3/mail/send",
headers={"Authorization": f"Bearer {os.environ['SCAISEND_API_KEY']}"},
json={
"personalizations": [
{"to": [{"email": "you@example.com"}]}
],
"from": {"email": "hello@mail.example.com", "name": "ScaiSend Quickstart"},
"subject": "Hello from ScaiSend",
"content": [
{"type": "text/plain", "value": "It works."}
],
},
)
resp.raise_for_status()
print(resp.json())
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | const resp = await fetch("https://scaisend.scailabs.ai/v3/mail/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SCAISEND_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
personalizations: [
{ to: [{ email: "you@example.com" }] }
],
from: { email: "hello@mail.example.com", name: "ScaiSend Quickstart" },
subject: "Hello from ScaiSend",
content: [
{ type: "text/plain", value: "It works." }
],
}),
});
const data = await resp.json();
console.log(data);
|
Response
| {
"message_id": "msg_01HXYZ123..."
}
|
HTTP status is 202 Accepted. The email is queued; actual delivery happens in the background.
4. Check what happened
Poll the message you just sent:
| curl https://scaisend.scailabs.ai/v3/messages/msg_01HXYZ123 \
-H "Authorization: Bearer $SCAISEND_API_KEY"
|
| resp = httpx.get(
f"https://scaisend.scailabs.ai/v3/messages/{message_id}",
headers={"Authorization": f"Bearer {os.environ['SCAISEND_API_KEY']}"},
)
msg = resp.json()
print(msg["status"], msg["events"])
|
You'll see a status (queued, processing, sent, delivered, bounced, sandbox, etc.) and an event timeline:
1
2
3
4
5
6
7
8
9
10
11
12
13 | {
"id": "msg_01HXYZ123",
"status": "delivered",
"subject": "Hello from ScaiSend",
"from_email": "hello@mail.example.com",
"to_emails": ["you@example.com"],
"events": [
{"event_type": "processed", "timestamp": "2026-04-23T10:00:00Z"},
{"event_type": "delivered", "timestamp": "2026-04-23T10:00:02Z", "smtp_response": "250 2.0.0 OK"}
],
"created_at": "2026-04-23T10:00:00Z",
"delivered_at": "2026-04-23T10:00:02Z"
}
|
If you used a test key, the status will be sandbox and there will be no delivered event — that's expected.
That's it. You just sent a ScaiSend email.
5. Next: add a template
Dynamic templates let you send structured emails without rebuilding the HTML every time. Create one:
| curl -X POST https://scaisend.scailabs.ai/v3/templates \
-H "Authorization: Bearer $SCAISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "welcome-email", "generation": "dynamic"}'
|
Add a version with Handlebars markup:
| curl -X POST https://scaisend.scailabs.ai/v3/templates/d-abc123/versions \
-H "Authorization: Bearer $SCAISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "v1",
"subject": "Welcome, {{name}}",
"html_content": "<h1>Hi {{name}}!</h1><p>Your plan: {{plan}}.</p>",
"plain_content": "Hi {{name}}! Your plan: {{plan}}.",
"active": 1
}'
|
Send using the template:
1
2
3
4
5
6
7
8
9
10
11
12
13 | curl -X POST https://scaisend.scailabs.ai/v3/mail/send \
-H "Authorization: Bearer $SCAISEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"personalizations": [
{
"to": [{"email": "you@example.com"}],
"dynamic_template_data": {"name": "Ada", "plan": "Pro"}
}
],
"from": {"email": "hello@mail.example.com"},
"template_id": "d-abc123"
}'
|
See Templates for the full syntax (conditionals, iteration, helpers).
What's next