This guide walks you from creating a template in the Maildeno builder to rendering it in your application.

Prerequisites

  • A Maildeno account (free tier available)

  • Node.js ≥ 18 or Python ≥ 3.9 — pick whichever fits your stack

Step 1 — Create a template

  1. Log in to the Maildeno Dashboard.

  2. Navigate to Create Templates.

  3. Drag or click layout block onto the canvas.

  4. Drag a Heading block and a Text block onto the canvas.

  5. In the heading block, type Hello {{ name }} — this is a merge tag.

  6. Click Save.

Creating a new template in the editor
  1. Copy the Template ID from the template settings panel (it looks like 550e8400-e29b-41d4-a716-446655440000).

Step 2 — Create an API key

  1. Go to Dashboard → API Keys → Create Key.

  2. Give it a name (e.g. quickstart-key) and leave Targets set to All.

  3. Copy the generated key — you’ll only see it once.

Never commit API keys to source control. Use environment variables or a secrets manager.

Step 3 — Install the SDK

  • JavaScript / TypeScript

  • Python

npm install maildeno
pip install maildeno

Step 4 — Render your first email

Replace <YOUR_API_KEY> and <YOUR_TEMPLATE_ID> with your actual values.

  • JavaScript / TypeScript

  • Python (sync)

  • Python (async)

import { MaildenoClient } from "maildeno"

const client = new MaildenoClient({
  apiKey: process.env.MAILDENO_API_KEY!,
})

const html = await client.renderHtml(
  "<YOUR_TEMPLATE_ID>",
  {
    merge_tags: {
      text: { name: "Noruwa" },
    },
  }
)

console.log(html) // <!DOCTYPE html>...
Load your API key from an environment variable — never hard-code it.
The `name` merge tag fills in the `{{ name }}` placeholder in your template.
import os
from maildeno import MaildenoClient

client = MaildenoClient(api_key=os.environ["MAILDENO_API_KEY"])

html = client.render_html(
    "<YOUR_TEMPLATE_ID>",
    {
        "merge_tags": {
            "text": {"name": "Noruwa"},
        },
    },
)

print(html)  # <!DOCTYPE html>...
Load your API key from an environment variable.
Fills in the `{{ name }}` merge tag.
import asyncio
import os
from maildeno import AsyncMaildenoClient

async def main():
    async with AsyncMaildenoClient(api_key=os.environ["MAILDENO_API_KEY"]) as client:
        html = await client.render_html(
            "<YOUR_TEMPLATE_ID>",
            {"merge_tags": {"text": {"name": "Noruwa"}}},
        )
        print(html)

asyncio.run(main())

You should see a complete HTML document printed to stdout. 🎉