# Send email manually

> Send mail from your own plugins and actions with the helpers in utilities.mail, or without code at all

---

Site [llms.txt](/llms.txt)

---

There is one helper for the administrator and one for any list of recipients, and both render an [email template](/docs/cmp/configure/administration/system/email/templates/).

## Email the administrator

`email_admin()` writes to the CB Admin address on [Email Settings](/docs/cmp/configure/administration/system/email/). Provide a subject and a message:

```python
from utilities.mail import email_admin

email_admin(context={'subject': 'Hello', 'message': 'My email message'})
```

To use a specific template, pass its slug. The context is rendered into the template's **Subject**, **Body**, and **Text body** fields:

```python
from utilities.mail import email_admin

email_admin(
    slug='order-complete',
    context={
        'subject': 'Your order is complete',
        'message': 'Success!',
        'order': order,
    },
)
```

## Email anyone else

`email()` takes a list of recipients, allowing you to reach, for example, a group's admins or a server owner:

```python
from utilities.mail import email

email(
    recipients=[user1.email, user2.email],
    slug='expired-server',
    context={
        'subject': 'Your server is expiring',
        'server': server,
    },
)
```

Both helpers accept the same options:

| Option | What it does |
| --- | --- |
| `slug` | The template to render. Without one, CMP sends the subject and message from the context as a plain message. |
| `context` | The values the template renders with. Pass the objects the template refers to, such as `order` or `server`. |
| `request` | Brands the message with the portal for that request's domain. Without it, the message uses the default portal. |
| `attachments` | A list of files, each as a tuple of name, content, and MIME type, for example `[('report.zip', contents, 'application/zip')]`. |
| `cc_addresses`, `bcc_addresses` | Adds to any provided by the template. To replace those, also pass `override_existing_cc_addresses=True` or `override_existing_bcc_addresses=True`. |
| `from_address` | Sends as this address rather than the template's or the global default. |
| `continue_on_error` | Logs a warning and continues. See below. |

## When sending fails

Helpers raise an `InvalidConfigurationException` if the mail cannot be sent, which stops your plugin. When the work should continue, use `continue_on_error`:

```python
from utilities.mail import email_admin

email_admin(
    context={'subject': 'Not important'},
    continue_on_error=True,
)
```

## Send email without code

**Email Hook** is one of the built-in action types. It emails the recipients supplied by the context in which it runs and can be limited to particular groups, environments, or resource technologies. See [Email hooks](/docs/cmp/use/orchestration/actions/email-hooks/).

Reports have an **Email Report** button that sends the report to a specified address.

## Related

- [Email templates](/docs/cmp/configure/administration/system/email/templates/): The built-in templates and their slugs, and how to create one.
- [Email](/docs/cmp/configure/administration/system/email/): SMTP settings and the addresses these helpers send from and to.
