send0
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

ParameterTypeRequiredDescription
fromstringYesSender address (must be verified domain)
tostring | string[]YesRecipient(s), max 50
subjectstringYesEmail subject line
htmlstringNoHTML body
textstringNoPlain text body
templatestringNoTemplate ID to use
dataobjectNoTemplate variables
ccstring | string[]NoCC recipients
bccstring | string[]NoBCC recipients
replyTostringNoReply-to address
attachmentsarrayNoFile attachments (max 10, 25MB total)
tagsobjectNoKey-value tags
metadataobjectNoCustom metadata (max 4KB)
categorystringNotransactional (default) or marketing
scheduledAtDateNoSchedule send (max 30 days)
idempotencyKeystringNoPrevent duplicate sends

Note: One of html, text, or template is required. Cannot combine template with html.

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

ParameterTypeDefaultDescription
limitnumber20Results per page (max 100)
cursorstringPagination cursor
statusstringFilter by status
tagstringFilter by tag (key:value format)
batch_idstringFilter 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

ParameterTypeRequiredDescription
fromstringYesSender address
subjectstringYesEmail subject
htmlstringNoHTML body
textstringNoPlain text body
templatestringNoTemplate ID
templateDataobjectNoDefault template variables
categorystringNotransactional or marketing
recipientsarrayYesArray of recipients (max 100)

Each recipient object:

ParameterTypeRequiredDescription
tostring | string[]YesRecipient address(es)
variablesobjectNoPer-recipient template variables
tagsobjectNoPer-recipient tags
metadataobjectNoPer-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_xxxx

Python 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)  # 2

Go 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) // 2

curl

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:

StatusDescription
queuedEmail accepted, waiting to send
scheduledScheduled for future delivery
sendingCurrently being sent
sentSent to mail server
deliveredDelivered to recipient
openedRecipient opened the email
clickedRecipient clicked a link
bouncedEmail bounced (hard or soft)
complainedRecipient marked as spam
failedDelivery failed
cancelledCancelled before sending