Banata

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

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

  1. Go to Email Templates in the dashboard sidebar.
  2. Click Create Template.
  3. A new template named "Untitled Template" is created with a blank heading and text block.
  4. 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 (h1 through h6). 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, or outline). 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:

PropertyDescription
colorText color
backgroundColorBackground color
fontSizeFont size
fontWeightFont weight (normal, bold, etc.)
fontStyleFont style (normal, italic)
textAlignText alignment (left, center, right)
textDecorationText decoration (underline, none)
lineHeightLine height
paddingShorthand padding
paddingTopTop padding in pixels
paddingBottomBottom padding in pixels
paddingLeftLeft padding in pixels
paddingRightRight padding in pixels
marginMargin
borderRadiusBorder radius
widthElement width
maxWidthMaximum 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.

typescript
// 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:

  1. Block palette -- Add blocks from the sidebar. All nine block types are available with labels and descriptions.
  2. Live preview -- See the rendered email update in real time as you edit.
  3. Block properties -- Click any block to edit its content, URL, style, and other settings in the inspector panel.
  4. Style inspector -- Configure backgroundColor, fontWeight, textDecoration, and directional padding (top, bottom, left, right) on any block.
  5. Variable hints -- The editor highlights {{variable}} placeholders and shows which variables are available.
  6. Reorder -- Drag blocks to rearrange them within the template.
  7. 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

typescript
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:

typescript
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

typescript
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

typescript
// 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

typescript
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

typescript
// 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:

typescript
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:

TemplateVariableDescription
verificationuserNameUser's display name
verificationUrlFull verification link
tokenVerification token
password-resetuserNameUser's display name
resetUrlPassword reset link
tokenReset token
magic-linkemailUser's email address
magicLinkUrlMagic link URL
tokenMagic link token
email-otpemailUser's email address
otpOne-time password code
invitationemailInvitee's email address
invitationIdInvitation record ID
organizationNameName of the inviting organization
inviterNameName of the person who sent the invite
acceptUrlInvitation acceptance link
welcomeuserNameUser's display name
dashboardUrlLink to the application dashboard
appNameApplication 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