# Elastic Email

> Send transactional and bulk email with Elastic Email, track delivery, opens and clicks, and manage contacts, lists and templates.

App · 20 actions. Web page: https://docs.lodol.com/docs/integrations/elastic-email

## Actions

### Add contact

Add a contact, optionally putting it on one or more lists. Free accounts can hold up to 1,000 contacts.

**Inputs**

- Email (`email`, text, required): The new contact's email address.
- First name (`first_name`, text): The contact's first name.
- Last name (`last_name`, text): The contact's last name.
- Status (`status`, text): Active contacts can receive marketing email; Transactional ones only transactional email. Leave empty for Elastic Email's default. One of: `Active` (Active - can receive marketing email), `Transactional` (Transactional - transactional email only).
- Custom fields (`custom_fields`, object): Values for the account's custom contact fields. Only fields that already exist in Elastic Email are saved - others are silently dropped.
- Lists (`list_names`, text): Lists to add the contact to.

**Outputs**

- `activity` (object)
- `consent` (object)
- `custom_fields` (object)
- `date_added` (text)
- `date_updated` (text)
- `email` (text)
- `first_name` (text)
- `last_name` (text)
- `lists` (list)
- `source` (text)
- `source_info` (text)
- `status` (text)
- `status_change_date` (text)

**Example output**

```json
{
  "activity": {
    "error_code": null,
    "friendly_error_message": null,
    "last_clicked": "2026-10-02T10:06:00",
    "last_failed": null,
    "last_ip": null,
    "last_opened": "2026-10-02T10:05:00",
    "last_sent": "2026-10-02T10:00:00",
    "total_clicked": 1,
    "total_failed": 0,
    "total_opened": 2,
    "total_sent": 3
  },
  "consent": {
    "date": null,
    "ip": null,
    "tracking": "Unknown"
  },
  "custom_fields": {},
  "date_added": "2026-10-01T09:30:00",
  "date_updated": "2026-10-02T11:00:00",
  "email": "ada@example.com",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "lists": [
    "Newsletter"
  ],
  "source": "ContactApi",
  "source_info": null,
  "status": "Active",
  "status_change_date": null
}
```

### Add contacts to list

Put existing contacts on a list.

**Inputs**

- List (`list_name`, text, required): The list, by its exact name.
- Contact emails (`emails`, list, required): Email addresses of contacts that already exist in Elastic Email (up to 1,000). Use Add contact to create new ones.

**Outputs**

- `emails` (list)
- `list` (object)
- `list_name` (text)

**Example output**

```json
{
  "emails": [
    "ada@example.com"
  ],
  "list": {
    "allow_unsubscribe": true,
    "date_added": "2026-09-15T08:00:00",
    "name": "Newsletter",
    "public_list_id": "2b6c9d1e-3f4a-4b5c-8d7e-9f0a1b2c3d4e"
  },
  "list_name": "Newsletter"
}
```

### Create list

Create a contact list holding the given existing contacts.

**Inputs**

- List name (`list_name`, text, required): The new list's name.
- Contact emails (`emails`, list): Email addresses of existing contacts to put on the list. Required unless 'Add every contact' is ticked.
- Add every contact (`include_all_contacts`, true/false): Put every contact in the account on the list. Elastic Email does this when no emails are given, so it must be chosen explicitly. Default: `false`.
- Allow unsubscribe (`allow_unsubscribe`, true/false): Let contacts unsubscribe from this list.

**Outputs**

- `allow_unsubscribe` (true/false)
- `date_added` (text)
- `name` (text)
- `public_list_id` (text)

**Example output**

```json
{
  "allow_unsubscribe": true,
  "date_added": "2026-09-15T08:00:00",
  "name": "Newsletter",
  "public_list_id": "2b6c9d1e-3f4a-4b5c-8d7e-9f0a1b2c3d4e"
}
```

### Create template

Create an email template from HTML and/or text. Use {name} for merge fields.

**Inputs**

- Template name (`template_name`, text, required): The new template's name, which sends refer to.
- Subject (`subject`, text): The subject line emails using it get.
- HTML body (`html_body`, text): The HTML content.
- Text body (`text_body`, text): The plain-text content, for mail clients that do not show HTML.

**Outputs**

- `body` (list)
- `date_added` (text)
- `html_body` (text)
- `name` (text)
- `scope` (text)
- `subject` (text)
- `text_body` (text)
- `type` (text)

**Example output**

```json
{
  "body": [
    {
      "charset": null,
      "content": "<p>Hello {firstname}</p>",
      "content_type": "HTML"
    }
  ],
  "date_added": "2026-09-20T12:00:00",
  "html_body": "<p>Hello {firstname}</p>",
  "name": "Welcome",
  "scope": "Personal",
  "subject": "Welcome aboard",
  "text_body": null,
  "type": "RawHTML"
}
```

### Delete contact

Delete a contact by email address.

**Inputs**

- Contact email (`email`, text, required): The contact's email address.

**Outputs**

- `deleted` (true/false)
- `email` (text)

**Example output**

```json
{
  "deleted": true,
  "email": "ada@example.com"
}
```

### Delete list

Delete a list. Its contacts are kept in the account.

**Inputs**

- List (`list_name`, text, required): The list, by its exact name.

**Outputs**

- `deleted` (true/false)
- `list_name` (text)

**Example output**

```json
{
  "deleted": true,
  "list_name": "Newsletter"
}
```

### Delete template

Delete a template by its name.

**Inputs**

- Template (`template_name`, text, required): The template, by its exact name.

**Outputs**

- `deleted` (true/false)
- `template_name` (text)

**Example output**

```json
{
  "deleted": true,
  "template_name": "Welcome"
}
```

### Get contact

Get a contact by email address: name, status, custom fields, consent and sending activity.

**Inputs**

- Contact email (`email`, text, required): The contact's email address.

**Outputs**

- `activity` (object)
- `consent` (object)
- `custom_fields` (object)
- `date_added` (text)
- `date_updated` (text)
- `email` (text)
- `first_name` (text)
- `last_name` (text)
- `source` (text)
- `source_info` (text)
- `status` (text)
- `status_change_date` (text)

**Example output**

```json
{
  "activity": {
    "error_code": null,
    "friendly_error_message": null,
    "last_clicked": "2026-10-02T10:06:00",
    "last_failed": null,
    "last_ip": null,
    "last_opened": "2026-10-02T10:05:00",
    "last_sent": "2026-10-02T10:00:00",
    "total_clicked": 1,
    "total_failed": 0,
    "total_opened": 2,
    "total_sent": 3
  },
  "consent": {
    "date": null,
    "ip": null,
    "tracking": "Unknown"
  },
  "custom_fields": {},
  "date_added": "2026-10-01T09:30:00",
  "date_updated": "2026-10-02T11:00:00",
  "email": "ada@example.com",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "source": "ContactApi",
  "source_info": null,
  "status": "Active",
  "status_change_date": null
}
```

### Get email status

Get the status of a send by its transaction ID: how many recipients were sent to, delivered, opened, clicked, bounced or unsubscribed, optionally with the addresses in each group.

**Inputs**

- Transaction ID (`transaction_id`, text, required): The transaction_id a send step returned.
- Include (`include`, text): Which address lists to return alongside the counts. Leave empty for counts only. One or more of: `failed` (Failed (bounced) addresses), `errors` (Error messages for bounces), `sent` (Sent addresses), `delivered` (Delivered addresses), `pending` (Pending addresses), `opened` (Opened addresses), `clicked` (Clicked addresses), `unsubscribed` (Unsubscribed addresses), `abuse` (Abuse reports), `message_ids` (Message IDs).

**Outputs**

- `abuse_reports` (list)
- `abuse_reports_count` (number)
- `clicked` (list)
- `clicked_count` (number)
- `delivered` (list)
- `delivered_count` (number)
- `failed` (list)
- `failed_count` (number)
- `id` (text)
- `message_ids` (list)
- `opened` (list)
- `opened_count` (number)
- `pending` (list)
- `pending_count` (number)
- `recipients_count` (number)
- `sent` (list)
- `sent_count` (number)
- `status` (text)
- `unsubscribed` (list)
- `unsubscribed_count` (number)

**Example output**

```json
{
  "abuse_reports": [],
  "abuse_reports_count": 0,
  "clicked": [],
  "clicked_count": 0,
  "delivered": [],
  "delivered_count": 1,
  "failed": [],
  "failed_count": 0,
  "id": "8c2f0a5e-1d9b-4b7e-9c41-5f0b2a7d6e10",
  "message_ids": [],
  "opened": [],
  "opened_count": 0,
  "pending": [],
  "pending_count": 0,
  "recipients_count": 1,
  "sent": [],
  "sent_count": 1,
  "status": "complete",
  "unsubscribed": [],
  "unsubscribed_count": 0
}
```

### Get statistics

Get the account's sending totals between two dates: emails sent, delivered, opened, clicked, bounced, unsubscribed and complaints.

**Inputs**

- From (`start`, date, required): The first day to count (UTC).
- To (`end`, date): The last day to count (UTC). Defaults to now.

**Outputs**

- `bounced` (number)
- `clicked` (number)
- `complaints` (number)
- `delivered` (number)
- `email_total` (number)
- `in_progress` (number)
- `inbound` (number)
- `manual_cancel` (number)
- `not_delivered` (number)
- `opened` (number)
- `recipients` (number)
- `sms_total` (number)
- `unsubscribed` (number)

**Example output**

```json
{
  "bounced": 3,
  "clicked": 21,
  "complaints": 0,
  "delivered": 117,
  "email_total": 120,
  "in_progress": 0,
  "inbound": 0,
  "manual_cancel": 0,
  "not_delivered": 0,
  "opened": 64,
  "recipients": 120,
  "sms_total": 0,
  "unsubscribed": 1
}
```

### Get template

Get a template's subject and body by its name.

**Inputs**

- Template (`template_name`, text, required): The template, by its exact name.

**Outputs**

- `body` (list)
- `date_added` (text)
- `html_body` (text)
- `name` (text)
- `scope` (text)
- `subject` (text)
- `text_body` (text)
- `type` (text)

**Example output**

```json
{
  "body": [
    {
      "charset": null,
      "content": "<p>Hello {firstname}</p>",
      "content_type": "HTML"
    }
  ],
  "date_added": "2026-09-20T12:00:00",
  "html_body": "<p>Hello {firstname}</p>",
  "name": "Welcome",
  "scope": "Personal",
  "subject": "Welcome aboard",
  "text_body": null,
  "type": "RawHTML"
}
```

### List contacts

List the account's contacts, a page at a time.

**Inputs**

- Limit (`limit`, number): How many to return, up to 1,000. Defaults to 100. From 1 to 1000. Default: `100`.
- Offset (`offset`, number): How many to skip, for the next page. Defaults to 0. From 0 to 1000000. Default: `0`.

**Outputs**

- `contacts` (list): Contacts
- `count` (number)
- `has_more` (true/false)
- `limit` (number)
- `offset` (number)

**Example output**

```json
{
  "contacts": [
    {
      "activity": {
        "error_code": null,
        "friendly_error_message": null,
        "last_clicked": "2026-10-02T10:06:00",
        "last_failed": null,
        "last_ip": null,
        "last_opened": "2026-10-02T10:05:00",
        "last_sent": "2026-10-02T10:00:00",
        "total_clicked": 1,
        "total_failed": 0,
        "total_opened": 2,
        "total_sent": 3
      },
      "consent": {
        "date": null,
        "ip": null,
        "tracking": "Unknown"
      },
      "custom_fields": {},
      "date_added": "2026-10-01T09:30:00",
      "date_updated": "2026-10-02T11:00:00",
      "email": "ada@example.com",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "source": "ContactApi",
      "source_info": null,
      "status": "Active",
      "status_change_date": null
    }
  ],
  "count": 1,
  "has_more": false,
  "limit": 100,
  "offset": 0
}
```

### List contacts in list

List the contacts on one list, a page at a time.

**Inputs**

- List (`list_name`, text, required): The list, by its exact name.
- Limit (`limit`, number): How many to return, up to 1,000. Defaults to 100. From 1 to 1000. Default: `100`.
- Offset (`offset`, number): How many to skip, for the next page. Defaults to 0. From 0 to 1000000. Default: `0`.

**Outputs**

- `contacts` (list): Contacts on the list
- `count` (number)
- `has_more` (true/false)
- `limit` (number)
- `list_name` (text)
- `offset` (number)

**Example output**

```json
{
  "contacts": [
    {
      "activity": {
        "error_code": null,
        "friendly_error_message": null,
        "last_clicked": "2026-10-02T10:06:00",
        "last_failed": null,
        "last_ip": null,
        "last_opened": "2026-10-02T10:05:00",
        "last_sent": "2026-10-02T10:00:00",
        "total_clicked": 1,
        "total_failed": 0,
        "total_opened": 2,
        "total_sent": 3
      },
      "consent": {
        "date": null,
        "ip": null,
        "tracking": "Unknown"
      },
      "custom_fields": {},
      "date_added": "2026-10-01T09:30:00",
      "date_updated": "2026-10-02T11:00:00",
      "email": "ada@example.com",
      "first_name": "Ada",
      "last_name": "Lovelace",
      "source": "ContactApi",
      "source_info": null,
      "status": "Active",
      "status_change_date": null
    }
  ],
  "count": 1,
  "has_more": false,
  "limit": 100,
  "list_name": "Newsletter",
  "offset": 0
}
```

### List events

List delivery events - submissions, sends, opens, clicks, bounces, unsubscribes and more - in a time window. The Free plan keeps 3 days of email logs.

**Inputs**

- Event types (`event_types`, text): Only these kinds of event. Leave empty for all. One or more of: `Submission`, `FailedAttempt` (Failed attempt), `Error`, `Sent`, `Open`, `Click`, `Unsubscribe`, `Complaint`, `Bounce`, `TransactionalUnsubscribe` (Transactional unsubscribe), `Suppress`.
- From (`start`, date and time): Only events at or after this time (UTC).
- To (`end`, date and time): Only events at or before this time (UTC).
- Order (`order`, text): Defaults to Elastic Email's order. One of: `DateDescending` (Newest first), `DateAscending` (Oldest first).
- Limit (`limit`, number): How many to return, up to 1,000. Defaults to 100. From 1 to 1000. Default: `100`.
- Offset (`offset`, number): How many to skip, for the next page. Defaults to 0. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number)
- `events` (list): Delivery events
- `has_more` (true/false)
- `limit` (number)
- `offset` (number)

**Example output**

```json
{
  "count": 1,
  "events": [
    {
      "channel_name": null,
      "event_date": "2026-10-02T10:00:00",
      "event_type": "Sent",
      "from_email": "news@example.com",
      "ip_address": null,
      "message": null,
      "message_category": null,
      "message_id": "Xy7Kq2Zr9pLw3Nv8Tb4Hm1",
      "next_try_on": null,
      "subject": "Welcome aboard",
      "to": "ada@example.com",
      "transaction_id": "8c2f0a5e-1d9b-4b7e-9c41-5f0b2a7d6e10"
    }
  ],
  "has_more": false,
  "limit": 100,
  "offset": 0
}
```

### List lists

List the account's contact lists.

**Inputs**

- Limit (`limit`, number): How many to return, up to 1,000. Defaults to 100. From 1 to 1000. Default: `100`.
- Offset (`offset`, number): How many to skip, for the next page. Defaults to 0. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `limit` (number)
- `lists` (list): Contact lists
- `offset` (number)

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "limit": 100,
  "lists": [
    {
      "allow_unsubscribe": true,
      "date_added": "2026-09-15T08:00:00",
      "name": "Newsletter",
      "public_list_id": "2b6c9d1e-3f4a-4b5c-8d7e-9f0a1b2c3d4e"
    }
  ],
  "offset": 0
}
```

### List templates

List your email templates, or Elastic Email's gallery.

**Inputs**

- Scope (`scope`, text): Defaults to My templates. One or more of: `Personal` (My templates), `Global` (Elastic Email gallery).
- Template types (`template_types`, text): Only templates made this way. Leave empty for all. One or more of: `RawHTML` (Raw HTML), `DragDropEditor` (Drag and drop editor), `TemplateEditor` (Template editor).
- Limit (`limit`, number): How many to return, up to 1,000. Defaults to 100. From 1 to 1000. Default: `100`.
- Offset (`offset`, number): How many to skip, for the next page. Defaults to 0. From 0 to 1000000. Default: `0`.

**Outputs**

- `count` (number)
- `has_more` (true/false)
- `limit` (number)
- `offset` (number)
- `templates` (list): Templates

**Example output**

```json
{
  "count": 1,
  "has_more": false,
  "limit": 100,
  "offset": 0,
  "templates": [
    {
      "body": [
        {
          "charset": null,
          "content": "<p>Hello {firstname}</p>",
          "content_type": "HTML"
        }
      ],
      "date_added": "2026-09-20T12:00:00",
      "html_body": "<p>Hello {firstname}</p>",
      "name": "Welcome",
      "scope": "Personal",
      "subject": "Welcome aboard",
      "text_body": null,
      "type": "RawHTML"
    }
  ]
}
```

### Remove contacts from list

Take contacts off a list. The contacts stay in the account.

**Inputs**

- List (`list_name`, text, required): The list, by its exact name.
- Contact emails (`emails`, list, required): Email addresses of contacts that already exist in Elastic Email (up to 1,000). Use Add contact to create new ones.

**Outputs**

- `emails` (list)
- `list_name` (text)
- `removed` (true/false)

**Example output**

```json
{
  "emails": [
    "ada@example.com"
  ],
  "list_name": "Newsletter",
  "removed": true
}
```

### Send bulk email

Send a separate copy of an email to each recipient, who do not see each other, with per-recipient merge fields. Returns the transaction ID.

**Inputs**

- From (`from_address`, text, required): The sender, optionally with a name: Ada Lovelace <ada@example.com>. It must be on a domain verified in Elastic Email, or the address the account was registered with.
- Recipients (`recipients`, list, required): Email addresses, or objects with each recipient's own merge fields: {"email": "ada@example.com", "fields": {"firstname": "Ada"}}.
- Subject (`subject`, text): The subject line. Optional when a template supplies one.
- HTML body (`html_body`, text): The HTML content. Merge fields are written in braces, such as {firstname}. Give an HTML body, a text body or a template.
- Text body (`text_body`, text): The plain-text content, for mail clients that do not show HTML.
- Template (`template_name`, text): Send this template instead of (or as well as) a body.
- Reply to (`reply_to`, text): Where replies go, if not to the sender.
- Merge fields (`merge`, object): Values shared by every recipient, used in the body as {name}. For example firstname = Ada fills {firstname}.
- Channel (`channel_name`, text): A channel name to group this send under in Elastic Email reports.
- Track opens (`track_opens`, true/false): Leave empty to use the account's default.
- Track clicks (`track_clicks`, true/false): Leave empty to use the account's default.
- Delay (minutes) (`delay_minutes`, number): Hold the email back this many minutes before sending (up to 35 days). From 0 to 50400.

**Outputs**

- `message_id` (text)
- `transaction_id` (text)

**Example output**

```json
{
  "message_id": "Xy7Kq2Zr9pLw3Nv8Tb4Hm1",
  "transaction_id": "8c2f0a5e-1d9b-4b7e-9c41-5f0b2a7d6e10"
}
```

### Send transactional email

Send one email to one or more recipients, who can see each other (To and CC). Write the body or use a template. Returns the transaction ID to check its status with.

**Inputs**

- From (`from_address`, text, required): The sender, optionally with a name: Ada Lovelace <ada@example.com>. It must be on a domain verified in Elastic Email, or the address the account was registered with.
- To (`to`, list, required): Recipient email addresses.
- CC (`cc`, list): Copy recipients, visible to everyone.
- BCC (`bcc`, list): Hidden copy recipients.
- Subject (`subject`, text): The subject line. Optional when a template supplies one.
- HTML body (`html_body`, text): The HTML content. Merge fields are written in braces, such as {firstname}. Give an HTML body, a text body or a template.
- Text body (`text_body`, text): The plain-text content, for mail clients that do not show HTML.
- Template (`template_name`, text): Send this template instead of (or as well as) a body.
- Reply to (`reply_to`, text): Where replies go, if not to the sender.
- Merge fields (`merge`, object): Values shared by every recipient, used in the body as {name}. For example firstname = Ada fills {firstname}.
- Channel (`channel_name`, text): A channel name to group this send under in Elastic Email reports.
- Track opens (`track_opens`, true/false): Leave empty to use the account's default.
- Track clicks (`track_clicks`, true/false): Leave empty to use the account's default.
- Delay (minutes) (`delay_minutes`, number): Hold the email back this many minutes before sending (up to 35 days). From 0 to 50400.

**Outputs**

- `message_id` (text)
- `transaction_id` (text)

**Example output**

```json
{
  "message_id": "Xy7Kq2Zr9pLw3Nv8Tb4Hm1",
  "transaction_id": "8c2f0a5e-1d9b-4b7e-9c41-5f0b2a7d6e10"
}
```

### Update contact

Change a contact's name or custom fields. Fields left empty are not changed.

**Inputs**

- Contact email (`email`, text, required): The contact's email address.
- First name (`first_name`, text): The contact's first name.
- Last name (`last_name`, text): The contact's last name.
- Custom fields (`custom_fields`, object): Values for the account's custom contact fields. Only fields that already exist in Elastic Email are saved - others are silently dropped.

**Outputs**

- `activity` (object)
- `consent` (object)
- `custom_fields` (object)
- `date_added` (text)
- `date_updated` (text)
- `email` (text)
- `first_name` (text)
- `last_name` (text)
- `source` (text)
- `source_info` (text)
- `status` (text)
- `status_change_date` (text)

**Example output**

```json
{
  "activity": {
    "error_code": null,
    "friendly_error_message": null,
    "last_clicked": "2026-10-02T10:06:00",
    "last_failed": null,
    "last_ip": null,
    "last_opened": "2026-10-02T10:05:00",
    "last_sent": "2026-10-02T10:00:00",
    "total_clicked": 1,
    "total_failed": 0,
    "total_opened": 2,
    "total_sent": 3
  },
  "consent": {
    "date": null,
    "ip": null,
    "tracking": "Unknown"
  },
  "custom_fields": {},
  "date_added": "2026-10-01T09:30:00",
  "date_updated": "2026-10-02T11:00:00",
  "email": "ada@example.com",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "source": "ContactApi",
  "source_info": null,
  "status": "Active",
  "status_change_date": null
}
```
