Courier Elemental lets you define notification content as JSON instead of using the visual template designer. This is useful when your content is generated dynamically, managed in code, or needs to differ per channel. This tutorial walks through building a real notification end-to-end: starting with a simple message, then layering in channel-specific content, conditional rendering, and dynamic lists.Documentation Index
Fetch the complete documentation index at: https://www.courier.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
- A Courier account with at least one configured email provider (e.g. SendGrid)
- Your Courier API key (found in Settings > API Keys)
Send a Simple Elemental Message
The fastest way to use Elemental is the sugar syntax: justtitle and body. Courier automatically converts this into the full Elemental format behind the scenes.
Send with title and body
Verify delivery
Check the Message Logs in the Courier dashboard to confirm the message was delivered and see the rendered output.
The sugar syntax is ideal for simple messages. For multi-element layouts, channel-specific content, or dynamic logic, use the full Elemental format below.
Use Full Elemental Format
Full Elemental gives you complete control over the notification structure. Every template requires aversion field ("2022-01-01") and an elements array.
Element Types at a Glance
| Element | Purpose | Key properties |
|---|---|---|
meta | Sets the email subject / push title | title |
text | Body text with optional formatting | content, text_style, format, align |
action | Button or link | content, href, style (button or link) |
image | Inline image | src, alt_text, width, href |
divider | Horizontal rule | color |
quote | Blockquote text | content, border_color |
html | Raw HTML (email only) | content |
group | Container for conditional/loop logic | elements, if, loop |
channel | Channel-specific content branch | channel, elements, raw |
columns | Multi-column layout | elements (array of column nodes) |
Customize Content Per Channel
Usechannel elements to send different content to different channels from a single API call. This is one of Elemental’s most powerful features.
channels property on individual elements to show or hide them by channel without wrapping in a channel block:
Add Conditional Logic
Use theif property on any element to conditionally render it based on your data.
if expression is evaluated as JavaScript against the data object you pass in the send call.
Render Dynamic Lists
Theloop property iterates over an array in your data and renders the element once per item.
{{$.item}} refers to the current item and {{$.index}} gives the zero-based index.
The
format property on text elements supports "markdown" for bold, italic, and link rendering. Use double asterisks (**bold**) or single asterisks (*italic*) in your content strings.Send to a Stored User Profile
Instead of specifying an email address directly, you can send to a user by their profile ID. Courier looks up their contact details from the stored profile.What’s Next
Elements Reference
Complete reference for all Elemental element types and properties
Control Flow
Deep dive into conditionals, loops, references, and channel filtering
Locales
Localize Elemental templates for multiple languages
Send API Reference
Full API documentation for sending messages
How to Use the Templates API
Workspace templates: list, draft, publish, and read content over HTTP
Templates API
Notification Templates REST endpoints for your workspace