Send email from a workflow
Verify a sending domain, build email templates with variables, and send them from a workflow step, with attachments and a failure path for when a send fails.
Last updated
A workflow can send an email to anyone, from your own domain, using a template you control. Setting that up is three jobs: verify a sending domain so your project can send as you, write an email template, then add a Send An Email step that picks the template and fills in its variables from the workflow's data.
| Piece | What it is | Where it lives |
|---|---|---|
| Sending domain | A domain you own, proved with DNS records | Settings › Communications › Email Templates › Sending Domains |
| Sender address | An address on a verified domain, one of which is the default | The same tab |
| Email template | A subject and an HTML body, with {{ }} variables |
Settings › Communications › Email Templates › Templates |
| Send An Email step | Sends one template to one recipient | A workflow step |
Anythink also sends its own system emails, such as account confirmation and password reset. They use the same template editor, so you can restyle them in the same place.
Note: Only project administrators can manage sending domains, sender addresses and templates.
Set up a sending domain
Workflow emails go out from an address on a domain you've verified. Until a domain is verified and a sender address exists, a Send An Email step has nothing to send from. System emails don't need this: with no default sender they're sent from Anythink's own address.
Add and verify a domain
Register the domain, add the DNS records Anythink shows you at your DNS provider, then check them.
In the Anythink dashboard
- Open Settings and, under Communications, select Email Templates.
- Open the Sending Domains tab and select Add Domain.
- Enter the hostname, such as
mail.example.com, and select Register. - Add each record in the list at your DNS provider. The table gives the Type, Host and Value, and the copy button copies the value.
- Select Verify. Records that DNS has picked up show Valid, the rest show Pending. DNS changes can take a while to spread, so check again later. The domain shows Verified once every record passes, and Re-check re-tests it at any time.
With the CLI
Sending domains are managed in the Anythink dashboard. Use the steps above.
With an AI assistant (MCP)
Sending domains are managed in the Anythink dashboard. Your assistant can walk you through the steps above.
Rules for domains
- Enter a bare hostname. It's stored in lower case.
- Each hostname can be registered once per project.
- Anythink's own domains and placeholder names such as
localhost,example.comandtestcan't be registered. - You can't delete a domain while a sender address still uses it. Remove the address first.
Set sender addresses and the default sender
A sender address is a full address on a verified domain, with an optional display name that recipients see before the address. One address is the default. A Send An Email step uses the default unless the step sets its own From address.
In the Anythink dashboard
- On the Sending Domains tab, under Sender addresses, select Add sender. The button is disabled until one domain is verified.
- Enter a Display name (up to 80 characters), type the part before the
@and choose a verified domain. - Tick Make this the default sender to use it by default.
- Select Add sender.
To change the default later, use Make this the default sender on another address in the list. Edit display name changes the name, and Remove sender deletes an address.
With the CLI
Sender addresses are managed in the Anythink dashboard. Use the steps above. An address must be on a verified domain.
With an AI assistant (MCP)
Sender addresses are managed in the Anythink dashboard. Your assistant can walk you through the steps above.
How the From address is chosen
For a workflow email Anythink picks the first of these that sits on a verified domain:
- The From address set on the step.
- The default sender address.
If neither is usable, the email isn't sent. A From address on a domain you haven't verified is ignored and the default is used instead.
Gmail can show a small image next to your name. Each verified domain can have a public image file as its sender avatar, set from the same tab. Other mail apps ignore it.
Create and edit email templates
A template is a subject and an HTML body. The body is wrapped in a shell that supplies the header, footer and brand colours, so you only write the content.
In the Anythink dashboard
- Open Settings › Communications › Email Templates, on the Templates tab.
- To make a new one, select Create New Template. Enter a Template Type (a unique name such as
order_confirmation) and a Subject Line, then select Create Template. - To change an existing one, pick it from the list. Custom templates and system templates are listed separately.
- Use the Edit tab to write the body, Source to edit the HTML, Preview to see it rendered, and Variables to see the variables it uses. Insert variable adds one at the cursor and Insert Button adds a call-to-action link.
- Select Save. The next email sent with the template uses the new version.
You can also create and edit a template without leaving a workflow: the Send An Email step has a New template button and a Save template button, covered below.
With the CLI
anythink fetch /email-templates --method POST --body '{
"template_type": "order_confirmation",
"subject": "Your order {{ order_ref }} is confirmed",
"content": "<h2>Thanks, {{ first_name }}</h2><p>Order {{ order_ref }} is on its way.</p>"
}'
To change one, send the full subject and content to its type:
anythink fetch /email-templates/order_confirmation --method PUT --body '{
"subject": "Order {{ order_ref }} confirmed",
"content": "<h2>Thanks, {{ first_name }}</h2><p>Order {{ order_ref }} is on its way.</p>"
}'
A type that already exists returns 409. anythink fetch /email-templates lists every template, and anythink fetch /email-templates/order_confirmation --method DELETE removes a custom one.
With an AI assistant (MCP)
Create an email template called order_confirmation with the subject "Your order {{ order_ref }} is confirmed" and a short thank-you body that uses first_name and order_ref.
The assistant runs the same fetch commands through the cli tool.
Template variables
Write a variable as {{ name }} in the subject or the body. Spaces inside the braces are optional and names aren't case-sensitive, so {{first_name}} and {{ First_Name }} are the same. A variable with no value is left in the email as written, so check the spelling.
Two kinds of variable are available.
Your own variables. The Send An Email step supplies them. A template for a welcome email might use {{ first_name }} and {{ order_ref }}. Each value is sent as text.
Built-in variables. Anythink fills these in for every email, and they take priority over a variable of the same name.
| Variable | Value |
|---|---|
{{ OrgName }} |
Your project's name |
{{ OrgId }} |
Your project's id |
{{ BrandColor }}, {{ BrandColorHover }} |
Your brand colour and its hover shade |
{{ BaseUrl }} |
The Anythink dashboard address |
{{ LoginUrl }} |
Link to sign in to your project |
{{ DashboardUrl }} |
Link to your project in the Anythink dashboard |
In the dashboard, the Preview tab shows the template with sample values, and the Variables tab lists every variable the template uses so you can give each a sample. Samples are only for the preview and aren't saved.
The email shell
Every template's body is inserted into one shared shell: header, footer and styles. The shell is listed above your templates as Shell template. Its Design tab changes colours, corners, header and footer without writing HTML, and Source edits the HTML directly. Reset to default restores Anythink's shell. The shell must keep the {{Content}} placeholder, because that's where each template's body goes.
System templates
These templates are created for every project, and Anythink sends them itself when the matching event happens.
| Template | Sent when |
|---|---|
| Email Confirmation | A new user registers and has to confirm their address |
| User Invitation | You invite someone to your project |
| Password Recovery | A user asks to reset their password |
| Magic Link | A user asks for a link to sign in |
| Email Change | A user changes their email address |
| Added to Organisation | An existing user is added to your project |
Run anythink fetch /email-templates to see each one's type. You can edit a system template's subject and body, and the new version is used the next time that email is sent. You can't delete one, and the template type can't change. Keep the link variable the email depends on, such as {{ ConfirmationUrl }}, {{ InviteUrl }}, {{ PasswordResetUrl }} or {{ MagicLinkUrl }}, or the person has no way to complete the action. System templates also use {{ OrgName }} and, for Added to Organisation, {{ AccessLevel }} and {{ LoginUrl }}.
The Send An Email step's template list shows only your own templates, so create a template for workflow emails.
To restyle every email at once, change the shell instead of each template.
Send an email from a workflow
The Send An Email step queues one email for one recipient. It has no subject or body fields of its own: the subject and body come from the template you name.
| Parameter | Required | Notes |
|---|---|---|
to |
Yes | The recipient's address. Templated, so it can be {{ $anythink.trigger.data.email }}. |
template_type |
Yes | The template's type, such as order_confirmation. |
payload |
No | The values for your own template variables, as a JSON object written as a string. Each value can be a {{ }} expression. |
from |
No | A sender address on a verified domain. Without it the default sender is used. |
attachments |
No | Up to 10 files. See below. |
Anythink reads each key in payload as a variable name. A key the template doesn't use is ignored.
In the Anythink dashboard
- Open the workflow, select Add Step and choose Send An Email.
- Optionally set From address: type the part before the
@and choose a verified domain, or select Use default. If there are no verified domains the field links you to Sending Domains. - Enter To Email Address, either an address or an expression such as
{{$anythink.trigger.data.email}}. - Under Email template, pick a template or select New template. The editor below shows its subject and body. Save template saves changes to the template itself, separately from the step.
- Open the Mappings tab. It lists every variable in the template. For each one, choose a value with Insert variable › From this workflow, which offers the trigger data and earlier steps' output, or type a fixed value. A sample value renders the preview with real-looking data.
- Save the step, then save and enable the workflow.
With the CLI
anythink workflows step-add 42 send_confirmation \
--name "Send confirmation" \
--action SendAnEmail \
--start --enabled \
--params '{
"to": "{{ $anythink.trigger.data.email }}",
"template_type": "order_confirmation",
"payload": "{\"first_name\":\"{{ $anythink.trigger.data.first_name }}\",\"order_ref\":\"{{ $anythink.trigger.data.order_ref }}\"}"
}'
Replace 42 with your workflow's id. Note that payload is a string holding JSON, so its quotes are escaped. To change the step later, use anythink workflows step-update <workflow_id> <step_id> --params '<json>'.
With an AI assistant (MCP)
In workflow 42, add a Send An Email step that sends the order_confirmation template to the trigger's email address, filling first_name and order_ref from the trigger data.
The assistant runs workflows step-add through the cli tool. It can only fill variables the template actually uses, so create the template first.
Use trigger data as variables
The workflow's trigger data and earlier steps' output are available in to, from and every value in payload. See Template syntax for the full set of expressions.
{{ $anythink.trigger.data.email }}
{{ $anythink.trigger.data.customer.first_name }}
{{ $anythink.steps.lookup_order.data.reference }}
If a value can't be found, the variable is empty, so a template reads Hello , order rather than failing. If it's the to address that can't be found, the step fails (see below).
Note: Send names, references and amounts. Don't send credentials or secrets in an email.
Attach files
Attach files from your project's file storage. Each attachment has:
| Field | Notes |
|---|---|
file_id |
The file's id, or an expression such as {{ $anythink.steps.upload.data.id }}. |
disposition |
attachment (the default) adds it as a download. inline shows an image inside the body. |
content_id |
For inline images only: the name used in the template as <img src="cid:logo.png">. Defaults to the file's name. |
{
"to": "{{ $anythink.trigger.data.email }}",
"template_type": "order_confirmation",
"payload": "{\"first_name\":\"{{ $anythink.trigger.data.first_name }}\"}",
"attachments": [
{ "file_id": "{{ $anythink.trigger.data.invoice_file_id }}", "disposition": "attachment" }
]
}
In the dashboard, open the step's Attachments tab. It counts files out of 10 and lets you pick files from storage or enter an id or expression, with an Attached or Inline (CID) switch. Images you insert into a template's body are sent inline automatically.
A file_id that doesn't resolve to a number is skipped, and the step log says so. The email still goes out without it.
What happens when a send fails
A Send An Email step checks its inputs and queues the email; the email itself is sent straight afterwards.
These problems fail the step and the job, with a message in the job's error:
tois empty, still contains an unresolved{{ }}expression, or isn't an email address.fromis set but still contains an unresolved expression or isn't an email address.template_typeis empty, more than 10 attachments are set, or a disposition isn'tattachmentorinline.payloadisn't valid JSON.
When the checks pass, the step logs Successfully queued email to … and finishes.
For the email to go out, make sure that:
- the template type exists;
- the project has a verified sending domain with a default sender, or the step's From address is on a verified domain;
- the project is within its daily email allowance for its plan;
- attachments can be read and are 25 MB or less in total.
To react to a failed step, link the step's failure path to another step such as a Slack message or a record update:
anythink workflows step-link 42 575 --on-failure 576
In the dashboard, set the step's failure path to the step that should run instead.
See what was sent
Anythink doesn't keep a list of sent emails. Open the workflow's job history to see that each email was queued.
In the Anythink dashboard
Open the workflow and select View Job History. Each job shows its status and, for each step, the log and result. A queued email shows Successfully queued email to <address> using template <type> and the number of attachments.
With the CLI
anythink workflows jobs 42
This lists each job and its status. For each step's log, fetch the job history:
anythink fetch /workflows/42/jobs
With an AI assistant (MCP)
Show the last jobs for workflow 42 and tell me whether the email step queued an email.
To check the layout before you send, use Preview in the template editor, which renders the body with sample values. Send a test through a workflow to your own address to see the finished email. Watch the daily limit while you test.
See Test workflows and read job history for more on job history.
Limits
| Limit | Value |
|---|---|
| Attachments per email | 10 |
| Attachment size | 25 MB in total for one email |
| Recipients per step | One address in to. To email several people, use one step for each. |
| Sender display name | 80 characters |
| Daily emails | Set by your plan. Emails your workflows send count towards it; system emails don't. |
| Template type | Unique within a project. System templates can't be deleted. |
| Sending domains | Each hostname once per project, and never Anythink's own or placeholder names |
Next steps
- Step types: the other steps you can combine with an email
- Template syntax: every
{{ }}expression a step accepts - Triggers and scheduling: start a workflow from a record change, a schedule or an HTTP call
- Secrets: keep credentials out of your steps and emails
- Upload and manage files: store the files you attach
- Roles and permissions: control who can manage email settings