# Lettermint

> Send transactional email one at a time or in batches of up to 500, follow each message's delivery events, read sending statistics, and manage sending domains, webhooks and the suppression list.

App · 20 actions. Web page: https://docs.lodol.com/docs/integrations/lettermint

## Actions

### Add suppressions

Stop Lettermint sending to up to 1,000 addresses, for the whole team or one project. Addresses already suppressed are skipped.

**Inputs**

- Addresses (`emails`, list, required): The addresses to suppress.
- Reason (`reason`, text): Why they are suppressed. One of: `manual` (Added manually), `unsubscribe`, `hard_bounce` (Hard bounce), `spam_complaint` (Spam complaint). Default: `manual`.
- Applies across (`scope`, text): The whole team, one project, or one route. One of: `team` (Whole team), `project` (One project), `route` (One route). Default: `team`.
- Project (`project_id`, text): The project to suppress them in. Only when Applies across is One project.
- Route ID (`route_id`, text): The id of the route to suppress them in. Only when Applies across is One route.
- Block (`applies_to`, text): All email, or only broadcasts (transactional email still goes through). One of: `all` (All email), `broadcast` (Broadcasts only).

**Outputs**

- `created` (list)
- `created_count` (number)
- `message` (text)
- `skipped` (list)
- `skipped_count` (number)

**Example output**

```json
{
  "created": [
    "blocked@example.com"
  ],
  "created_count": 1,
  "message": "Suppression processed.",
  "skipped": [],
  "skipped_count": 0
}
```

### Create domain

Add a sending domain. Returns the DNS records to publish at your DNS provider before verifying it. The Free plan allows one domain.

**Inputs**

- Domain (`domain`, text, required): The domain to send from, e.g. mail.example.com.

**Outputs**

- `created_at` (text)
- `dkim_mode` (text)
- `dns_records` (list)
- `domain` (text)
- `id` (text)
- `projects` (list)
- `rotation_ready` (true/false)
- `status_changed_at` (text)

**Example output**

```json
{
  "created_at": "2026-10-01T09:30:00.000000Z",
  "dkim_mode": "managed_cname",
  "dns_records": [
    {
      "content": "lm1._domainkey.lettermint.co",
      "fqdn": "lm1._domainkey.example.com",
      "hostname": "lm1._domainkey",
      "id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
      "last_checked_at": null,
      "purpose": "dkim_primary",
      "required_for_verification": true,
      "status": "pending",
      "type": "CNAME",
      "verification_scope": "required",
      "verified_at": null
    }
  ],
  "domain": "example.com",
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "projects": [
    {
      "id": "9a1f3c2e-4b5d-4e6f-8a7b-1c2d3e4f5a6b",
      "name": "Production"
    }
  ],
  "rotation_ready": false,
  "status_changed_at": null
}
```

### Create webhook

Have Lettermint call a URL when messages are delivered, bounce, are opened and so on. Returns the signing secret - the only time Lettermint shows it.

**Inputs**

- Name (`name`, text, required): A name to recognise it by.
- URL (`url`, text, required): The address Lettermint calls, e.g. https://example.com/hooks/lettermint.
- Events (`events`, text, required): The events that call the URL. One or more of: `message.created` (Message created), `message.sent` (Message sent), `message.delivered` (Message delivered), `message.auto_replied` (Message auto-replied), `message.hard_bounced` (Message hard bounced), `message.soft_bounced` (Message soft bounced), `message.spam_complaint` (Spam complaint), `message.failed` (Message failed), `message.suppressed` (Message suppressed), `message.unsubscribed` (Recipient unsubscribed), and 11 more.
- Enabled (`enabled`, true/false): Start sending events straight away. Default: `true`.
- Include machine events (`include_machine_events`, true/false): Also send opens and clicks made by mail scanners and proxies.
- Messages (`delivery_mode_filter`, text): Live messages, sandbox messages, or both. One of: `live` (Live messages), `sandbox` (Sandbox messages), `both`.
- Applies to (`scope`, text): Events from the whole team, chosen projects, or chosen routes. Defaults to the whole team. One of: `team` (Whole team), `project` (Chosen projects), `route` (Chosen routes).
- Projects (`project_ids`, text): The projects whose events it receives. Only when Applies to is Chosen projects.
- Route IDs (`route_ids`, list): The ids of the routes whose events it receives. Only when Applies to is Chosen routes.
- Basic auth username (`basic_auth_username`, text): If your endpoint needs HTTP basic auth.
- Basic auth password (`basic_auth_password`, text): The password for that username.

**Outputs**

- `created_at` (text)
- `delivery_mode_filter` (text)
- `enabled` (true/false)
- `events` (list)
- `has_basic_auth` (true/false)
- `id` (text)
- `include_machine_events` (true/false)
- `last_called_at` (text)
- `message` (text)
- `name` (text)
- `project_ids` (list)
- `route_ids` (list)
- `scope` (text)
- `secret` (text)
- `updated_at` (text)
- `url` (text)

**Example output**

```json
{
  "created_at": "2026-10-01T09:30:00.000000Z",
  "delivery_mode_filter": "live",
  "enabled": true,
  "events": [
    "message.delivered",
    "message.hard_bounced"
  ],
  "has_basic_auth": false,
  "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
  "include_machine_events": false,
  "last_called_at": null,
  "message": "Webhook created.",
  "name": "Delivery events",
  "project_ids": [],
  "route_ids": [],
  "scope": "team",
  "secret": "whsec_7f3a9c1e5b2d4f6a8c0e",
  "updated_at": "2026-10-01T09:30:00.000000Z",
  "url": "https://example.com/hooks/lettermint"
}
```

### Delete domain

Remove a sending domain from Lettermint.

**Inputs**

- Domain (`domain_id`, text, required): The sending domain. Pick one, or paste its id.

**Outputs**

- `deleted` (true/false)
- `domain_id` (text)
- `message` (text)

**Example output**

```json
{
  "deleted": true,
  "domain_id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "message": "Domain deleted."
}
```

### Delete webhook

Delete a webhook and its delivery history.

**Inputs**

- Webhook (`webhook_id`, text, required): The webhook. Pick one, or paste its id.

**Outputs**

- `deleted` (true/false)
- `message` (text)
- `webhook_id` (text)

**Example output**

```json
{
  "deleted": true,
  "message": "Webhook deleted.",
  "webhook_id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9"
}
```

### Get domain

Get a sending domain with the DNS records to publish and each record's verification status.

**Inputs**

- Domain (`domain_id`, text, required): The sending domain. Pick one, or paste its id.
- Include DNS records (`include_dns_records`, true/false): Return the DNS records and their status. Default: `true`.
- Include projects (`include_projects`, true/false): Return the projects that use the domain. Default: `true`.

**Outputs**

- `created_at` (text)
- `dkim_mode` (text)
- `dns_records` (list)
- `domain` (text)
- `id` (text)
- `projects` (list)
- `rotation_ready` (true/false)
- `status_changed_at` (text)

**Example output**

```json
{
  "created_at": "2026-10-01T09:30:00.000000Z",
  "dkim_mode": "managed_cname",
  "dns_records": [
    {
      "content": "lm1._domainkey.lettermint.co",
      "fqdn": "lm1._domainkey.example.com",
      "hostname": "lm1._domainkey",
      "id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
      "last_checked_at": null,
      "purpose": "dkim_primary",
      "required_for_verification": true,
      "status": "pending",
      "type": "CNAME",
      "verification_scope": "required",
      "verified_at": null
    }
  ],
  "domain": "example.com",
  "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "projects": [
    {
      "id": "9a1f3c2e-4b5d-4e6f-8a7b-1c2d3e4f5a6b",
      "name": "Production"
    }
  ],
  "rotation_ready": false,
  "status_changed_at": null
}
```

### Get message

Get one message: its status, sender, recipients, tags, metadata, attachments and spam score.

**Inputs**

- Message ID (`message_id`, text, required): The message's id, as returned by Send email or List messages, or copied from the message's page in Lettermint.

**Outputs**

- `attachments` (list)
- `bcc` (list)
- `cc` (list)
- `created_at` (text)
- `delivery_mode` (text)
- `from_email` (text)
- `from_name` (text)
- `id` (text)
- `metadata` (object)
- `reply_to` (list)
- `route_id` (text)
- `sandbox_result` (text)
- `scheduled_at` (text)
- `spam_score` (number)
- `spam_symbols` (list)
- `status` (text)
- `status_changed_at` (text)
- `subject` (text)
- `tag` (text)
- `tags` (list)
- `to` (list)
- `type` (text)

**Example output**

```json
{
  "attachments": [],
  "bcc": null,
  "cc": null,
  "created_at": "2026-10-01T09:30:00.000000Z",
  "delivery_mode": "live",
  "from_email": "onboarding@lettermint.dev",
  "from_name": "Acme",
  "id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
  "metadata": {
    "order_id": "1001"
  },
  "reply_to": null,
  "route_id": "2f3e4d5c-6b7a-4980-a1b2-c3d4e5f6a7b8",
  "sandbox_result": null,
  "scheduled_at": null,
  "spam_score": 0.4,
  "spam_symbols": [],
  "status": "delivered",
  "status_changed_at": "2026-10-01T09:30:04.000000Z",
  "subject": "Your receipt",
  "tag": "receipts",
  "tags": [
    {
      "name": "__lettermint_tag",
      "value": "receipts"
    }
  ],
  "to": [
    {
      "email": "ok@lettermint.dev",
      "name": null,
      "sandbox_result": null
    }
  ],
  "type": "outbound"
}
```

### Get sending statistics

Get totals and a day-by-day count of emails sent, delivered, bounced, complained about, opened and clicked, for up to 90 days. Defaults to the last 7 days.

**Inputs**

- From (`from_date`, date): First day. Defaults to 6 days before To.
- To (`to_date`, date): Last day. Defaults to today (UTC).
- Project (`project_id`, text): Only this project - adds a transactional/broadcast breakdown. Pick one, or paste its id.
- Include machine opens and clicks (`include_machine`, true/false): Count opens and clicks made by mail scanners too.

**Outputs**

- `daily` (list)
- `from` (text)
- `to` (text)
- `totals` (object)

**Example output**

```json
{
  "daily": [
    {
      "broadcast": null,
      "clicked": null,
      "date": "2026-10-01",
      "delivered": 12,
      "effective_opened": null,
      "hard_bounced": 0,
      "human_opened": null,
      "inbound": {
        "received": 0
      },
      "machine_clicked": null,
      "machine_opened": null,
      "observed_opened": null,
      "opened": null,
      "privacy_opened": null,
      "sent": 12,
      "spam_complaints": 0,
      "transactional": null
    }
  ],
  "from": "2026-10-01",
  "to": "2026-10-07",
  "totals": {
    "broadcast": null,
    "clicked": null,
    "delivered": 12,
    "effective_opened": null,
    "hard_bounced": 0,
    "human_opened": null,
    "inbound": {
      "received": 0
    },
    "machine_clicked": null,
    "machine_opened": null,
    "observed_opened": null,
    "opened": null,
    "privacy_opened": null,
    "sent": 12,
    "spam_complaints": 0,
    "transactional": null
  }
}
```

### Get webhook

Get a webhook's URL, events, scope and status.

**Inputs**

- Webhook (`webhook_id`, text, required): The webhook. Pick one, or paste its id.

**Outputs**

- `created_at` (text)
- `delivery_mode_filter` (text)
- `enabled` (true/false)
- `events` (list)
- `has_basic_auth` (true/false)
- `id` (text)
- `include_machine_events` (true/false)
- `last_called_at` (text)
- `name` (text)
- `project_ids` (list)
- `route_ids` (list)
- `scope` (text)
- `updated_at` (text)
- `url` (text)

**Example output**

```json
{
  "created_at": "2026-10-01T09:30:00.000000Z",
  "delivery_mode_filter": "live",
  "enabled": true,
  "events": [
    "message.delivered",
    "message.hard_bounced"
  ],
  "has_basic_auth": false,
  "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
  "include_machine_events": false,
  "last_called_at": null,
  "name": "Delivery events",
  "project_ids": [],
  "route_ids": [],
  "scope": "team",
  "updated_at": "2026-10-01T09:30:00.000000Z",
  "url": "https://example.com/hooks/lettermint"
}
```

### List domains

List sending domains and their verification status.

**Inputs**

- Domain contains (`domain`, text): Part of the domain name.
- Status (`status`, text): Only domains in this verification status. One of: `verified`, `partially_verified` (Partially verified), `pending_verification` (Pending verification), `failed_verification` (Failed verification).
- Project (`project_id`, text): Only this project. Pick one, or paste its id.
- Sort by (`sort`, text): How to order the domains. One of: `domain` (Domain A-Z), `-created_at` (Newest first), `created_at` (Oldest first), `-status_changed_at` (Most recent status change first).
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `domains` (list)
- `has_more` (true/false)
- `next_cursor` (text)

**Example output**

```json
{
  "count": 1,
  "domains": [
    {
      "created_at": "2026-10-01T09:30:00.000000Z",
      "dkim_mode": "managed_cname",
      "domain": "example.com",
      "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
      "status": "verified",
      "status_changed_at": "2026-10-01T09:30:00.000000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

### List message events

List a message's delivery timeline: queued, delivered, bounced, opened, clicked and so on, with timestamps.

**Inputs**

- Message ID (`message_id`, text, required): The message's id, as returned by Send email or List messages, or copied from the message's page in Lettermint.
- Include machine events (`include_machine_events`, true/false): Also list opens and clicks made by mail scanners and proxies.
- Order (`sort`, text): Oldest or newest event first. One of: `timestamp` (Oldest first), `-timestamp` (Newest first).
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `events` (list)
- `has_more` (true/false)
- `next_cursor` (text)

**Example output**

```json
{
  "count": 1,
  "events": [
    {
      "event": "delivered",
      "message_id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
      "metadata": null,
      "tag": "receipts",
      "tags": [],
      "timestamp": "2026-10-01T09:30:04.000000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
```

### List messages

List sent and received messages, newest first, filtered by status, sender, subject, tag, project, domain or date.

**Inputs**

- Search (`search`, text): Find messages by address or subject.
- Status (`status`, text): Only messages in this status. One of: `scheduled`, `pending`, `queued`, `quarantined`, `suppressed`, `processed`, `delivered`, `opened`, `clicked`, `soft_bounced` (Soft bounced), and 7 more.
- Direction (`message_type`, text): Only sent or only received messages. One of: `outbound` (Outbound (sent)), `inbound` (Inbound (received)).
- Sender contains (`from_email`, text): Part of the sender address.
- Subject contains (`subject`, text): Part of the subject.
- Tag (`tag`, text): Only messages with exactly this tag. Use _none for untagged.
- Tag pairs (`tags`, object): Only messages carrying every one of these name/value tags.
- Project (`project_id`, text): Only this project. Pick one, or paste its id.
- Domain (`domain_id`, text): Only messages sent from this domain.
- Created on or after (`from_date`, date): Earliest creation date.
- Created on or before (`to_date`, date): Latest creation date.
- Sort by (`sort`, text): How to order the messages. One of: `-created_at` (Newest first), `created_at` (Oldest first), `-status_changed_at` (Most recent status change first), `subject` (Subject A-Z), `from_email` (Sender A-Z), `status` (Status A-Z). Default: `-created_at`.
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `messages` (list)
- `next_cursor` (text)

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "messages": [
    {
      "bcc": null,
      "cc": null,
      "created_at": "2026-10-01T09:30:00.000000Z",
      "delivery_mode": "live",
      "from_email": "onboarding@lettermint.dev",
      "from_name": "Acme",
      "id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
      "reply_to": null,
      "sandbox_result": null,
      "scheduled_at": null,
      "spam_score": 0.4,
      "status": "delivered",
      "status_changed_at": "2026-10-01T09:30:04.000000Z",
      "subject": "Your receipt",
      "tag": "receipts",
      "tags": [
        {
          "name": "__lettermint_tag",
          "value": "receipts"
        }
      ],
      "to": [
        {
          "email": "ok@lettermint.dev",
          "name": null,
          "sandbox_result": null
        }
      ],
      "type": "outbound"
    }
  ],
  "next_cursor": null
}
```

### List projects

List the team's projects with their message volumes and deliverability over the last 28 days.

**Inputs**

- Search (`search`, text): Find projects by name.
- Sort by (`sort`, text): How to order the projects. One of: `name` (Name A-Z), `-created_at` (Newest first), `created_at` (Oldest first).
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `next_cursor` (text)
- `projects` (list)

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "next_cursor": null,
  "projects": [
    {
      "created_at": "2026-10-01T09:30:00.000000Z",
      "delivery_mode": "live",
      "domains_count": 1,
      "id": "9a1f3c2e-4b5d-4e6f-8a7b-1c2d3e4f5a6b",
      "last_28_days": {
        "deliverability": 99.2,
        "messages_broadcast": 0,
        "messages_inbound": 0,
        "messages_transactional": 120
      },
      "name": "Production",
      "routes_count": 2,
      "smtp_enabled": false,
      "updated_at": "2026-10-01T09:30:00.000000Z"
    }
  ]
}
```

### List suppressions

List the addresses Lettermint will not send to - bounces, spam complaints, unsubscribes and manual blocks.

**Inputs**

- Address contains (`value`, text): Part of the address.
- Reason (`reason`, text): Only suppressions for this reason. One of: `spam_complaint` (Spam complaint), `hard_bounce` (Hard bounce), `unsubscribe`, `manual` (Added manually), `disposable_email` (Disposable email).
- Scope (`scope`, text): Only suppressions at this level. One of: `team` (Whole team), `project` (One project), `route` (One route).
- Project (`project_id`, text): Only this project. Pick one, or paste its id.
- Added on or after (`start_date`, date): Earliest date.
- Added on or before (`end_date`, date): Latest date.
- Sort by (`sort`, text): How to order the suppressions. One of: `-created_at` (Newest first), `created_at` (Oldest first), `value` (Address A-Z), `reason` (Reason A-Z). Default: `-created_at`.
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `next_cursor` (text)
- `suppressions` (list)

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "next_cursor": null,
  "suppressions": [
    {
      "applies_to": "all",
      "created_at": "2026-10-01T09:30:00.000000Z",
      "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
      "project_id": null,
      "reason": "hard_bounce",
      "route_id": null,
      "scope": "team",
      "source_message": null,
      "type": "email",
      "value": "bounced@example.com"
    }
  ]
}
```

### List webhooks

List webhooks with their URL, events and status.

**Inputs**

- Search (`search`, text): Find webhooks by name or URL.
- Status (`enabled`, text): Only enabled or only disabled webhooks. One of: `enabled`, `disabled`.
- Event (`event`, text): Only webhooks that receive this event. One of: `message.created` (Message created), `message.sent` (Message sent), `message.delivered` (Message delivered), `message.auto_replied` (Message auto-replied), `message.hard_bounced` (Message hard bounced), `message.soft_bounced` (Message soft bounced), `message.spam_complaint` (Spam complaint), `message.failed` (Message failed), `message.suppressed` (Message suppressed), `message.unsubscribed` (Recipient unsubscribed), and 11 more.
- Scope (`scope`, text): Only webhooks at this level. One of: `team` (Whole team), `project` (Chosen projects), `route` (Chosen routes).
- Project (`project_id`, text): Only this project. Pick one, or paste its id.
- Sort by (`sort`, text): How to order the webhooks. One of: `-created_at` (Newest first), `created_at` (Oldest first), `name` (Name A-Z), `url` (URL A-Z).
- Page size (`page_size`, number): How many to return on this page. From 1 to 100.
- Page cursor (`cursor`, text): The next_cursor from a previous page. Leave empty for the first page.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `next_cursor` (text)
- `webhooks` (list)

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "next_cursor": null,
  "webhooks": [
    {
      "created_at": "2026-10-01T09:30:00.000000Z",
      "delivery_mode_filter": "live",
      "enabled": true,
      "events": [
        "message.delivered",
        "message.hard_bounced"
      ],
      "has_basic_auth": false,
      "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
      "last_called_at": null,
      "name": "Delivery events",
      "project_ids": [],
      "route_ids": [],
      "scope": "team",
      "updated_at": "2026-10-01T09:30:00.000000Z",
      "url": "https://example.com/hooks/lettermint"
    }
  ]
}
```

### Remove suppression

Let Lettermint send to a suppressed address again. A spam complaint is sent to Lettermint support for review instead of being removed - removed tells you which happened.

**Inputs**

- Suppression ID (`suppression_id`, text, required): The suppression's id, from List suppressions.

**Outputs**

- `message` (text)
- `removed` (true/false)
- `status` (text)
- `suppression_id` (text)
- `ticket_identifier` (text)

**Example output**

```json
{
  "message": "Suppression removed.",
  "removed": true,
  "status": "removed",
  "suppression_id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d",
  "ticket_identifier": null
}
```

### Send batch emails

Send up to 500 emails in one request: either the same email to each recipient separately, or a list of different emails. Returns one message id per email, in order.

**Inputs**

- Recipients (`recipients`, list): Send the email below to each of these addresses separately (they do not see each other).
- From (`sender`, text): The sender, as an address or Name <address>, on a domain verified in Lettermint. Until you verify one, use Your App <onboarding@lettermint.dev>, which can send to your team's verified members and test addresses such as ok@lettermint.dev.
- Subject (`subject`, text): The subject line.
- HTML body (`html`, text): The email as HTML. Give this, a text body, or both.
- Text body (`text`, text): The plain-text version. Give this, an HTML body, or both.
- Tag (`tag`, text): A label to find these emails by later (letters, digits, - and _), e.g. password-reset.
- Emails (advanced) (`emails`, list): A list of email objects, each with from, to, subject and html and/or text, plus any of cc, bcc, reply_to, tag, tags, metadata, headers, route and scheduled_at - e.g. [{"from": "Acme <hello@acme.com>", "to": ["a@example.com"], "subject": "Hi", "text": "Hello there"}]. Leave empty to send one email to each recipient below instead.
- Idempotency key (`idempotency_key`, text): Optional. Lettermint ignores a repeat with the same key and body for 24 hours, so a retried step cannot send twice. Use something unique to this email, such as an order id.

**Outputs**

- `count` (number)
- `messages` (list)

**Example output**

```json
{
  "count": 1,
  "messages": [
    {
      "message_id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
      "status": "pending"
    }
  ]
}
```

### Send email

Send one email to up to 50 recipients, with an optional attachment, tags and metadata. Returns the message id to follow its delivery.

**Inputs**

- From (`sender`, text, required): The sender, as an address or Name <address>, on a domain verified in Lettermint. Until you verify one, use Your App <onboarding@lettermint.dev>, which can send to your team's verified members and test addresses such as ok@lettermint.dev.
- To (`to`, list, required): One or more recipients, as addresses or Name <address>.
- Subject (`subject`, text, required): The subject line.
- HTML body (`html`, text): The email as HTML. Give this, a text body, or both.
- Text body (`text`, text): The plain-text version. Give this, an HTML body, or both.
- Cc (`cc`, list): Copy these recipients.
- Bcc (`bcc`, list): Blind-copy these recipients.
- Reply to (`reply_to`, list): Where replies should go.
- Attachment (`attachment`, text): A file to attach.
- Attachment file name (`attachment_name`, text): The name the recipient sees, e.g. invoice.pdf. Defaults to the uploaded file's name.
- Tag (`tag`, text): A label to find these emails by later (letters, digits, - and _), e.g. password-reset.
- Tag pairs (`tags`, object): Name/value tags to filter by later, e.g. plan = pro (each 1-32 / 1-64 letters, digits, - or _).
- Metadata (`metadata`, object): Your own values stored with the message and sent to your webhooks, not added to the email.
- Custom headers (`headers`, object): Extra email headers, e.g. X-Campaign = autumn.
- Route (`route`, text): The route slug to send through. Leave empty for the project's default route.
- Send at (`scheduled_at`, date and time): Deliver later instead of now. Scheduling needs a Lettermint Growth or Pro plan.
- Track opens (`track_opens`, true/false): Track when the email is opened (paid plans).
- Track clicks (`track_clicks`, true/false): Track clicks on links (paid plans).
- TLS policy (`tls`, text): Whether delivery must use an encrypted connection. One of: `opportunistic` (Opportunistic (use TLS when the receiver offers it)), `enforced` (Enforced (do not deliver without TLS)).
- Idempotency key (`idempotency_key`, text): Optional. Lettermint ignores a repeat with the same key and body for 24 hours, so a retried step cannot send twice. Use something unique to this email, such as an order id.

**Outputs**

- `message_id` (text)
- `scheduled_at` (text)
- `status` (text)

**Example output**

```json
{
  "message_id": "0b1c2d3e-4f5a-4b6c-9d7e-8f9a0b1c2d3e",
  "status": "pending"
}
```

### Update webhook

Change a webhook's name, URL, events, scope or status. Fields left empty are not changed.

**Inputs**

- Webhook (`webhook_id`, text, required): The webhook. Pick one, or paste its id.
- Name (`name`, text): A new name.
- URL (`url`, text): A new address for Lettermint to call.
- Events (`events`, text): Replace the events it receives. One or more of: `message.created` (Message created), `message.sent` (Message sent), `message.delivered` (Message delivered), `message.auto_replied` (Message auto-replied), `message.hard_bounced` (Message hard bounced), `message.soft_bounced` (Message soft bounced), `message.spam_complaint` (Spam complaint), `message.failed` (Message failed), `message.suppressed` (Message suppressed), `message.unsubscribed` (Recipient unsubscribed), and 11 more.
- Status (`enabled`, text): Turn the webhook on or off. One of: `enabled`, `disabled`.
- Machine events (`include_machine_events`, text): Send opens and clicks made by mail scanners and proxies, or not. One of: `enabled`, `disabled`.
- Messages (`delivery_mode_filter`, text): Live messages, sandbox messages, or both. One of: `live` (Live messages), `sandbox` (Sandbox messages), `both`.
- Applies to (`scope`, text): Events from the whole team, chosen projects, or chosen routes. One of: `team` (Whole team), `project` (Chosen projects), `route` (Chosen routes).
- Projects (`project_ids`, text): The projects whose events it receives. Only when Applies to is Chosen projects.
- Route IDs (`route_ids`, list): The ids of the routes whose events it receives. Only when Applies to is Chosen routes.
- Basic auth username (`basic_auth_username`, text): Set new HTTP basic auth credentials.
- Basic auth password (`basic_auth_password`, text): The password for that username.
- Remove basic auth (`remove_basic_auth`, true/false): Stop sending basic auth credentials.

**Outputs**

- `created_at` (text)
- `delivery_mode_filter` (text)
- `enabled` (true/false)
- `events` (list)
- `has_basic_auth` (true/false)
- `id` (text)
- `include_machine_events` (true/false)
- `last_called_at` (text)
- `message` (text)
- `name` (text)
- `project_ids` (list)
- `route_ids` (list)
- `scope` (text)
- `updated_at` (text)
- `url` (text)

**Example output**

```json
{
  "created_at": "2026-10-01T09:30:00.000000Z",
  "delivery_mode_filter": "live",
  "enabled": true,
  "events": [
    "message.delivered",
    "message.hard_bounced"
  ],
  "has_basic_auth": false,
  "id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
  "include_machine_events": false,
  "last_called_at": null,
  "message": "Webhook updated.",
  "name": "Delivery events",
  "project_ids": [],
  "route_ids": [],
  "scope": "team",
  "updated_at": "2026-10-01T09:30:00.000000Z",
  "url": "https://example.com/hooks/lettermint"
}
```

### Verify domain DNS records

Check a domain's DNS records now. Returns verified true or false, with the records that still fail. Lettermint allows only a few checks a minute.

**Inputs**

- Domain (`domain_id`, text, required): The sending domain. Pick one, or paste its id.

**Outputs**

- `domain_id` (text)
- `errors` (list)
- `failed_count` (number)
- `failed_records` (list)
- `message` (text)
- `recommended_failed_records` (list)
- `total_count` (number)
- `verified` (true/false)

**Example output**

```json
{
  "domain_id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
  "errors": [
    {
      "error": "Record not found.",
      "record_id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
    }
  ],
  "failed_count": 1,
  "failed_records": [
    {
      "id": "1d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
      "name": "lm1._domainkey",
      "type": "CNAME"
    }
  ],
  "message": "Some required DNS records could not be verified.",
  "recommended_failed_records": [],
  "total_count": 4,
  "verified": false
}
```
