API Reference
Emails
Send, retrieve, list, and cancel emails.
Send an email
POST /v1/emails
Send an email to one or more recipients.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender address (must be verified domain) |
to | string | string[] | Yes | Recipient(s), max 50 |
subject | string | Yes | Email subject line |
html | string | No | HTML body |
text | string | No | Plain text body |
template | string | No | Template ID to use |
data | object | No | Template variables |
cc | string | string[] | No | CC recipients |
bcc | string | string[] | No | BCC recipients |
replyTo | string | No | Reply-to address |
attachments | array | No | File attachments (max 10, 25MB total) |
tags | object | No | Key-value tags |
metadata | object | No | Custom metadata (max 4KB) |
category | string | No | transactional (default) or marketing |
scheduledAt | Date | No | Schedule send (max 30 days) |
idempotencyKey | string | No | Prevent duplicate sends |
Note: One of
html,text, ortemplateis required. Cannot combinetemplatewithhtml.
TypeScript SDK
const email = await send0.emails.send({
from: 'Acme <hello@acme.com>',
to: 'user@example.com',
subject: 'Welcome to Acme!',
html: '<h1>Welcome</h1><p>Thanks for joining.</p>',
tags: { category: 'onboarding' },
});Python SDK
email = client.emails.send(
from_address="Acme <hello@acme.com>",
to="user@example.com",
subject="Welcome to Acme!",
html="<h1>Welcome</h1><p>Thanks for joining.</p>",
tags={"category": "onboarding"},
)Go SDK
email, err := client.Emails.Send(ctx, &send0.SendEmailParams{
From: "Acme <hello@acme.com>",
To: []string{"user@example.com"},
Subject: "Welcome to Acme!",
HTML: "<h1>Welcome</h1><p>Thanks for joining.</p>",
Tags: map[string]string{"category": "onboarding"},
})curl
curl -X POST https://api.send0.dev/v1/emails \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <hello@acme.com>",
"to": "user@example.com",
"subject": "Welcome to Acme!",
"html": "<h1>Welcome</h1><p>Thanks for joining.</p>",
"tags": { "category": "onboarding" }
}'Response (201)
{
"id": "em_2xKq9mNpLvRw",
"object": "email",
"status": "queued",
"from": "Acme <hello@acme.com>",
"to": ["user@example.com"],
"subject": "Welcome to Acme!",
"created_at": "2026-04-12T10:30:00Z",
"scheduled_at": null,
"test_mode": false
}With attachments
const email = await send0.emails.send({
from: 'billing@acme.com',
to: 'user@example.com',
subject: 'Your Invoice',
html: '<p>Please find your invoice attached.</p>',
attachments: [
{
filename: 'invoice.pdf',
content: base64EncodedContent,
contentType: 'application/pdf',
},
],
});With template
const email = await send0.emails.send({
from: 'hello@acme.com',
to: 'user@example.com',
subject: 'Welcome!',
template: 'tmpl_welcome123',
data: { name: 'Jane', company: 'Acme' },
});Get an email
GET /v1/emails/:id
Retrieve a single email by its ID.
TypeScript SDK
const email = await send0.emails.get('em_2xKq9mNpLvRw');Python SDK
email = client.emails.get("em_2xKq9mNpLvRw")Go SDK
email, err := client.Emails.Get(ctx, "em_2xKq9mNpLvRw")curl
curl https://api.send0.dev/v1/emails/em_2xKq9mNpLvRw \
-H "Authorization: Bearer sk_live_..."Response (200)
{
"id": "em_2xKq9mNpLvRw",
"object": "email",
"status": "delivered",
"from": "hello@acme.com",
"to": ["user@example.com"],
"cc": null,
"bcc": null,
"subject": "Welcome to Acme!",
"html": "<h1>Welcome</h1>",
"text": null,
"tags": { "category": "onboarding" },
"created_at": "2026-04-12T10:30:00Z",
"scheduled_at": null,
"sent_at": "2026-04-12T10:30:01Z",
"delivered_at": "2026-04-12T10:30:03Z",
"opened_at": "2026-04-12T10:35:00Z",
"test_mode": false
}List emails
GET /v1/emails
Retrieve a paginated list of emails.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 20 | Results per page (max 100) |
cursor | string | — | Pagination cursor |
status | string | — | Filter by status |
tag | string | — | Filter by tag (key:value format) |
batch_id | string | — | Filter by batch ID |
TypeScript SDK
const { data, has_more, cursor } = await send0.emails.list({
limit: 20,
status: 'delivered',
});Python SDK
result = client.emails.list(limit=20, status="delivered")
for email in result.data:
print(email.id, email.status)Go SDK
list, err := client.Emails.List(ctx, &send0.ListEmailsParams{
Limit: 20,
Status: "delivered",
})
for _, email := range list.Data {
fmt.Println(email.ID, email.Status)
}curl
curl "https://api.send0.dev/v1/emails?limit=20&status=delivered" \
-H "Authorization: Bearer sk_live_..."Response (200)
{
"data": [...],
"has_more": true,
"cursor": "cur_abc123"
}Cancel a scheduled email
DELETE /v1/emails/:id
Cancel an email that has been scheduled for future delivery. Only works for emails with status scheduled.
TypeScript SDK
await send0.emails.cancel('em_2xKq9mNpLvRw');Python SDK
client.emails.cancel("em_2xKq9mNpLvRw")Go SDK
err := client.Emails.Cancel(ctx, "em_2xKq9mNpLvRw")curl
curl -X DELETE https://api.send0.dev/v1/emails/em_2xKq9mNpLvRw \
-H "Authorization: Bearer sk_live_..."Batch send
POST /v1/emails/batch
Send an email to multiple recipients in a single API call. Each recipient can have individual variables, tags, and metadata. Max 100 recipients per batch.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender address |
subject | string | Yes | Email subject |
html | string | No | HTML body |
text | string | No | Plain text body |
template | string | No | Template ID |
templateData | object | No | Default template variables |
category | string | No | transactional or marketing |
recipients | array | Yes | Array of recipients (max 100) |
Each recipient object:
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | string[] | Yes | Recipient address(es) |
variables | object | No | Per-recipient template variables |
tags | object | No | Per-recipient tags |
metadata | object | No | Per-recipient metadata |
TypeScript SDK
const batch = await send0.emails.batch({
from: 'hello@acme.com',
subject: 'Monthly Update',
template: 'tmpl_monthly',
recipients: [
{ to: 'jane@example.com', variables: { name: 'Jane' } },
{ to: 'john@example.com', variables: { name: 'John' } },
],
});
console.log(batch.count); // 2
console.log(batch.emails[0].id); // em_xxxxPython SDK
batch = client.emails.batch(
from_address="hello@acme.com",
subject="Monthly Update",
template="tmpl_monthly",
recipients=[
{"to": "jane@example.com", "variables": {"name": "Jane"}},
{"to": "john@example.com", "variables": {"name": "John"}},
],
)
print(batch.count) # 2Go SDK
batch, err := client.Emails.Batch(ctx, &send0.SendBatchParams{
From: "hello@acme.com",
Subject: "Monthly Update",
Template: "tmpl_monthly",
Recipients: []send0.BatchRecipient{
{To: []string{"jane@example.com"}, Variables: map[string]any{"name": "Jane"}},
{To: []string{"john@example.com"}, Variables: map[string]any{"name": "John"}},
},
})
fmt.Println(batch.Count) // 2curl
curl -X POST https://api.send0.dev/v1/emails/batch \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"from": "hello@acme.com",
"subject": "Monthly Update",
"template": "tmpl_monthly",
"recipients": [
{ "to": "jane@example.com", "variables": { "name": "Jane" } },
{ "to": "john@example.com", "variables": { "name": "John" } }
]
}'Response (201)
{
"object": "email.batch",
"id": "batch_2xKq9mNpLvRw",
"count": 2,
"emails": [
{
"id": "em_abc123",
"object": "email",
"status": "queued",
"from": "hello@acme.com",
"to": ["jane@example.com"],
"subject": "Monthly Update",
"created_at": "2026-04-12T10:30:00Z",
"batch_id": "batch_2xKq9mNpLvRw"
},
{
"id": "em_def456",
"object": "email",
"status": "queued",
"from": "hello@acme.com",
"to": ["john@example.com"],
"subject": "Monthly Update",
"created_at": "2026-04-12T10:30:00Z",
"batch_id": "batch_2xKq9mNpLvRw"
}
]
}Email status lifecycle
An email progresses through the following statuses:
| Status | Description |
|---|---|
queued | Email accepted, waiting to send |
scheduled | Scheduled for future delivery |
sending | Currently being sent |
sent | Sent to mail server |
delivered | Delivered to recipient |
opened | Recipient opened the email |
clicked | Recipient clicked a link |
bounced | Email bounced (hard or soft) |
complained | Recipient marked as spam |
failed | Delivery failed |
cancelled | Cancelled before sending |