Operate Your Project
Email Templates
Customize the emails Banata sends with a block-based template editor, variable interpolation, and project branding.
Banata uses a block-based email template system to power every transactional email your project sends. You build templates by combining blocks -- heading, text, button, image, divider, spacer, code, link, and columns -- using the visual editor in your dashboard. At send time, Banata renders the blocks to HTML and automatically applies your project branding (colors, fonts, logo) so every email looks consistent without extra work.
Templates are organized into two categories: System Templates that power authentication flows, and Custom Templates that you create for your own use cases.
System Templates
Banata ships with six system templates that power built-in authentication flows. These are created automatically when you set up your project. You can customize their content and styling in the editor, but you cannot delete or rename them. System templates are marked with a lock icon in the dashboard.
verification
Sent when a user signs up and needs to confirm their email address.
Variables: userName, verificationUrl, token
password-reset
Sent when a user requests a password reset.
Variables: userName, resetUrl, token
magic-link
Sent for passwordless sign-in via a magic link.
Variables: email, magicLinkUrl, token
email-otp
Sent for email-based one-time password verification.
Variables: email, otp
invitation
Sent when a user is invited to join an organization. Organization invitations are now sent through the branded template system automatically — no custom email-sending code is required.
Variables: email, invitationId, organizationName, inviterName, acceptUrl
welcome
Sent after successful account creation.
Variables: userName, dashboardUrl, appName
Custom Templates
Custom templates are templates you create for your own use cases — marketing emails, onboarding sequences, notifications, or anything else. You have full control over custom templates: create, edit, rename, and delete them freely.
Creating a Custom Template
- Go to Email Templates in the dashboard sidebar.
- Click Create Template.
- A new template named "Untitled Template" is created with a blank heading and text block.
- Edit the name, subject line, and blocks to match your needs.
Variables in Custom Templates
When you use {{variableName}} placeholders in your custom template blocks, the dashboard auto-detects them and displays them in the Variables panel. You can add descriptions and default values for each variable to help your team understand what data to pass when sending the email.
Block Types
Every template is an ordered list of blocks. You can mix and match these nine types to build any layout you need.
- Heading -- Renders a heading (
h1throughh6). Set the level, text, and optional styles. - Text -- A paragraph of body text. Supports
{{variable}}interpolation and basic inline HTML like<strong>and<em>. - Button -- A call-to-action button with a label, URL, and variant (
primary,secondary, oroutline). Button text color automatically adjusts for contrast against the primary color. - Image -- An inline image with a source URL, alt text, and optional width/height.
- Divider -- A horizontal rule to visually separate sections.
- Spacer -- Empty vertical space with a configurable height in pixels.
- Code -- Monospace-styled text, ideal for OTP codes, tokens, or inline code snippets.
- Link -- An inline hyperlink with display text and a URL.
- Columns -- A multi-column layout (2 to 4 columns). Each column has a width and its own nested array of blocks, so you can build side-by-side layouts.
Block Styling
All blocks that support styling accept optional properties:
| Property | Description |
|---|---|
color | Text color |
backgroundColor | Background color |
fontSize | Font size |
fontWeight | Font weight (normal, bold, etc.) |
fontStyle | Font style (normal, italic) |
textAlign | Text alignment (left, center, right) |
textDecoration | Text decoration (underline, none) |
lineHeight | Line height |
padding | Shorthand padding |
paddingTop | Top padding in pixels |
paddingBottom | Bottom padding in pixels |
paddingLeft | Left padding in pixels |
paddingRight | Right padding in pixels |
margin | Margin |
borderRadius | Border radius |
width | Element width |
maxWidth | Maximum width |
Variable Interpolation
Templates support {{variableName}} placeholders in text, URLs, and subject lines. At send time, Banata replaces each placeholder with the value you pass in.
// In a template block:
{ type: "text", text: "Hi {{userName}}, welcome to {{appName}}!" }
// At send time, pass data to fill in the variables:
await banata.emails.send({
to: "jane@example.com",
template: "welcome",
data: { userName: "Jane", appName: "Acme" },
});
// Renders: "Hi Jane, welcome to Acme!"If a variable appears in the template but you don't provide a value for it, the raw placeholder (e.g., {{promoCode}}) is left in the output. This makes it easy to spot missing data during development.
Variable Quick-Insert
In the email editor, text and heading blocks have a Variable button in their inspector panel. Click it to see a dropdown of available variables and insert {{variableName}} directly into the block content.
For system templates, the variable list is fixed and shows descriptions for each variable. For custom templates, variables are auto-detected from your block content.
Dashboard Editor
The easiest way to work with templates is through the visual editor in your dashboard. Navigate to Email Templates in the sidebar to get started.
The editor gives you:
- Block palette -- Add blocks from the sidebar. All nine block types are available with labels and descriptions.
- Live preview -- See the rendered email update in real time as you edit.
- Block properties -- Click any block to edit its content, URL, style, and other settings in the inspector panel.
- Style inspector -- Configure
backgroundColor,fontWeight,textDecoration, and directional padding (top, bottom, left, right) on any block. - Variable hints -- The editor highlights
{{variable}}placeholders and shows which variables are available. - Reorder -- Drag blocks to rearrange them within the template.
- Preview and test -- Send a test email to yourself using sample data to verify the final result.
Branding Integration
Your email templates automatically inherit your project's branding configuration when rendered. You configure branding once in the dashboard under Branding, and every email -- system and custom -- picks it up:
- Primary color -- Applied to buttons, links, and headings. Button text automatically contrasts against the primary color (white text on dark backgrounds, black text on light backgrounds).
- Background color -- Used for the email body background
- Font family -- Applied to all text blocks
- Logo URL -- Displayed in the email header
- Border radius -- Applied to buttons and containers
- Dark mode -- Optional dark mode rendering with appropriate color adjustments
This means you never have to set colors or fonts on individual templates. Update your branding in one place and every email reflects the change.
Modifying Templates from Code
You can manage templates entirely from code without using the dashboard. All template operations use the HTTP API, so they work from any backend — Node.js, Bun, Deno, Hono, Express, or any runtime.
Create a Template
const BASE = "https://auth.banata.dev/api/auth";
const headers = {
"Content-Type": "application/json",
"x-api-key": "sk_live_...",
};
// Create a custom template
const res = await fetch(`${BASE}/banata/emails/templates/create`, {
method: "POST",
headers,
body: JSON.stringify({
name: "Marketing Welcome",
slug: "marketing-welcome",
subject: "Welcome to {{appName}}, {{userName}}!",
previewText: "Your account is ready",
category: "custom",
description: "Sent to new marketing leads after signup",
blocksJson: JSON.stringify([
{ id: "1", type: "heading", as: "h1", text: "Welcome, {{userName}}!" },
{ id: "2", type: "text", text: "Thanks for joining {{appName}}." },
{ id: "3", type: "button", text: "Get Started", href: "{{dashboardUrl}}", variant: "primary" },
]),
variablesJson: JSON.stringify([
{ name: "userName", description: "User's display name", required: true },
{ name: "appName", description: "Application name", required: true },
]),
}),
});
const { template } = await res.json();You can also use the @banata-auth/shared package to generate block structures:
import { createDefaultBlock, getBlankTemplateBlocks } from "@banata-auth/shared";
// Start with blank template blocks (heading + text)
const blocks = getBlankTemplateBlocks();
// Or build blocks individually
const button = createDefaultBlock("button");Update a Template
await fetch(`${BASE}/banata/emails/templates/update`, {
method: "POST",
headers,
body: JSON.stringify({
id: "etpl_01HXYZ...",
subject: "Welcome aboard, {{userName}}!",
previewText: "Let's get started",
}),
});List and Get Templates
// List all templates
const { templates } = await fetch(`${BASE}/banata/emails/templates/list`, {
method: "POST", headers, body: "{}",
}).then(r => r.json());
// Get a specific template by slug
const { template } = await fetch(`${BASE}/banata/emails/templates/get`, {
method: "POST",
headers,
body: JSON.stringify({ idOrSlug: "marketing-welcome" }),
}).then(r => r.json());Delete a Template
await fetch(`${BASE}/banata/emails/templates/delete`, {
method: "POST",
headers,
body: JSON.stringify({ id: "etpl_01HXYZ..." }),
});System templates (verification, password-reset, magic-link, email-otp, invitation, welcome) cannot be deleted. You can only customize their content and styling.
Send an Email
// Send using a system or custom template
await fetch(`${BASE}/banata/emails/send`, {
method: "POST",
headers,
body: JSON.stringify({
to: "user@example.com",
template: "welcome", // any template slug
data: {
userName: "Jane Doe",
dashboardUrl: "https://app.example.com",
appName: "My App",
},
}),
});Preview a Template
Render to HTML without sending — useful for testing or custom delivery:
const { subject, html, text } = await fetch(`${BASE}/banata/emails/preview`, {
method: "POST",
headers,
body: JSON.stringify({
template: "welcome",
data: { userName: "Jane", dashboardUrl: "https://example.com", appName: "Acme" },
}),
}).then(r => r.json());System Template Variable Reference
Each system template has a fixed set of variables. Here's the complete reference:
| Template | Variable | Description |
|---|---|---|
| verification | userName | User's display name |
verificationUrl | Full verification link | |
token | Verification token | |
| password-reset | userName | User's display name |
resetUrl | Password reset link | |
token | Reset token | |
| magic-link | email | User's email address |
magicLinkUrl | Magic link URL | |
token | Magic link token | |
| email-otp | email | User's email address |
otp | One-time password code | |
| invitation | email | Invitee's email address |
invitationId | Invitation record ID | |
organizationName | Name of the inviting organization | |
inviterName | Name of the person who sent the invite | |
acceptUrl | Invitation acceptance link | |
| welcome | userName | User's display name |
dashboardUrl | Link to the application dashboard | |
appName | Application name |
Next Steps
- Emails — Configure email providers and send branded emails from code
- SDK Reference — Complete API reference for the Emails resource
- Branding — Configure project branding used by email templates