Writing emails
Campaigns, flow emails and transactional templates share the same editor and design. Kula wraps the content in your brand, personalizes it for each recipient and adds the plain-text version, tracking and unsubscribe links.
The editor
| Mode | Best for |
|---|---|
| Visual | Most emails. Headings, bold, lists, quotes, links, images and dividers, wrapped in your email design. Stored as Markdown, so AI assistants and the API can write it too. |
| HTML | Emails designed elsewhere, or full control over the layout. Sent as you write it, without the email design. |
Use Preview to check the email on Desktop and Mobile, and Send test to receive it in a real inbox. Test emails go to up to 5 addresses, with [Test] in front of the subject, and are not tracked.
contentFormat: "MARKDOWN" with Markdown content, or "HTML" with your own HTML. Campaigns API.Email design
Settings › Email design sets the look of every email written in the visual editor: campaigns, flows and transactional templates.
| Setting | Notes |
|---|---|
| Brand color | Links and buttons |
| Logo URL | A PNG or JPG over https://, about 300 px wide. Leave empty for no logo |
| Footer | Markdown. Put your postal address here: anti-spam laws require it in marketing emails |
Marketing emails end with Unsubscribe and Manage preferences links under your footer. Send a test on the design page shows the result in your inbox.
Variables
Click Insert variable in the editor, or type them:
Hi {{ contact.first_name | default: "there" }},
| Variable | Value |
|---|---|
{{ contact.email }} | The recipient's address |
{{ contact.first_name }}, {{ contact.last_name }} | Name of the contact |
{{ contact.<attribute> }} | Any attribute: {{ contact.plan }}, {{ contact.company }} |
{{ data.<key> }} | Variables sent with a transactional email: {{ data.reset_url }} |
{{ space.name }} | The name of your space |
{{ unsubscribe_url }} | The recipient's unsubscribe link (marketing emails) |
{{ preferences_url }} | The recipient's preferences page |
- An unknown variable or an empty value renders as nothing. Add
| default: "…"to show a fallback instead. - Dotted paths read nested values:
{{ data.order.total }}. - Values are escaped, so a name containing
<or&cannot break your HTML. - Variables only insert values. There are no conditions, loops or other filters: for logic, prepare the text in your app and send it as a variable.
What Kula does before sending
For each recipient, Kula:
- Fills in the variables with the contact's data.
- Rewrites links so clicks are counted, through your tracking subdomain:
https://link.acme.com/c/…. The reader lands on the original URL. Turn click tracking off in Settings › General with Track clicks. - Adds a 1×1 pixel to count opens, if Track opens is on.
- Adds a plain-text version, made from your content. Some mailbox providers reject HTML-only emails, and it helps deliverability everywhere.
- Adds the unsubscribe headers and links on marketing emails. Unsubscribe and preferences.
Opens and clicks made by machines (Apple Mail Privacy Protection, link scanners of company mailboxes) are recorded but flagged: they do not count as engagement and never lift the review of a contact.