# Getting Started

{/* api-kit:generated */}

This guide walks you through authenticating with the API and making your first request.

## Base URL

All API requests go to:

```
https://api.cakemail.dev
```

## Authentication

The API uses OAuth2 password grant. Exchange your credentials for an access token:

```bash
curl -X POST https://api.cakemail.dev/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=password&username=YOUR_EMAIL&password=YOUR_PASSWORD"
```

The response includes an `access_token` and `refresh_token`:

```json
{
  "access_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 432000,
  "refresh_token": "..."
}
```

Use the access token in subsequent requests:

```bash
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  https://api.cakemail.dev/campaigns
```

## Your first API call

List your campaigns:

```bash
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  "https://api.cakemail.dev/campaigns?page=1&per_page=10"
```

## Using MCP with AI assistants

If you're using an AI coding assistant like Claude Code, you can connect directly to the API via MCP servers instead of writing HTTP calls manually.


```bash
claude mcp add exec-mcp \
  --transport http \
  https://exec.mcp.cakemail.com/api/mcp \
  --header "Authorization: Basic $(echo -n 'you@example.com:your-password' | base64)"
```

Once connected, your AI assistant can call API operations directly — list campaigns, create contacts, check analytics — without you writing any code.

[Learn more about MCP servers →](/tools/mcp/overview)


## AI-powered development

The Cakemail OpenAPI spec is indexed on [Context7](https://context7.com), so AI coding assistants that support it can pull up-to-date API documentation on demand. You can also connect any MCP-compatible assistant directly to Cakemail's API servers.

[Learn more about AI assistant integrations →](/tools/ai-assistants)

## API Reference

Explore all available endpoints in the [interactive API reference](/api).

## Next steps

- [Managing contacts](/guides/managing-contacts) — Create lists and add contacts
- [Sending campaigns](/guides/sending-campaigns) — Create and send your first email campaign
- [Using webhooks](/guides/using-webhooks) — Get notified about events in real time

---

# Managing Contacts

Contacts are organized into lists. Before adding contacts, you need at least one list.

## Create a list

```bash
curl -X POST https://api.cakemail.dev/lists \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Newsletter Subscribers"}'
```

The response includes a `list_id` you'll use for all contact operations.

## Add a contact

```bash
curl -X POST https://api.cakemail.dev/lists/{list_id}/contacts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "subscriber@example.com"}'
```

## List contacts

```bash
curl "https://api.cakemail.dev/lists/{list_id}/contacts?page=1&per_page=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Use `page` and `per_page` for pagination. Results are sorted by creation date.

## Update a contact

```bash
curl -X PATCH https://api.cakemail.dev/lists/{list_id}/contacts/{contact_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"custom_attributes": [{"name": "first_name", "value": "Jane"}]}'
```

## Delete a contact

```bash
curl -X DELETE https://api.cakemail.dev/lists/{list_id}/contacts/{contact_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Accept anti-spam policy

You must accept the anti-spam policy for a list before you can send to it. This is a one-time step per list.

```bash
curl -X POST https://api.cakemail.dev/lists/{list_id}/accept-policy \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Import contacts in bulk

Import up to 1,000 contacts per request using the import endpoint:

```bash
curl -X POST https://api.cakemail.dev/lists/{list_id}/contacts/import \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"contacts": [{"email": "alice@example.com"}, {"email": "bob@example.com"}]}'
```

For larger lists, split your contacts into batches of 1,000 and send multiple requests.

## Unsubscribe a contact

```bash
curl -X POST https://api.cakemail.dev/lists/{list_id}/contacts/{contact_id}/unsubscribe \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Filtering and pagination

When listing contacts, use query parameters to control results:

- `page` — page number (starts at 1)
- `per_page` — number of results per page
- `sort` — sort field and direction (e.g. `email:asc`)
- `filter` — filter by field value (e.g. `status:active`)

```bash
curl "https://api.cakemail.dev/lists/{list_id}/contacts?page=1&per_page=50&sort=email:asc&filter=status:active" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Tags

Tag contacts for flexible grouping:

```bash
curl -X POST https://api.cakemail.dev/lists/{list_id}/contacts/tag \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"contact_ids": [123, 456], "tags": ["vip", "newsletter"]}'
```

## Using MCP

With the Execution MCP connected, your AI assistant can manage contacts directly:

- `contacts` tool with operation `list` — list contacts in a list
- `contacts` tool with operation `create` — add a new contact
- `tags` tool with operation `list` — browse available tags

See [MCP Servers](/tools/mcp/overview) for connection instructions.

---

# Sending Campaigns

A campaign goes through a lifecycle: create → configure content → test → schedule → send. Here's how to do each step via the API.

## Create a campaign

```bash
curl -X POST https://api.cakemail.dev/campaigns \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "April Newsletter"}'
```

The response includes a `campaign_id` and a status of `draft`.

## Configure the campaign

Update the campaign with sender, audience, and content:

```bash
curl -X PATCH https://api.cakemail.dev/campaigns/{campaign_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sender": {"sender_id": 123},
    "audience": {"list_id": 456},
    "content": {
      "subject": "Our April Newsletter",
      "html": "<html><body><h1>Hello!</h1><p>Welcome to our newsletter.</p></body></html>"
    }
  }'
```

You need a confirmed sender. See [the API reference](/api) for all available fields.

## Preview the campaign

Render the campaign to see what it will look like:

```bash
curl "https://api.cakemail.dev/campaigns/{campaign_id}/render" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Send a test email

Before sending to your full audience, send a test:

```bash
curl -X POST https://api.cakemail.dev/campaigns/{campaign_id}/send-test \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"test_email": "you@example.com"}'
```

## Schedule the campaign

```bash
curl -X POST https://api.cakemail.dev/campaigns/{campaign_id}/schedule \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"scheduled_for": "2026-04-15T10:00:00Z"}'
```

Omit `scheduled_for` to send immediately.

## Campaign lifecycle

| Status | Meaning |
|--------|---------|
| `draft` | Campaign is being built. Can be edited. |
| `scheduled` | Campaign is scheduled for sending. |
| `delivering` | Campaign is being sent. |
| `delivered` | Campaign has been fully sent. |

Only `draft` campaigns can be edited or deleted.

## List campaigns

Retrieve your campaigns with pagination and optional status filtering:

```bash
curl "https://api.cakemail.dev/campaigns?page=1&per_page=50&status=delivered" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

| Parameter | Description |
|-----------|-------------|
| `page` | Page number (default: 1) |
| `per_page` | Results per page (default: 50) |
| `status` | Filter by status: `draft`, `scheduled`, or `delivered` |

## Campaign reports

Get delivery statistics for a campaign:

```bash
curl "https://api.cakemail.dev/reports/campaigns/{campaign_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

The response includes aggregate counts: `sent`, `opened`, `clicked`, `bounced`, and `unsubscribed`.

## Campaign logs

Get per-recipient activity for a campaign:

```bash
curl "https://api.cakemail.dev/logs/campaigns/{campaign_id}?page=1&per_page=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Results are paginated. Use `page` and `per_page` to navigate through the activity log.

## Using MCP

With the Execution MCP, your AI assistant can manage the full campaign lifecycle:

- `campaigns` tool with operation `list` — view your campaigns
- `campaigns` tool with operation `create` — start a new campaign
- `campaigns` tool with operation `schedule` — schedule for delivery

---

# Managing Users

Users represent team members on your account. You can invite new users, assign roles, and manage access through the API.

## Create a user

```bash
curl -X POST https://api.cakemail.dev/users \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane Smith", "email": "jane@example.com", "role": "manager"}'
```

The response includes a `user_id` you'll use for all subsequent operations on this user.

## List users

```bash
curl "https://api.cakemail.dev/users?page=1&per_page=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Use `page` and `per_page` for pagination. Results are sorted by creation date.

## Update a user

```bash
curl -X PATCH https://api.cakemail.dev/users/{user_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"role": "admin", "name": "Jane Doe"}'
```

## Suspend a user

```bash
curl -X POST https://api.cakemail.dev/users/{user_id}/suspend \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Suspended users cannot log in or access the account until unsuspended.

## Unsuspend a user

```bash
curl -X POST https://api.cakemail.dev/users/{user_id}/unsuspend \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Delete a user

```bash
curl -X DELETE https://api.cakemail.dev/users/{user_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Using MCP

With the Execution MCP connected, your AI assistant can manage users directly:

- `users` tool with operation `list` — list users on the account
- `users` tool with operation `create` — invite a new user
- `users` tool with operation `suspend` — suspend a user

See [MCP Servers](/tools/mcp/overview) for connection instructions.

---

# Using Templates

Templates let you create reusable email designs. Build a template once, then use it across multiple campaigns.

## Create a template

```bash
curl -X POST https://api.cakemail.dev/templates \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Monthly Newsletter",
    "content": {
      "html": "<html><body><h1>{{title}}</h1><p>{{body}}</p></body></html>",
      "text": "{{title}}\n\n{{body}}"
    }
  }'
```

## List templates

```bash
curl "https://api.cakemail.dev/templates?page=1&per_page=25" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Render a template

Preview how a template will look:

```bash
curl "https://api.cakemail.dev/templates/{template_id}/render" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Use a template in a campaign

When creating or updating a campaign, reference a template by ID instead of providing inline HTML:

```bash
curl -X PATCH https://api.cakemail.dev/campaigns/{campaign_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": {"template_id": 789}}'
```

## Update a template

```bash
curl -X PATCH https://api.cakemail.dev/templates/{template_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated Newsletter",
    "content": {
      "html": "<html><body><h1>{{title}}</h1><p>{{body}}</p><footer>{{footer}}</footer></body></html>"
    }
  }'
```

## Delete a template

```bash
curl -X DELETE https://api.cakemail.dev/templates/{template_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Use a template with transactional emails

When sending a transactional email via the Email API, reference a template by ID and pass custom attributes to populate its merge tags:

```bash
curl -X POST https://api.cakemail.dev/v2/emails \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "recipient@example.com",
    "sender": {
      "name": "My App",
      "email": "noreply@myapp.com"
    },
    "content": {
      "subject": "Your Monthly Update",
      "template_id": 789
    },
    "custom_attributes": {
      "title": "April Newsletter",
      "body": "Here is your monthly update.",
      "footer": "© 2026 Your Company"
    }
  }'
```

---

# Using Webhooks

Webhooks notify your application in real time when events happen — a contact subscribes, an email is opened, a campaign is sent.

## Create a webhook

```bash
curl -X POST https://api.cakemail.dev/webhooks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/cakemail",
    "events": ["Contact.Added", "Email.Opened", "Campaign.Sent"],
    "rate_limit": 100,
    "rate_limit_period": "hour"
  }'
```

The response includes a `webhook_id` and a `secret` for signature verification.

## Available events

| Event | Triggered when |
|-------|---------------|
| `Contact.Added` | A contact is added to a list |
| `Contact.Unsubscribed` | A contact unsubscribes |
| `Email.Opened` | A recipient opens an email |
| `Email.Clicked` | A recipient clicks a link |
| `Email.Bounced` | An email bounces |
| `Campaign.Sent` | A campaign finishes sending |
| `Campaign.Scheduled` | A campaign is scheduled |

See the [API reference](/api) for the full list.

## Retrieve webhook details

Fetch a webhook's configuration, including its `secret` and `hash_function`, using its ID:

```bash
curl "https://api.cakemail.dev/webhooks/{webhook_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

The response contains the webhook's URL, subscribed events, rate limit settings, secret key, and hash function used for signature verification.

## Verify webhook signatures

Each webhook request includes a signature header. Verify it to ensure the request is authentic:

```javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('base64');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}
```

## Webhook payload structure

When an event fires, Cakemail sends a `POST` request to your endpoint. The request includes a signature header and a JSON body:

**Header:**

```
X-Cakemail-Signature: BASE64_ENCODED_HMAC_SIGNATURE
```

**Body:**

```json
{
  "event": "Email.Opened",
  "timestamp": "2026-04-10T14:32:00Z",
  "data": {
    "email_id": "e_abc123",
    "contact_id": "c_def456",
    "campaign_id": "cmp_ghi789",
    "list_id": "lst_jkl012",
    "email_address": "recipient@example.com",
    "opened_at": "2026-04-10T14:32:00Z"
  }
}
```

The exact fields inside `data` vary by event type. Refer to the [API reference](/api) for the schema of each event.

## List your webhooks

```bash
curl "https://api.cakemail.dev/webhooks" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Archive a webhook

Webhooks can't be deleted, but they can be archived (disabled):

```bash
curl -X POST https://api.cakemail.dev/webhooks/{webhook_id}/archive \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

To re-enable, use the `unarchive` endpoint.

## Limitations

Only Next-gen API events are supported. Legacy API events are not forwarded to webhooks.

---

# Automating Emails with Workflows

<Callout type="caution" title="Feature in development">
The Automation API is being updated. Some details on this page may change. Contact support for the latest status.
</Callout>

The Automation API lets you build email sequences triggered by subscriber actions. When someone subscribes to a list, you can automatically send a welcome email, follow up three days later, and continue based on engagement.

## Concepts

### Workflows

A workflow is an ordered sequence of actions triggered by an event on a contact list. Workflows start with a trigger (e.g., a new subscription) and execute actions over time.

### Actions

An action performs a task — currently, sending an email. Actions can be chained: each action references a parent and executes after a delay and/or condition (e.g., parent email was opened or clicked).

## Create a workflow

Create a workflow by specifying a target audience (list) and a trigger event:

```bash
curl -X POST https://api.cakemail.dev/workflows \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Welcome series",
    "goal": "Onboard new subscribers",
    "trigger": "subscribed",
    "audience": { "list_id": LIST_ID }
  }'
```

The response includes a workflow ID. Workflows are **inactive by default** so you can add actions before they start executing.

## Add actions

### First action (no parent)

The first action has no parent — it's triggered directly by the workflow:

```bash
curl -X POST https://api.cakemail.dev/workflows/WORKFLOW_ID/actions \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Welcome email",
    "type": "email",
    "condition": "none",
    "delay": 0,
    "email_settings": {
      "sender": { "id": SENDER_ID },
      "tracking": { "opens": true, "clicks_html": true, "clicks_text": true },
      "content": {
        "subject": "Welcome!",
        "html": "<html><body>Thanks for subscribing.</body></html>",
        "type": "html",
        "encoding": "utf-8"
      }
    }
  }'
```

### Chained action (with parent and delay)

Subsequent actions reference their parent and specify a delay in seconds. This example sends a follow-up 3 days (259200 seconds) after the first email:

```bash
curl -X POST https://api.cakemail.dev/workflows/WORKFLOW_ID/actions \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Follow-up email",
    "type": "email",
    "parent_id": FIRST_ACTION_ID,
    "condition": "none",
    "delay": 259200,
    "email_settings": {
      "sender": { "id": SENDER_ID },
      "tracking": { "opens": true, "clicks_html": true, "clicks_text": true },
      "content": {
        "subject": "How are you finding things?",
        "html": "<html><body>Just checking in.</body></html>",
        "type": "html",
        "encoding": "utf-8"
      }
    }
  }'
```

### Action conditions

The `condition` field controls when a chained action executes relative to its parent:

| Condition | Behavior |
|-----------|----------|
| `none` | Execute after the delay regardless of parent outcome |
| `sent` | Execute only if the parent email was sent |
| `opened` | Execute only if the parent email was opened |
| `clicked` | Execute only if a link in the parent email was clicked |

## Activate the workflow

Once all actions are in place, activate the workflow:

```bash
curl -X POST https://api.cakemail.dev/workflows/WORKFLOW_ID/activate \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Test it by subscribing to the target contact list.

## List workflow actions

Review the actions in an existing workflow:

```bash
curl https://api.cakemail.dev/workflows/WORKFLOW_ID/actions?page=1&per_page=50 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Modifying workflows

To modify a workflow or its actions, you must **deactivate it first**. Make your changes, then re-activate.

---

# Email API Overview

Cakemail's Email API enables you to integrate email sending into your applications. Whether you prefer REST endpoints or standard SMTP, both methods provide industry-leading deliverability through Cakemail's infrastructure.

## Why Use Cakemail's Email API?

- **Industry-leading deliverability** with managed reputation and expert guidance
- **Two integration methods** — REST API for full control, SMTP for existing applications
- **Real-time analytics** for delivery performance and engagement tracking
- **Canadian data storage** — your data stays in Canada
- **Scalable infrastructure** that grows with your needs

## Choosing Your Integration Method

### REST API

Direct HTTP calls for maximum control and flexibility.

**Best for:**
- Applications that need programmatic control
- Custom integrations requiring full API features
- Modern web applications and microservices
- Systems requiring detailed delivery status tracking

[Sending Emails via REST API →](/guides/sending-emails-rest-api)

### SMTP

Standard email protocol that works with existing SMTP clients.

**Best for:**
- Legacy applications already using SMTP
- Quick migrations from other email providers
- Applications with established SMTP libraries
- Minimal code changes to existing systems

[Sending Emails via SMTP →](/guides/sending-emails-smtp)

## Prerequisites

Before sending emails with either method, you'll need:

1. **Active Email API Subscription** — [Email API pricing](https://www.cakemail.com/solutions/email-api)
2. **Cakemail Account** — username and password for authentication
3. **Verified Sender** — registered, verified, and authenticated with SPF/DKIM
4. **List ID** — required for contact management and compliance

## Pricing

- **35,000 free monthly email credits** to get started
- **$50/month** for the first 100,000 emails
- Volume pricing decreases as you scale

[Learn more about pricing →](https://www.cakemail.com/solutions/email-api)

## Email API vs Campaigns

| | Email API | Campaigns |
|---|-----------|-----------|
| **Use case** | Transactional (1:1) | Marketing (1:many) |
| **Triggered by** | Your application | Schedule or manual |
| **Recipients** | Single email address | Contact list |
| **Personalization** | Per-request content | Merge tags |
| **Tracking** | Per-email logs | Campaign reports |

## Next Steps

- [Sending Emails via REST API](/guides/sending-emails-rest-api)
- [Sending Emails via SMTP](/guides/sending-emails-smtp)
- [Email API Quick Reference](/guides/email-api-reference)

---

# Sending Emails via REST API

Send emails through Cakemail's `/v2/emails` endpoint using standard HTTP requests. This guide walks you through authentication, sender setup, sending your first email, and troubleshooting.

## Authentication

Obtain an access token by calling the `/token` endpoint:

```bash
curl -X POST https://api.cakemail.dev/token \
  -d "grant_type=password" \
  -d "username=YOUR_USERNAME" \
  -d "password=YOUR_PASSWORD"
```

Use the token in subsequent requests via the `Authorization: Bearer YOUR_ACCESS_TOKEN` header.

<Callout type="tip">
API tokens are private. Store them securely and only use them from your backend.
</Callout>

## Prerequisites

### Create a sender

A confirmed sender is required before sending:

```bash
curl -X POST https://api.cakemail.dev/brands/default/senders \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Sender Name", "email": "sender@example.com"}'
```

- If the sender email matches your account email, it's auto-confirmed
- Otherwise, a confirmation email is sent — the recipient must click the activation link
- The sender domain must be authenticated with SPF/DKIM records
- Your tracking domain must be branded on your domain

### Find your list ID

Contact management is required for compliance and bounce handling:

```bash
curl https://api.cakemail.dev/lists \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Use the `id` field from your chosen list when sending emails.

## Send an email

```bash
curl -X POST https://api.cakemail.dev/v2/emails \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": LIST_ID,
    "sender": { "id": SENDER_ID },
    "email": "recipient@example.com",
    "content": {
      "type": "marketing",
      "subject": "Hello, world!",
      "html": "<html><body>Hello, world!</body></html>",
      "encoding": "utf-8"
    }
  }'
```

### Required fields

| Field | Description |
|-------|-------------|
| `list_id` | Contact list ID |
| `sender.id` | Verified sender ID |
| `email` | Recipient email address |
| `content.type` | `marketing` or `transactional` |
| `content.subject` | Email subject line |
| `content.html` | HTML body content |

### Optional fields

| Field | Description |
|-------|-------------|
| `content.encoding` | Character encoding (default: `utf-8`) |
| `tags` | Array of tags for filtering |

### Response

```json
{
  "email": "recipient@example.com",
  "object": "email",
  "submitted": true,
  "data": {
    "id": "3fbfa67e-c4c4-4e03-8dfd-556037960374",
    "status": "queued"
  }
}
```

## Check email status

Track delivery progress using the email ID from the send response:

```bash
curl https://api.cakemail.dev/v2/emails/EMAIL_ID \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Email lifecycle

Each email moves through a series of statuses:

| Status | Meaning |
|--------|---------|
| `submitted` | Email accepted by the API |
| `queued` | Email queued for delivery |
| `delivered` | Successfully delivered to the recipient's mail server |
| `opened` | Recipient opened the email |
| `clicked` | Recipient clicked a link |
| `bounced` | Delivery failed |
| `complained` | Recipient marked as spam |

## Activity logs and tags

Tag emails for organized tracking:

```bash
curl -X POST https://api.cakemail.dev/v2/emails \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "tags": ["password-reset", "auth"],
    "list_id": LIST_ID,
    "sender": { "id": SENDER_ID },
    "content": {
      "type": "transactional",
      "subject": "Password Reset",
      "html": "<p>Click to reset.</p>"
    }
  }'
```

Filter activity logs by tag, date, or status:

```bash
curl "https://api.cakemail.dev/v2/logs/emails?tags=password-reset&page=1&per_page=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

## Troubleshooting

### Authentication errors

- Verify your username and password
- Ensure your account has API access enabled
- Obtain a new token if the current one has expired

### Invalid sender

- Confirm the sender email is registered and verified
- Verify the sender ID exists
- Ensure the domain is authenticated with SPF/DKIM

### List ID not found

- Use `GET /lists` to retrieve available lists
- Verify the list hasn't been deleted

### Email not received

- Check spam/junk folders
- Verify the recipient email address is valid
- Review your sender reputation and authentication
- Monitor bounce reports in your Cakemail account

---

# Sending Emails via SMTP

Send emails through Cakemail's SMTP gateway using standard SMTP protocol. This allows you to leverage the full power of Cakemail's Email API without modifying your existing SMTP-based applications.

## Overview

The SMTP gateway provides a familiar interface for developers already using SMTP. Simply configure your SMTP client to use Cakemail's server with your account credentials.

**Benefits:**
- Use existing SMTP libraries and code
- Minimal changes to legacy applications
- Standard protocol with wide language support
- Industry-leading deliverability

## Email API Subscription Required

Before using SMTP, you need an active Email API account with a valid subscription.

Learn more at [cakemail.com/solutions/email-api](https://www.cakemail.com/solutions/email-api).

## SMTP Configuration

| Setting | Value |
|---------|-------|
| **Host** | `smtp.cakemail.dev` |
| **Port** | `465` |
| **Encryption** | SSL/TLS (SMTPS) |
| **Authentication** | Your Cakemail username and password |

## Prerequisites

### Sender Requirements

Your sender address must be:

- **Registered** in your Cakemail account
- **Validated** through email verification
- **Authenticated** with SPF/DKIM records
- **Tracking domain** branded on your domain

The `From:` header must match a validated sender. Emails from unvalidated senders will be rejected.

### List ID

Contact management is required for compliance and bounce handling. You'll need a List ID from your Cakemail account. Find your default list or create a new one through the [Lists API](/api).

## Required Headers

### x-email-api-enabled

**Format:** `x-email-api-enabled: true`

Enables Email API routing for this message. Required for all SMTP messages.

### x-list-id

**Format:** `x-list-id: <list-id>`

Associates the email with a Cakemail list. Required by default.

**Why x-list-id is required:**
- **Consent management**: Maintains compliance with email regulations
- **Bounce handling**: Automatically processes bounces and unsubscribes
- **Contact management**: Recipients not in the list are automatically added

If your use case justifies not using a list ID, contact [support@cakemail.com](mailto:support@cakemail.com).

## Optional Headers

| Header | Format | Default | Purpose |
|--------|--------|---------|---------|
| `x-email-api-type` | `marketing` or `transactional` | `marketing` | Email type classification |
| `x-tags` | `tag1,tag2` | None | Comma-separated tags for filtering |

## Quick Start

```bash
curl -v \
    --mail-from 'sender@example.com' \
    --mail-rcpt 'recipient@example.com' \
    smtps://smtp.cakemail.dev:465 \
    --user "your-username:your-password" \
    --upload-file - <<EOF
From: sender@example.com
To: recipient@example.com
Subject: Test Email
x-email-api-enabled: true
x-list-id: 9234980

This is the email body content.
EOF
```

## Code Examples

### Python (smtplib)

```python
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

smtp_server = "smtp.cakemail.dev"
smtp_port = 465
username = "your-username"
password = "your-password"

msg = MIMEMultipart()
msg['From'] = 'sender@example.com'
msg['To'] = 'recipient@example.com'
msg['Subject'] = 'Test Email'
msg['x-email-api-enabled'] = 'true'
msg['x-list-id'] = '9234980'

body = "This is the email body content."
msg.attach(MIMEText(body, 'plain'))

with smtplib.SMTP_SSL(smtp_server, smtp_port) as server:
    server.login(username, password)
    server.send_message(msg)
    print("Email sent successfully!")
```

### Node.js (nodemailer)

```javascript
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'smtp.cakemail.dev',
  port: 465,
  secure: true,
  auth: {
    user: 'your-username',
    pass: 'your-password'
  }
});

const mailOptions = {
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: 'Test Email',
  text: 'This is the email body content.',
  headers: {
    'x-email-api-enabled': 'true',
    'x-list-id': '9234980'
  }
};

transporter.sendMail(mailOptions, (error, info) => {
  if (error) {
    console.error('Error:', error);
  } else {
    console.log('Email sent:', info.response);
  }
});
```

### PHP (PHPMailer)

```php
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

$mail = new PHPMailer(true);

try {
    $mail->isSMTP();
    $mail->Host       = 'smtp.cakemail.dev';
    $mail->SMTPAuth   = true;
    $mail->Username   = 'your-username';
    $mail->Password   = 'your-password';
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
    $mail->Port       = 465;

    $mail->setFrom('sender@example.com');
    $mail->addAddress('recipient@example.com');

    $mail->addCustomHeader('x-email-api-enabled', 'true');
    $mail->addCustomHeader('x-list-id', '9234980');

    $mail->Subject = 'Test Email';
    $mail->Body    = 'This is the email body content.';

    $mail->send();
    echo 'Email sent successfully!';
} catch (Exception $e) {
    echo "Email could not be sent. Error: {$mail->ErrorInfo}";
}
```

## Troubleshooting

### Authentication Failed

- Verify your Cakemail username and password
- Ensure your account has API access enabled

### Connection Refused

- Confirm you're using port 465 with SSL/TLS
- Check if your firewall allows outbound connections on port 465
- Verify the hostname is `smtp.cakemail.dev`

### Email Not Delivered

- Ensure `x-email-api-enabled: true` header is included
- Confirm the sender email is validated and authenticated
- Check that `x-list-id` contains a valid list ID
- Review spam/junk folders

## Limitations

- **Single recipient per SMTP call** — send separately for multiple recipients
- **Attachments disabled by default** — contact [support@cakemail.com](mailto:support@cakemail.com) to enable

---

# Email API Quick Reference

Quick-lookup reference for Cakemail Email API endpoints, SMTP configuration, headers, and response formats.

## REST API Endpoints

| Method | Endpoint | Purpose |
|--------|----------|---------|
| POST | `/token` | Obtain access token |
| POST | `/brands/default/senders` | Create a sender |
| GET | `/lists` | List contact lists |
| POST | `/v2/emails` | Send an email |
| GET | `/v2/emails/:id` | Check email status |
| GET | `/v2/emails/:id/render` | Render email content |
| GET | `/v2/logs/emails` | Email activity logs |
| GET | `/v2/reports/emails` | Email reports |

## SMTP Configuration

| Setting | Value |
|---------|-------|
| **Host** | `smtp.cakemail.dev` |
| **Port** | `465` |
| **Encryption** | SSL/TLS (SMTPS) |
| **Authentication** | Cakemail username and password |

## SMTP Headers

### Required

| Header | Format | Purpose |
|--------|--------|---------|
| `From` | `sender@example.com` | Validated sender address |
| `To` | `recipient@example.com` | Single recipient only |
| `Subject` | Text | Email subject line |
| `x-email-api-enabled` | `true` | Enables Email API routing |
| `x-list-id` | `9234980` | Associates with contact list |

### Optional

| Header | Format | Default | Purpose |
|--------|--------|---------|---------|
| `x-email-api-type` | `marketing` or `transactional` | `marketing` | Email classification |
| `x-tags` | `tag1,tag2` | None | Tags for filtering |

## Email Types

| Type | Use cases | Characteristics |
|------|-----------|-----------------|
| `marketing` | Newsletters, promotions, announcements | Subject to consent requirements, bulk-optimized |
| `transactional` | Order confirmations, password resets, notifications | Higher priority delivery, must relate to user actions |

## Send Email (REST)

```bash
curl -X POST https://api.cakemail.dev/v2/emails \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "list_id": LIST_ID,
    "sender": { "id": SENDER_ID },
    "email": "recipient@example.com",
    "content": {
      "type": "marketing",
      "subject": "Hello",
      "html": "<html><body>Hello</body></html>",
      "encoding": "utf-8"
    }
  }'
```

## Response Format

### Successful Submission

```json
{
  "email": "recipient@example.com",
  "object": "email",
  "submitted": true,
  "data": {
    "id": "3fbfa67e-c4c4-4e03-8dfd-556037960374",
    "status": "queued"
  }
}
```

Use `data.id` to track delivery status via `GET /v2/emails/:id`.

## Best Practices

- **Authenticate your domain** with SPF and DKIM before sending
- **Use lists** for bounce handling and consent management
- **Handle token expiration** — obtain a new token when the current one expires
- **Monitor delivery status** for critical transactional emails
- **SMTP: single recipient only** — make separate calls for multiple recipients
- **SMTP: attachments disabled by default** — contact support to enable

---

# Partner API

The Partner API lets resellers and agencies manage sub-accounts programmatically. You can create, suspend, and delete sub-accounts, and access their resources using your partner credentials.

## Create a sub-account

```bash
curl -X POST https://api.cakemail.dev/sub-accounts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Corp",
    "admin_email": "admin@acmecorp.com"
  }'
```

The response includes a `sub_account_id` you'll use for all subsequent operations on that account.

## List sub-accounts

```bash
curl "https://api.cakemail.dev/sub-accounts?page=1&per_page=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Use `page` and `per_page` for pagination. Results are sorted by creation date.

## Update a sub-account

```bash
curl -X PATCH https://api.cakemail.dev/sub-accounts/{sub_account_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"company_name": "Acme Corporation"}'
```

## Suspend a sub-account

```bash
curl -X POST https://api.cakemail.dev/sub-accounts/{sub_account_id}/suspend \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

Suspended accounts cannot send emails or access the API. Their data is preserved.

## Unsuspend a sub-account

```bash
curl -X POST https://api.cakemail.dev/sub-accounts/{sub_account_id}/unsuspend \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

This restores full access to the sub-account.

## Access sub-account resources

As a partner, you can access any sub-account's resources by adding the `account_id` query parameter to standard API endpoints. This lets you manage campaigns, contacts, and other resources on behalf of your sub-accounts without needing their credentials.

For example, to list campaigns for a specific sub-account:

```bash
curl "https://api.cakemail.dev/campaigns?account_id={sub_account_id}" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

The `account_id` parameter works with any API endpoint — contacts, lists, templates, and more.

## Delete a sub-account

```bash
curl -X DELETE https://api.cakemail.dev/sub-accounts/{sub_account_id} \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

This permanently removes the sub-account and all its associated data. This action cannot be undone.

---

# Partner Login Integration

As a Cakemail partner, you can offer a **Login to Cakemail** button inside your application or control panel, giving your clients direct access to their Cakemail accounts.

## Implementation

Use an HTML form that posts credentials to the Cakemail login endpoint:

```html
<form action="https://app.cakemail.com/api/login" method="POST" target="_blank">
    <input type="hidden" name="email" value="client@example.com" />
    <input type="hidden" name="password" value="client-password" />
    <input type="submit" value="Open Email Marketing" />
</form>
```

## Steps

1. Replace `app.cakemail.com` with your **partner URL** if you have a custom domain
2. Replace the `email` and `password` values with the client's credentials from your database
3. Customize the submit button with CSS to match your application's design

<Callout type="caution" title="Security">
The form posts credentials directly, so it should only be rendered server-side where you control the credential values. Never expose client passwords in client-side JavaScript.
</Callout>

## Related

- [Partner API guide](/guides/partner-api) — managing sub-accounts programmatically

---

# Classic API Migration

If you are currently using the Classic API and wish to migrate to the current API, consult the following table to assess the impact.

## Compatibility Matrix

| Current API | Classic API | Compatibility |
|---|---|---|
| Campaigns | Mailing | Compatible |
| N/A | Mailing (recurring) | Classic only |
| N/A | Mailing (absplit) | Classic only |
| List | List | Compatible |
| Contact | List / Record | Compatible |
| Custom Attribute | List / Fields | Compatible |
| Segment | List / Sublist | Compatible |
| Suppressed Email | SuppressionList | Compatible |
| Transactional Email | Relay | Compatible |
| Transactional Email via SMTP | N/A | Current API only |
| Log | Mailing / List / Relay Log | Compatible |
| Report | Mailing / List / Relay Log | Compatible |
| Account | Client | Compatible |
| Sub-Account | Client | Compatible |
| User | User | Compatible |
| Form | N/A | Current API only |
| Domain | Client | Compatible |
| Logo | N/A | Current API only |
| Sender | N/A | Current API only |
| N/A | TemplateV2 | Classic only |
| N/A | Trigger | Classic only |
| N/A | Permission | Classic only |
| N/A | Campaign | Classic only |

## Key Differences

### Available only in the current API

- **Transactional Email via SMTP** — send emails through the SMTP gateway
- **Forms** — custom subscription forms with opt-in parameters
- **Sender management** — dedicated sender identity and authentication
- **Domain management** — SPF/DKIM authentication resources
- **Logo** — brand customization

### Available only in Classic

- **Recurring mailings** — automated recurring sends
- **A/B split mailings** — built-in split testing
- **TemplateV2** — legacy template system
- **Triggers** — legacy automation triggers
- **Permissions** — legacy permission model

## Partner Login

The current API provides a way to embed a **Login to Cakemail** button in your application. See the [Partner Login guide](/guides/partner-login) for implementation details.

---

# AI Assistant Integrations

The Cakemail API is designed to work with AI coding assistants. Whether you're generating integration code, exploring endpoints, or executing API calls directly, there are several ways to connect your AI tools to Cakemail.

## Context7

The Cakemail OpenAPI specification is indexed on [Context7](https://context7.com), a service that provides up-to-date library and API documentation to AI coding assistants.

Any AI tool that supports Context7 — including Claude Code, Cursor, Windsurf, and others — can automatically pull the latest Cakemail API docs when you're writing integration code.

### How it works

When you ask your AI assistant about Cakemail, Context7 fetches the current OpenAPI spec so the assistant has accurate endpoint definitions, parameter schemas, and response formats — not outdated training data.

No configuration is needed if your tool already has Context7 enabled. Just mention Cakemail in your prompt and the assistant will pull the relevant documentation.

## MCP servers in AI coding assistants

Any AI coding assistant that supports [MCP](https://modelcontextprotocol.io) — including Claude Code, Cursor, Windsurf, and others — can connect directly to Cakemail's MCP servers. This gives the assistant live access to the API: browsing endpoints, making real API calls, and searching documentation.

Cakemail provides three MCP servers:

- **Discovery MCP** — Browse endpoints and schemas, no auth required
- **Execution MCP** — Make real API calls on behalf of users
- **Knowledge Base MCP** — Search Cakemail documentation in natural language

### Setup with Claude Code

Add the MCP servers to Claude Code:

```bash
# Discovery — browse the API (no auth required)
claude mcp add cakemail-discovery \
  --transport http \
  https://apidoc.mcp.cakemail.com/api/mcp

# Execution — make API calls (requires auth)
claude mcp add cakemail-exec \
  --transport http \
  https://exec.mcp.cakemail.com/api/mcp \
  --header "Authorization: Basic $(echo -n 'you@example.com:your-password' | base64)"

# Knowledge base — search docs (requires auth)
claude mcp add cakemail-kb \
  --transport http \
  https://kb.mcp.cakemail.com/api/mcp \
  --header "Authorization: Basic $(echo -n 'you@example.com:your-password' | base64)"
```

Other MCP-compatible tools use similar configuration — provide the server URL and transport type. See your tool's documentation for specifics.

### Example prompts

Once connected, you can ask your AI assistant things like:

- "List my Cakemail campaigns from the last 30 days"
- "Create a new contact list called 'Newsletter Subscribers'"
- "Show me the parameters for the send campaign endpoint"
- "What webhook events does Cakemail support?"

For a detailed breakdown of each MCP server — available tools, authentication, and usage examples — see the [MCP Servers documentation](/tools/mcp/overview).

---

# TypeScript SDK

The official TypeScript SDK provides typed methods for all 222+ API operations with built-in authentication, retry logic, and error handling.

## Installation

```bash
npm install @cakemail-org/cakemail-sdk
```

## Quick start

```typescript
import { CakemailClient } from '@cakemail-org/cakemail-sdk';

const client = new CakemailClient({
  email: 'you@example.com',
  password: 'your-password',
});

// List campaigns
const campaigns = await client.campaignService.listCampaigns({
  page: 1,
  perPage: 10,
});

// Create a contact
const contact = await client.contactService.addContact({
  listId: 123,
  requestBody: {
    email: 'new-subscriber@example.com',
  },
});
```

## Authentication

The SDK handles OAuth2 automatically. Provide email/password and it manages token acquisition, caching, and refresh:

```typescript
// Email/password auth (recommended)
const client = new CakemailClient({
  email: 'you@example.com',
  password: 'your-password',
});

// Or use a pre-existing access token
const client = new CakemailClient({
  accessToken: 'your-access-token',
});
```

## Error handling

```typescript
import { CakemailAPIError } from '@cakemail-org/cakemail-sdk';

try {
  await client.campaignService.getCampaign({ campaignId: 999 });
} catch (error) {
  if (error instanceof CakemailAPIError) {
    console.log(error.statusCode);     // 404
    console.log(error.message);        // "Campaign not found"
    console.log(error.requestId);      // For support debugging
  }
}
```

## Available services

The SDK exposes one service per API resource:

| Service | Description |
|---------|-------------|
| `accountService` | Account management |
| `campaignService` | Campaign lifecycle |
| `contactService` | Contact CRUD, import, tags |
| `listService` | List management |
| `templateService` | Email templates |
| `senderService` | Sender management |
| `webhookService` | Webhook management |
| `emailApiService` | Transactional email (v2) |
| `reportService` | Analytics and stats |
| `tagService` | Contact tags |
| `segmentService` | List segmentation |

And 20+ more services covering the full API.

## Multi-account support

For partner/reseller operations, pass `accountId` to any service method:

```typescript
const campaigns = await client.campaignService.listCampaigns({
  accountId: 12345,
  page: 1,
  perPage: 10,
});
```

## Source

The SDK is open source at [github.com/cakemail/cakemail-sdk](https://github.com/cakemail/cakemail-sdk).

---

# CLI

The official command-line interface for the Cakemail API. Built on the TypeScript SDK with 100% API coverage (232 operations) across 30 command groups.

## Installation

```bash
# npm (global)
npm install -g @cakemail-org/cakemail-cli

# Or run without installing
npx @cakemail-org/cakemail-cli campaigns list
```

## Authentication

```bash
# Access token (recommended for scripting)
export CAKEMAIL_ACCESS_TOKEN=your-access-token

# Or email/password
export CAKEMAIL_EMAIL=you@example.com
export CAKEMAIL_PASSWORD=your-password

# Or pass directly
cakemail campaigns list --access-token your-token
```

## Quick start

```bash
# List your campaigns
cakemail campaigns list

# Create a contact
cakemail contacts create --email subscriber@example.com --list-id 123

# Send a transactional email
cakemail email-apis submit --email user@example.com --subject "Welcome" --html "<h1>Hello</h1>"

# Check campaign performance
cakemail reports get 456
```

## Key features

### Campaign management

Full lifecycle control — create, configure, test, schedule, and track delivery:

```bash
# List delivered campaigns
cakemail campaigns list --status delivered

# Schedule a campaign
cakemail campaigns schedule 123 --scheduled-for "2026-04-15T10:00:00Z"

# Send a test email before launching
cakemail campaigns send-test 123 --email you@example.com
```

### Contact and list management

Manage contacts, lists, segments, and custom attributes:

```bash
# List active contacts
cakemail contacts list --list-id 123

# Import contacts in bulk
cakemail contacts import --list-id 123 --data-file contacts.csv

# Tag contacts for segmentation
cakemail tags list --with-count
```

### Reports and analytics

Track campaign performance, link clicks, and email delivery:

```bash
# Campaign delivery report
cakemail reports get 456

# Email API activity logs
cakemail email-apis logs --per-page 25
```

### Multi-account support

Seamlessly operate across parent and sub-accounts for multi-tenant workflows:

```bash
# List sub-accounts
cakemail sub-accounts list

# Run a command against a specific account
cakemail campaigns list --account-id 789
```

## Output formats

Three formats controlled by `--format` or your active profile:

```bash
# JSON — raw data, ideal for scripting and piping
cakemail campaigns list --format json

# Table — formatted columns with status badges and dates
cakemail campaigns list --format table

# Compact — one-liner per item, ideal for quick scanning
cakemail campaigns list --format compact
```

## Profiles

Profiles control the entire CLI experience — output format, colors, interactivity, date formatting, and error verbosity:

```bash
# Switch your active profile
cakemail config profile developer

# Override for a single command
cakemail campaigns list --profile marketer
```

| Profile | Best for | Output | Colors | Prompts | Dates |
|---------|----------|--------|--------|---------|-------|
| **developer** | CI/CD, scripting | JSON | None | Disabled | ISO 8601 |
| **balanced** | Day-to-day use | Table | Moderate | Auto (TTY) | Friendly |
| **marketer** | Exploration, manual work | Compact | Rich | Always | Relative |

## Configuration

Settings persist to `~/.cakemail/config.json`:

```bash
# Show current config
cakemail config show

# Set active profile
cakemail config set profile developer

# Set default list (auto-used when --list-id is omitted)
cakemail config set default.list_id 123

# Set default sender
cakemail config set default.sender_id 456
```

## Smart auto-detection

The CLI reduces typing by auto-detecting resources:

- **Single list?** Used automatically — no `--list-id` needed
- **Single confirmed sender?** Selected automatically
- **Session cache** — last-used resources cached for 5 minutes

```bash
# If you have only one list, this just works:
cakemail contacts list
# → Using list: My Newsletter (123)
```

## Scripting and automation

Use `--batch` or the developer profile to disable all interactive features:

```bash
# Pipe contact emails to another tool
cakemail contacts list --batch --format json | jq '.data[].email'

# Use in shell scripts
CAMPAIGN_ID=$(cakemail campaigns create --name "April" --format json | jq -r '.data.id')
cakemail campaigns schedule $CAMPAIGN_ID --scheduled-for "2026-04-15T10:00:00Z"
```

## All command groups

| Command | Description |
|---------|-------------|
| `campaigns` | Create, schedule, send, and manage campaigns |
| `contacts` | Add, update, import, tag, and manage contacts |
| `lists` | Create and manage contact lists |
| `templates` | Email template management |
| `senders` | Sender management and verification |
| `webhooks` | Webhook creation and management |
| `tags` | Contact tag management |
| `segments` | List segmentation |
| `reports` | Campaign and email analytics |
| `email-apis` | Transactional email (v2) |
| `accounts` | Account management |
| `sub-accounts` | Multi-tenant account management |
| `users` | User/team management |
| `domains` | Domain configuration |
| `dkims` | DKIM authentication setup |
| `config` | CLI configuration |

Plus 14 more command groups covering forms, workflows, logos, links, and more.

---

# CLI Advanced Usage

Patterns for scripting, CI/CD pipelines, and bulk operations with the CLI.

## Scripting best practices

Start every automation script with strict error handling:

```bash
#!/bin/bash
set -euo pipefail

LOG_FILE="cakemail-automation.log"
log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"; }
```

### Retry with backoff

```bash
retry() {
  local max=3 attempt=1 delay=2
  while [ $attempt -le $max ]; do
    "$@" && return 0
    [ $attempt -lt $max ] && { log "Retry $attempt..."; sleep $delay; delay=$((delay * 2)); }
    ((attempt++))
  done
  return 1
}

retry cakemail campaigns schedule 123
```

### Batch processing with rate limiting

```bash
# Process 10 contacts at a time with 1-second delay
cakemail contacts list --list-id 123 --format json --batch \
  | jq -r '.data[].id' \
  | while read -r id; do
    cakemail contacts get --list-id 123 "$id" --format json >> results.json
    sleep 0.1
  done
```

### Capture and check results

```bash
RESPONSE=$(cakemail -f json campaigns get 123 2>&1)
if echo "$RESPONSE" | jq -e . > /dev/null 2>&1; then
  STATUS=$(echo "$RESPONSE" | jq -r '.data.status')
  echo "Campaign status: $STATUS"
else
  echo "Error: $RESPONSE"
  exit 1
fi
```

## Contact import and export

### CSV requirements

- Header row required with `email` column (mandatory)
- UTF-8 encoding
- Dates in ISO format: `YYYY-MM-DD`

```bash
# Import contacts
cakemail contacts import --list-id 123 --file contacts.csv

# Check import progress
cakemail contacts import-status imp_abc123

# Export contacts
cakemail contacts export --list-id 123
cakemail contacts export-download exp_xyz789 > backup.csv

# Export only subscribed contacts
cakemail contacts export --list-id 123 --filter "status==subscribed"
```

### Data migration between lists

```bash
# Export from source list
cakemail contacts export --list-id 100
# Wait for export, then download
cakemail contacts export-download exp_xyz789 > migrated.csv
# Import to target list
cakemail contacts import --list-id 200 --file migrated.csv
```

### Deduplication before import

```bash
# Get existing emails
cakemail contacts list --list-id 123 --format json --batch \
  | jq -r '.data[].email' | sort > existing.txt

# Filter new contacts only
head -1 new_contacts.csv > unique.csv
tail -n +2 new_contacts.csv | while IFS=, read -r email rest; do
  grep -q "^$email$" existing.txt || echo "$email,$rest" >> unique.csv
done

cakemail contacts import --list-id 123 --file unique.csv
```

## CI/CD integration

### GitHub Actions

```yaml
name: Send weekly newsletter
on:
  schedule:
    - cron: '0 8 * * 1'  # Monday 8 AM UTC

jobs:
  newsletter:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install CLI
        run: npm install -g @cakemail-org/cakemail-cli

      - name: Create and schedule campaign
        env:
          CAKEMAIL_ACCESS_TOKEN: ${{ secrets.CAKEMAIL_TOKEN }}
        run: |
          CAMPAIGN_ID=$(cakemail campaigns create \
            --name "Newsletter $(date +%Y-%m-%d)" \
            --format json | jq -r '.data.id')

          cakemail campaigns schedule $CAMPAIGN_ID
```

### Docker

```dockerfile
FROM node:20-alpine
RUN npm install -g @cakemail-org/cakemail-cli
ENTRYPOINT ["cakemail"]
```

```bash
docker build -t cakemail-cli .
docker run -e CAKEMAIL_ACCESS_TOKEN=xxx cakemail-cli campaigns list
```

### Multi-environment setup

Use different credentials per environment:

```yaml
# In GitHub Actions
env:
  CAKEMAIL_ACCESS_TOKEN: ${{ github.ref == 'refs/heads/main'
    && secrets.CAKEMAIL_PROD_TOKEN
    || secrets.CAKEMAIL_STAGING_TOKEN }}
```

## Campaign lifecycle automation

### State diagram

```
draft → scheduled → sending → sent → archived
  ↓        ↓          ↓
delete   unschedule  suspend
```

### Emergency stop

```bash
STATUS=$(cakemail campaigns get 123 --format json | jq -r '.data.status')

case $STATUS in
  sending)
    cakemail campaigns suspend 123
    echo "Campaign suspended"
    ;;
  scheduled)
    cakemail campaigns unschedule 123
    echo "Campaign unscheduled (back to draft)"
    ;;
  draft)
    echo "Campaign is still in draft"
    ;;
esac
```

### Health check: detect stale campaigns

```bash
# Find drafts older than 30 days
cakemail campaigns list --filter "status==draft" --format json --batch \
  | jq -r '.data[] | select(
      (.created_on | fromdateiso8601) < (now - 2592000)
    ) | "\(.id) \(.name) \(.created_on)"'
```

---

# CLI Reference

Pagination, filtering, error codes, and authentication details.

## Authentication

The CLI resolves credentials in priority order:

1. **CLI flags** — `--access-token`, `--email`, `--password`
2. **Environment variables** — `CAKEMAIL_ACCESS_TOKEN` or `CAKEMAIL_EMAIL` + `CAKEMAIL_PASSWORD`
3. **Config file** — `~/.cakemail/config.json` (saved after first auth)
4. **Interactive prompt** — asks for credentials if TTY is available

Tokens are cached and auto-refreshed. Passwords are never stored — only OAuth tokens.

### Account switching

```bash
# Show current account
cakemail accounts get

# Switch to a sub-account
cakemail campaigns list --account-id 789
```

## Pagination

All list commands support pagination:

```bash
# Basic pagination
cakemail campaigns list --page 2 --per-page 25

# Response metadata (JSON format)
# { "data": [...], "count": 25, "total": 247, "page": 2, "per_page": 25 }
```

### Iterate all pages in a script

```bash
PAGE=1
while true; do
  RESPONSE=$(cakemail campaigns list --format json --batch --page $PAGE --per-page 100)
  COUNT=$(echo "$RESPONSE" | jq '.data | length')
  [ "$COUNT" -eq 0 ] && break
  echo "$RESPONSE" | jq '.data[]'
  PAGE=$((PAGE + 1))
done
```

## Filtering and sorting

```bash
# Filter by field (== exact match)
cakemail campaigns list --filter "status==delivered"

# Multiple filters (AND logic, semicolon separated)
cakemail campaigns list --filter "status==delivered;name==Newsletter"

# Sort ascending (+) or descending (-)
cakemail campaigns list --sort "-created_on"

# Combined
cakemail campaigns list --filter "status==draft" --sort "+name" --per-page 10
```

### Filterable fields

| Resource | Fields |
|----------|--------|
| Campaigns | `status`, `name`, `created_on`, `scheduled_for` |
| Contacts | `status`, `email`, `subscribed_on` |
| Lists | `status`, `name`, `created_on` |
| Templates | `name`, `created_on` |
| Senders | `confirmed`, `email`, `name` |

## Error codes

The CLI maps API errors to actionable messages:

| Code | Meaning | What to do |
|------|---------|------------|
| 400 | Invalid parameters | Check `--help` for correct syntax |
| 401 | Authentication failed | Run `cakemail config show` to check credentials |
| 403 | Permission denied | Verify account context with `--account-id` |
| 404 | Resource not found | List resources to find the correct ID |
| 409 | Conflict | Resource may already exist |
| 422 | Validation error | Check email format, date format (YYYY-MM-DD) |
| 429 | Rate limit | Add `sleep 1` between requests in scripts |
| 500+ | Server error | Retry after a moment |

### Exit codes

```bash
cakemail campaigns get 123
echo $?  # 0 = success, 1 = error

# Use in conditionals
if cakemail campaigns get 123 > /dev/null 2>&1; then
  echo "Campaign exists"
fi
```

## Global flags

| Flag | Description |
|------|-------------|
| `--format <json\|table\|compact>` | Output format |
| `--profile <developer\|marketer\|balanced>` | Override active profile |
| `--access-token <token>` | Override credentials |
| `--account-id <id>` | Target a sub-account |
| `--batch` | Disable all interactive features |
| `--help` | Show command help |
| `--version` | Show CLI version |

---

# MCP Servers

{/* api-kit:generated — Do not edit manually. Regenerated by api-kit. */}

The API is accessible to AI assistants through [Model Context Protocol (MCP)](https://modelcontextprotocol.io) servers. These servers let coding agents and AI tools discover and interact with the API programmatically.

## Available Servers


### Discovery MCP

**URL:** `https://apidoc.mcp.cakemail.com/api/mcp`

A read-only server for exploring the API. AI assistants can browse endpoints, view parameter schemas, and understand what the API offers — without making any API calls or requiring authentication.

**Tools:** `list_endpoints`, `get_endpoint`

[Learn more →](/tools/mcp/discovery-mcp)


### Execution MCP

**URL:** `https://exec.mcp.cakemail.com/api/mcp`

An authenticated server for making real API calls. AI assistants can create campaigns, manage contacts, check analytics — anything the API supports. Requires user credentials.

**Tools:** One tool per API tag (~30 tools) with structured parameters.

[Learn more →](/tools/mcp/execution-mcp)




### kb-mcp

**URL:** `https://kb.mcp.cakemail.com/api/mcp`

Semantic search over Cakemail documentation and knowledge base. Ask questions in natural language and get answers from the docs.

**Tools:** `search_knowledge_base`, `list_topics`
**Authentication required.**



## Which server should I use?

| Use case | Server |
|----------|--------|
| Exploring the API, reading docs | Discovery MCP |
| Building integrations, generating code | Discovery MCP |
| Performing actions on behalf of users | Execution MCP |


| Semantic search over Cakemail documentation and knowledge base | kb-mcp |


| Both exploring and executing | Connect both |

---

# Discovery MCP Server

{/* api-kit:generated — Do not edit manually. Regenerated by api-kit. */}

The Discovery MCP server lets AI assistants explore the API specification. It provides tools to list endpoints, view parameter schemas, and understand the API — without making any actual API calls.

**Server URL:** `https://apidoc.mcp.cakemail.com/api/mcp`

## Connect with Claude Code

```bash
claude mcp add apidoc-mcp \
  --transport http \
  https://apidoc.mcp.cakemail.com/api/mcp
```

## Connect with any MCP client

```json
{
  "mcpServers": {
    "apidoc-mcp": {
      "type": "streamable-http",
      "url": "https://apidoc.mcp.cakemail.com/api/mcp"
    }
  }
}
```

## Authentication

No authentication required. This is a read-only spec browser.

## Available Tools

### `list_endpoints`

List available API endpoints. Filter by tag or search term.

**Parameters:**
- `tag` (optional) — Filter by API category (e.g., Campaign, Contact, Account)
- `search` (optional) — Search term to filter by path, summary, or operationId

**Example usage:** "List all endpoints related to campaigns"

### `get_endpoint`

Get full details for a specific endpoint including parameters, request body schema, and response schema.

**Parameters:**
- `operationId` (optional) — The operation ID (e.g., listCampaigns, createCampaign)
- `path` (optional) — The API path (e.g., /campaigns)
- `method` (optional) — The HTTP method (e.g., GET, POST)

Provide either `operationId` alone, or both `path` and `method`.

---

# Execution MCP Server

{/* api-kit:generated — Do not edit manually. Regenerated by api-kit. */}

The Execution MCP server lets AI assistants make authenticated API calls on behalf of users. It provides one tool per API tag (~30 tools) with structured parameters, so agents see exactly what operations are available.

**Server URL:** `https://exec.mcp.cakemail.com/api/mcp`

## Connect with Claude Code

```bash
claude mcp add exec-mcp \
  --transport http \
  https://exec.mcp.cakemail.com/api/mcp \
  --header "Authorization: Basic BASE64_ENCODED_CREDENTIALS"
```

Generate the Base64 string:

```bash
echo -n 'you@example.com:your-password' | base64
```

## Connect with any MCP client

```json
{
  "mcpServers": {
    "exec-mcp": {
      "type": "streamable-http",
      "url": "https://exec.mcp.cakemail.com/api/mcp",
      "headers": {
        "Authorization": "Basic BASE64_ENCODED_CREDENTIALS"
      }
    }
  }
}
```

## Authentication

Authentication is required. Three methods are supported:

- **Basic Auth** — Base64-encoded `email:password` (recommended for MCP clients)
- **Bearer token** — An access token obtained from the `/api/auth` endpoint
- **Admin API key** — Set via the `API_KEY` environment variable on the server

## How it works

Each API tag (Campaigns, Contacts, Lists, etc.) is exposed as a separate MCP tool. To use a tool, specify an `operation` and the relevant parameters.

**Example:** To list campaigns, the agent calls the `campaigns` tool with `operation: "list"`.

**Example:** To delete a contact, the agent calls the `contacts` tool with `operation: "delete"`, `contact_id: "123"`, and `confirmed: true`.

## Safety

- **Destructive operations** (DELETE) require `confirmed: true`. Without it, the server returns a warning instead of executing.
- **Method whitelist** — Only GET, POST, PATCH, DELETE methods are allowed.

## Token endpoint

The server also exposes a `/api/auth` endpoint for obtaining access tokens:

```bash
curl -X POST https://exec.mcp.cakemail.com/api/auth \
  -H "Content-Type: application/json" \
  -d '{"username": "you@example.com", "password": "your-password"}'
```

---

# Knowledge Base MCP Server

The Knowledge Base MCP server provides semantic search over Cakemail's documentation. AI assistants can search articles in natural language and browse available topics across multiple languages.

**Server URL:** `https://kb.mcp.cakemail.com/api/mcp`

## Connect with Claude Code

```bash
claude mcp add cakemail-kb \
  --transport http \
  https://kb.mcp.cakemail.com/api/mcp \
  --header "Authorization: Basic BASE64_ENCODED_CREDENTIALS"
```

Generate the Base64 string:

```bash
echo -n 'you@example.com:your-password' | base64
```

## Connect with any MCP client

```json
{
  "mcpServers": {
    "cakemail-kb": {
      "type": "streamable-http",
      "url": "https://kb.mcp.cakemail.com/api/mcp",
      "headers": {
        "Authorization": "Basic BASE64_ENCODED_CREDENTIALS"
      }
    }
  }
}
```

## Connect with Cursor IDE

```json
// .cursor/mcp.json
{
  "mcpServers": {
    "cakemail-kb": {
      "type": "streamable-http",
      "url": "https://kb.mcp.cakemail.com/api/mcp",
      "headers": {
        "Authorization": "Basic BASE64_ENCODED_CREDENTIALS"
      }
    }
  }
}
```

## Connect with Continue.dev

```json
// .continue/config.json — add to the "mcpServers" array
{
  "name": "cakemail-kb",
  "type": "streamable-http",
  "url": "https://kb.mcp.cakemail.com/api/mcp",
  "headers": {
    "Authorization": "Basic BASE64_ENCODED_CREDENTIALS"
  }
}
```

## Authentication

Authentication is required. Two methods are supported:

- **Basic Auth** — Base64-encoded `email:password` (recommended for MCP clients)
- **Bearer token** — An access token obtained from the `/api/auth` endpoint

## Available Tools

### `search_knowledge_base`

Semantic search over Cakemail's documentation. Returns the most relevant article chunks with similarity scores, titles, URLs, and content.

**Parameters:**
- `query` (required) — The search query in natural language
- `language` (optional) — Filter results by language: `en`, `fr`, `fr-ca`, `es`
- `limit` (optional) — Number of results to return (default: 5, max: 20)

**Example usage:** "How do I verify a webhook signature?"

### `list_topics`

Browse all available articles and topics in the knowledge base.

**Parameters:**
- `language` (optional) — Filter by language: `en`, `fr`, `fr-ca`, `es`

## Supported languages

The knowledge base contains articles in four languages:

| Code | Language |
|------|----------|
| `en` | English |
| `fr` | French |
| `fr-ca` | French (Canada) |
| `es` | Spanish |

---

# n8n Integration

The Cakemail n8n community node lets you automate email marketing workflows in [n8n](https://n8n.io) — no code required. Connect Cakemail to hundreds of other apps and services.

## Installation

In your n8n instance, go to **Settings → Community Nodes** and install:

```
n8n-nodes-cakemail
```

Or install via npm:

```bash
npm install n8n-nodes-cakemail
```

## Authentication

1. In n8n, go to **Credentials → New Credential → Cakemail API**
2. Enter your Cakemail email and password
3. Click **Test** to verify the connection

## Available resources

The node covers the entire Cakemail API with 30+ resources:

| Resource | Operations |
|----------|-----------|
| **Campaign** | List, create, get, update, delete, schedule, send test, render |
| **Contact** | List, create, get, update, delete, import, tag/untag |
| **List** | List, create, get, update, delete, archive |
| **Template** | List, create, get, update, delete, render |
| **Sender** | List, create, get, update, delete, confirm |
| **Webhook** | List, create, get, update, archive, unarchive |
| **Email API** | Send transactional email, check status, view logs |
| **Report** | Campaign stats, email stats, link analytics |
| **Tag** | List, create, get, update, delete |
| **Segment** | List, create, get, update, delete |

Plus: Account, Sub-Account, User, Domain, DKIM, Form, Workflow, and more.

## Example: Welcome email workflow

1. **Trigger**: New contact added (via webhook or polling)
2. **Cakemail node**: Send a transactional welcome email using a template
3. **Wait**: 3 days
4. **Cakemail node**: Add the contact to your newsletter campaign list

## Example: Campaign reporting

1. **Schedule trigger**: Every Monday at 9am
2. **Cakemail node**: Get campaign stats for the past week
3. **Slack node**: Post a summary to your marketing channel

## Multi-account support

If you manage multiple accounts (partner/reseller), use the **Account ID** field in the Additional Fields section of any operation to specify which account to target.

## SDK

The n8n node uses the official `@cakemail-org/cakemail-sdk` under the hood. For custom integrations beyond what n8n offers, see the [SDK documentation](/tools/sdks/typescript).

---

# Zapier Integration

Connect Cakemail to 7,000+ apps with [Zapier](https://zapier.com/apps/cakemail/integrations) — no code required. Automate workflows between Cakemail and your favorite tools.

## Getting started

1. Go to [Cakemail on Zapier](https://zapier.com/apps/cakemail/integrations)
2. Click **Create a Zap**
3. Connect your Cakemail account with email and password
4. Choose a trigger or action

## Triggers

Zapier can start a workflow when something happens in Cakemail:

| Trigger | Description |
|---------|-------------|
| New Contact | A contact is added to a list |
| Contact Unsubscribed | A contact unsubscribes |

## Actions

Zapier can perform actions in Cakemail as part of a workflow:

| Action | Description |
|--------|-------------|
| Create Contact | Add a new contact to a list |
| Send Campaign | Trigger a campaign send |
| Create List | Create a new contact list |

## Popular Zaps

- **Google Sheets → Cakemail**: Add new spreadsheet rows as contacts
- **Typeform → Cakemail**: Subscribe form respondents to a list
- **Shopify → Cakemail**: Add customers as contacts after purchase
- **Slack → Cakemail**: Trigger campaign sends from a Slack message

## Learn more

Visit [Cakemail on Zapier](https://zapier.com/apps/cakemail/integrations) to browse all available triggers, actions, and pre-built templates.

---

# Integration Directory

Cakemail integrates with a growing ecosystem of platforms. Below are partner integrations available through their respective marketplaces.

<CardGrid>
<Card>
<CardHeader>
<CardTitle>Jotform</CardTitle>
<CardDescription>Forms / Lead capture</CardDescription>
</CardHeader>
<CardContent>

Automatically send form submissions to Cakemail lists and keep contacts in sync.

[Visit integration →](https://www.jotform.com/integrations/cakemail)

</CardContent>
</Card>

<Card>
<CardHeader>
<CardTitle>Okta</CardTitle>
<CardDescription>Identity / SSO</CardDescription>
</CardHeader>
<CardContent>

Enable Single Sign-On (SSO) and centralized user management for Cakemail.

[Visit integration →](https://www.okta.com/integrations/cakemail/)

</CardContent>
</Card>

<Card>
<CardHeader>
<CardTitle>Portable</CardTitle>
<CardDescription>Data / Analytics</CardDescription>
</CardHeader>
<CardContent>

Export Cakemail data into data warehouses for analytics and reporting.

[Visit integration →](https://portable.io/connectors/cakemail/luminous)

</CardContent>
</Card>

<Card>
<CardHeader>
<CardTitle>Tarvent</CardTitle>
<CardDescription>Marketing automation</CardDescription>
</CardHeader>
<CardContent>

Connect Cakemail with other marketing tools via automation platforms like Zapier.

[Visit integration →](https://www.tarvent.com/integrations/cakemail)

</CardContent>
</Card>
</CardGrid>

---

# API v1.20

Released between February and April 2026. Current production version. Major focus on OpenAPI spec quality, developer experience, and stability.

## Highlights

### OpenAPI spec enrichment
- Added comprehensive field descriptions across all API domains
- Added error models to the OpenAPI spec
- Tag descriptions for all major API categories
- Operation descriptions for 85%+ of endpoints

### Developer experience
- Token expiration improvements with configurable `expiration_seconds` on MFA challenge and token refresh
- Email subject parameter support
- Tag filtering by date

### Stability
- Fixed "Event Loop is Closed" and "Unclosed client session" errors
- File descriptor collision fix for uvicorn + aiohttp
- Webhook domain validation from configuration

---

# API v1.19

Released between July 2025 and February 2026. 72 releases covering webhooks, forms, caching, and infrastructure improvements.

## Highlights

### Webhook improvements
- Webhook event filtering with Hookdeck integration
- Archive/unarchive webhooks using disable/enable pattern
- Webhook domain validation from configuration
- Event checking on webhook creation

### Forms
- Subscription form endpoints with enable/disable support
- Form impersonation context fixes
- Enhanced form creation and management

### Email API
- Return email address in Email API v2 send response
- Subject parameter support for email sending

### Performance and infrastructure
- Cache with thundering herd protection
- ClickHouse database support
- Hookdeck API upgrades
- Gunicorn timing and timeout defaults
- File descriptor collision fixes

### Authentication
- MFA challenge expiration seconds support
- Token refresh with configurable expiration

---

# Next-gen API v1.18

## Improvements to Webhook Events and Email API Functionality

We’ve enhanced the Webhooks for User.Confirmed, User.Deleted, and User.Created events, expanding their capabilities and fixing several bugs. We also improved tag filtering and resolved issues related to rendering. We made improvements to email tracking for more accurate insights.

For the Email API, we’ve added support for direct thumbnail rendering.

---

# Next-gen API v1.17

## Email API Introduction

Discover our powerful Email API, now with a full-featured UI dashboard for seamless data analysis and insights.

---

# Next-gen API v1.15

## Multi-Factor Authentication (MFA) is now available

Developers can use the new API endpoints to add Authentication Factor in their implementation. A new micro frontend portal is available to support TOTP Authentication Factor. The new methods are available in Next-gen API “token” and “user" classes.

---

# Next-gen API v1.14

> Mandatory DMARC authentication

## What's new

All emails sent by Cakemail will be authenticated with DMARC. Sender email addresses that are not authenticated will be automatically modified to use an authenticated domain. Cakemail is thus implementing the necessary structure to support the best practices and anti-spam policies.

Here is how unauthenticated email addresses are transformed to be authenticated:

👉 Example of an unauthenticated sender's address: [client@gmail.com](mailto:client@gmail.com)  
‍👉 Transformed and authenticated address: client+gmail.com@[authenticated_domain.com]

The domain cmtd1.com will be used to transform sender addresses to ensure authentication and email deliverability.

If the sender address belongs to a client account under a reseller domain that is already authenticated, the emails will be sent with this authenticated domain.

---

# Next-gen API v1.13

Introducing multiple segments selection in campaigns and extending events support.

## What’s new

- We're now allowing multi-attachment support for transactional emails, enabling you to send various file types as png, jpeg, jpg.
- You can define[Interests](https://cakemail.dev/reference/listinterests) to classify and manage your subscribers.
- We have implemented Azure AD authentication for Single Sign-On (SSO) to access the Cakemail API. This feature is available on request for Enterprise accounts only.
- Our library has been updated to ensure enhanced security.

## Bug fixes

- For users experiencing discrepancies in the display of their physical address information, this issue has been resolved by using more detailed information.

---

# Next-gen API v1.12

This release brings you some new major features: **tags**, **campaign log export** and **calendar attachments**.

### Tags

[Tags](ref:tags) give you even more freedom to manage your contacts.

You can tag them [individually](ref:tagcontact) or [collectively](ref:tagmultiplecontacts) using [queries](ref:working-with-segment-queries).

### Campaign Log Export

Now you can [create a CSV export](ref:campaignlogexportcreate) of your campaign logs directly via the API.

### Calendar Attachments for Transactional Emails

When sending out event invitations with [transactional emails](ref:sendemail) you can now add iCal attachments to improve your recipient's experience.

## More Features and Bugfixes

- added an endpoint to [delete your default logo](ref:deletedefaultlogo)
- added support for cursor pagination on [campaign logs](ref:getcampaignlogs)
- added a **subscription_type** field to [list logs](ref:getlistlogs) events so you can also identify who's resubscribing to your list
- added new [webhook](ref:createwebhook) events for [senders](ref:listsenders)
- fixed a pagination issue on [contact listing](ref:listcontactsoflist) causing a contact to be skipped
- fixed a security issue by HTML-escaping all variables used on [system emails](ref:showsystememails).

---

# Next-gen API v1.11

Introducing multiple segments selection in campaigns and extending events support.

## What’s new

- Webhook on Email.Sent events now support automation emails and transactional emails.
- You can now send email campaigns to multiple segments at once.
- System emails now have a Sender language parameter.

## Bug fixes

- There was an issue with the Contact filters that prevented all of the data from being exported. The contact filtering functionality has been disabled for the time being while we work on improving it.
- In some cases, emails without links were not sent. This issue has been resolved.
- We fixed the Sender name personalization tag in the system emails.

---

# Next-gen API v1.10

You can now export your contacts and two [new webhooks](https://cakemail.dev/reference/createwebhook), and more.

## Contact export

- You can easily export your contacts from Cakemail.
- You can export contacts from a list or a segment of your audience.  You can also apply the same filters as used on the Contact List resource.
- A powerful asynchronous system supports the new Contact Export feature; first, you [start](https://cakemail.dev/reference/exportcontacts) the Contact Export then you [follow its progress](https://cakemail.dev/reference/getcontactsexport) until it is ready to [download](https://cakemail.dev/reference/downloadcontactsexport).

## New Features

- Contact Export - you can [export contacts](https://cakemail.dev/reference/exportcontacts) to CSV
- Two [new webhooks](https://cakemail.dev/reference/createwebhook) related to Contact Export
- Partners can [change the monthly statistics reset date](https://cakemail.dev/reference/patchaccount) of their sub-accounts
- Cursor pagination for [Contact List](https://cakemail.dev/reference/listcontactsoflist), dramatically increasing the pagination speed for enormous Contact Lists
- New Tasks API to [list and inspect asynchronous tasks](https://cakemail.dev/reference/listtasks), currently only listing Contact Exports. Future asynchronous tasks will be included there as they are released.
- For select Partners integrating Cakemail as part of their software offering, we now allow [skipping the initial email verification](https://cakemail.dev/reference/createaccount) when creating a sub-account.  If you are interested, please contact support.

## Bug Fixes

- Fixed a bug where the Email Log type was incorrectly returned as null.
- Fixed a bug where an account's phone, fax and website could not be emptied using 'null' as value.
- Improved clickthru statistic calculations.

---

# Next-gen API v1.9

Improvements in segments, feedback loops and bounce processing, and more.

## Feedback Loops

- We’ve improved the performance of feedback loop and bounce processing.
- A new webhook can be triggered when a spam complaint is received through a feedback loop:  
-- Email.ReportedAsSpam

## Improvements

- Segments can now be sorted by creation date. You can also sort them by name and ID.
- You can now reschedule a campaign or delete an incomplete campaign.
- We have improved the way we report errors and exceptions to help you better understand the issues.
- Automations are now stopped as soon as they are deactivated, preventing all subscribers from receiving emails until they are reactivated.

## Bug Fixes

- The company name in the profile(account) is now stored as text without encoding
- We’ve improved the performance and reliability of our event processing system.  
- Security improvements have been made

## Status Page

- We've released a new status page where you can get real-time information on the activity of all our applications and systems. You can also sign up to receive updates via email.

  [Discover the status page](https://status.cakemail.com/).

---

# Next-gen API v1.8

## Support for more webhook events

### Adding more webhooks

More events can trigger webhooks. Indeed, you can define callbacks when audience resources (lists, segments and contacts) are added, removed or updated. You can also define triggering webhooks upon campaign delivery or actions, such as when subscribers open emails and click a link in emails sent from automation, campaigns or transactional emails.

[How to create and manage Webhooks](https://cakemail.dev/v1.6/docs/using-webhooks)  
[Webhook API reference](https://cakemail.dev/v1.6/reference#webhooks)

### Usage of role-based email addresses

It is now possible to use role-based email addresses as a user or sender. A role-based email address is usually a corporate address that is not associated with a single, specific person, such as sales@ info@ or team@ email addresses.

[Role-based emails](https://support.cakemail.com/hc/en-us/articles/360056244474-Role-based-emails).

---

# Next-gen API v1.7

New functionalities through Webhooks and SMTP Endpoint

### Email bounce webhook events are now available

Webhooks can now be triggered on email bounce events.

More events will be supported in future releases.

[How to create and manage Webhooks](https://cakemail.dev/v1.6/docs/using-webhooks)  
[Webhook API reference](https://cakemail.dev/v1.6/reference#webhooks)

### Additional email headers for transactional emails

We now allow additional headers to be added to transactional emails. These headers are also added as metadata in the logs. This gives developers additional flexibility to include more context from which the email was initiated, which can be useful later when processing data or debugging.

When using the [Transactional SMTP API](https://cakemail.dev/reference#smtp-relay), the original envelope-from value will be copied into the x-sender-envelope-from header and the original return-path value into the x-original-return-path header.

---

# Next-gen API v1.6

Introducing webhook events

## Webhooks

"User-defined HTTP callbacks" can now be configured on events on accounts, campaigns, contacts, emails and users. The payload sent with them can be interpreted by your web services and 3rd party web services, therefore, augmenting your Cakemail integration.

Usage examples: a developer could improve the audit trail by logging different events on user accounts, or, when a contact is updated, a row could be synchronized in a Google sheet.

Webhooks can now be triggered on most events. For example: when an account is created, updated or deleted, or when a contact is added to a list or unsubscribe, or when a transactional email is sent. The complete events list is available in the documentation.

[How to create and manage Webhooks](https://cakemail.dev/docs/using-webhooks)  
[Webhook API reference](https://cakemail.dev/v1.6/reference#webhooks)

## Customizable system emails for white label resellers

System emails have been redesigned. White label resellers can now customize their own system emails.

[System emails API reference (Limited to qualified partners)](https://cakemail.dev/v1.6/reference#system-emails).

---

# Next-gen API v1.5

The SMTP endpoint is now simpler to use!

The _x-sender-id_ header is no longer required; when omitted, the _envelope mail from_ will be used to select the confirmed sender.  Confirm your sender in advance, and you are good to go!

For more details, see the [updated reference article](https://cakemail.dev/reference#smtp-relay).

## Branded System Emails

Emails for various confirmation needs (sub-account confirmation, user confirmation, sender confirmation, and reset password) can now be customized to your brand colours.  Prepare a template, attach it (with a sender) to one of the four customizable system emails.

## Template Tags

You can now add arbitrary tags to your templates for easy classification and filtering.

## More features and bugfixes

- Filter templates by name
- Enumerate the tracked links of your automation Actions
- HTML render endpoint for Campaign Blueprints
- Transactional emails are blocked if your account reaches its limits, avoiding surcharges
- All new lists are double opt-in
- Fixed a bug where a Form creation would fail with a generic error if the list policy is not accepted. Now, the API returns a clear error.
- Allow sending the double opt-in/welcome email when adding a contact via the API.  Useful if you collect emails instead of using the Forms.
- The return parameter `thumbnail` is now deprecated and will be removed in a future release. The return parameter `thumbnail` has been replaced by `thumbnail_url`.

---

# Next-gen API v1.4

600 Campaign Blueprints and new search functionalities in this release

- Blueprints! You now have access to more than 600 Campaign Blueprints to use as a starting point for your next email campaign.  
  Access [API documentation for Campaign Blueprints](https://cakemail.dev/v1.4.0/reference#campaign-blueprint)

Plus, a few more features and changes:

- Apply tags to Templates for easy categorization [API documentation for Campaign Blueprints](https://cakemail.dev/v1.4.0/reference#listcampaignblueprints)
- Search Templates by name and tags  [API documentation for Templates](https://cakemail.dev/v1.4.0/reference#template)
- Search Transaction Email logs by email [API documentation for logs Transactional Email](https://cakemail.dev/v1.4.0/reference#log-1)
- Usage of "-,\_" characters in Custom Attributes name is now allowed [API documentation for Account Custom Attributes](https://cakemail.dev/v1.4.0/reference#custom-attribute)  
  Finally, some minor bug fixes and invisible changes:
- Rate limiting on key endpoints, protecting the API and the sending reputation of your account.  On infrequent circumstances, the API can now return HTTP 429.

---

# Next-gen API v1.3

This is the first release of the email automation offering of the Cakemail Next-gen API.

This release adds automation workflow capability to the Cakemail API, which enables automated email campaigns and notifications.

Workflow automation can be used to simplify recurring processes and set up contingency-based email campaigns. Automated workflows are typically triggered by an action and move or transform data according to predefined rules. For example, an automation process can be set up for when a new customer creates a trial account in your application, to send a series of onboarding emails to the new client to guide them through the application with the appropriate documentation.

You can now:

- Trigger actions such as emails based on recipient events on previous actions such as openings, clicks, or sends.
- Plan onboarding email series and drip campaigns.

More actions, events and capabilities will be available in future releases.

- Access [API documentation for workflows](https://cakemail.dev/reference#workflow)
- Access [API documentation for actions](https://cakemail.dev/reference#action) within workflows  
  You don’t know much about Automation? Start with our guide [Automating your emails](https://cakemail.dev/docs/automating-your-emails) to understand and deploy automation workflows.

---

# Next-gen API v1.2

This release improves the security related to account creation.

When an account or user is created, an email containing a validation link is sent to the email address provided. The account is only made fully active when this validation link is clicked.

Google Location is used to automatically verify the physical address of the account.

---

# Next-gen API v1.1

Introducing dynamic email templates and contact segmentation using Feed Item Query Language (FIQL) and JSON

## Dynamic email templates

You can now store and use your templates to send campaigns and transactional emails.

Transactional emails can be personalized and sent by providing your custom attributes in a JSON format.  
You can manage your template library, use a template in a campaign and use a template in a transactional email

- Access [Email Template documentation](https://cakemail.dev/reference#template)
- Read our guide on [sending transactional emails using templates](https://cakemail.dev/docs/using-templates#using-a-template-with-transactional-emails)

## Contact segmentation using Feed Item Query Language (FIQL) and JSON query language

The Feed Item Query Language (FIQL, pronounced “fickle”) is a simple but flexible, URI-friendly syntax for expressing filters across the entries in syndicated feed entries.

On top of that, we added support for JSON query language in a format similar to ElasticSearch queries.

- [Learn more about FIQL](https://fiql-parser.readthedocs.io/en/stable/index.html)
- [Learn more about JSON](https://www.json.org/json-en.html)
- View examples of contact segmentation in section [Working with segment queries](https://cakemail.dev/reference#working-with-segment-queries).

---

# Next-gen API v1.0

Introducing the Cakemail Next-gen APIs, allowing you to send transactional emails, deploy email marketing campaigns, manage and segment contacts, report analytics, and much more. All emails are routed through our infrastructure, ensuring optimal performance and deliverability.

### OpenAPI for easy integration

Next-gen APIs are based on OpenAPI specifications, giving developers access to all API parameters and easy integration paths. Based on the new Restful and CORS (Cross Origins Request Server) API standards, OpenAPI offers flexibility and power. There’s no need to request a user key — any Cakemail customer can start using the APIs right away. Documentation is available at: [Cakemail API Documentation](https://cakemail.dev).

### A more extensive and interactive API Reference

Find all the information you need, thanks to an extensive and detailed API Reference. You’ll be able to test all API functions directly in the documentation to see exactly what the Next-gen APIs can do before you start your integration.

### In-depth integration guides

Real-life examples help you understand how you can connect the Cakemail APIs to your application.

### Custom subscription forms

Build your email lists your way using the new Form API to create custom subscription forms and define opt-in parameters.

### Dedicated Partner API

Partners and resellers are Cakemail's core business. To support you, we’ve built a new, dedicated Partner API that allows you to provision, configure, manage, and monitor sub-accounts.

Limited to qualified partners, the Partner API allows resellers to support their clients by carrying out all operations offered by the Cakemail APIs — including list syncing, campaign management, and logs access.

### Sender identity management and authentication

The Account API now includes new resources for managing sender identity and authentication — both of which are critical to ensuring your communications reach subscribers' inboxes.

The resources provided through sender identities management enable you to create one or more verified senders for all your Cakemail accounts. The simple process of implementing sender authentication will have a considerable positive impact on your delivery performance.

### High-capacity & optimized transactional email delivery

The Transactional API now allows you to send your emails via the SMTP protocol, taking advantage of Cakemail's high-capacity servers, optimized IP addresses, delivery monitoring, and email optimization systems. You’ll also be able to optimize email performance by monitoring transactional email logs and metrics through the Analytics API.

No need to code: simply connect your app to the Transactional API via the SMTP protocol and start sending transactional emails via our servers through your Cakemail account.

### Higher security standards

Next-gen APIs ship with higher security standards. We have chosen the OAuth 2.0 authentication standard for all API calls, which delivers higher security than the usual user key-password combination — removing the risk of having a static key waiting indefinitely on your server.

The Cakemail APIs are also fully hosted in Canada, which means Canadian privacy laws and protocols govern your data.

Cakemail Next-gen APIs include:

### Authentication API

Secure access to the APIs and your resources.

### Campaign API

Create and manage your email communications.

### Contact API

Manage your contacts, your lists, and your lists’ segments.

### Transactional API

Send an individual one time email. Use the SMTP relay if you don’t want to code.

### Analytics API

Access your lists, campaigns, and transactional email logs and reports.

### Asset API

Define and manage your forms and opt-in details.

### Brand API

Set-up your company logo and domain. Define and authenticate your senders.

### Account API

Define and manage accounts and users.

### Partner API

Manage sub-accounts. Limited to qualified partners.
