Templates
Create reusable email templates with {{variable}} placeholders, then send with
POST /emails using template: { id, variables }.
Base URL: https://api.ranla.ai
Authentication
Authorization: Bearer rnl_…Requires a full-scope API key (or dashboard session). Sending-scoped keys cannot manage templates.
Model
| Field | Notes |
|---|---|
name |
Required; unique per account |
alias |
Optional unique handle (not empty, not starting with rnl_ or stx_) |
status |
draft (default) or published |
format |
html (legacy) or blocks (visual builder document) |
subject / html / text |
Support {{var}} placeholders |
preheader |
Optional inbox preview text |
design |
TemplateDocument JSON when format is blocks |
variables |
Variable names (auto-extracted for blocks templates) |
published_version_id |
Immutable version used for sends |
unsubscribe_enabled |
When true, sends using this template inherit managed unsubscribe unless overridden per send |
category |
transactional (default), product, or newsletter. Product and newsletter support category-scoped opt-out |
warnings |
Non-blocking deliverability hints for html (e.g. SVG logos) |
Placeholders in HTML bodies are HTML-escaped when interpolated. Subject and text are not.
Publishing snapshots an immutable version. Sends always resolve published_version_id, so draft edits never break live aliases. See docs/templates/builder.md.
Global CSS (blocks templates)
design.settings.globalCss accepts ordinary CSS that is compiled for the inbox on render:
- Rules whose selector is a bare tag (
body,p,h1,h2,h3,a,img,hr) become inline styles on those elements and override per-block styling. Inlining matters because Gmail drops<style>on clipped and forwarded messages, and Outlook renders through Word. - Everything else — class and id selectors, pseudo-classes, descendant selectors, media
queries — is emitted into a
<style>block, which most clients honour.
{
"design": {
"version": 1,
"settings": {
"globalCss": "p { color: rgb(63,63,70); }\n@media (max-width: 480px) { p { font-size: 14px; } }"
}
}
}@import is stripped, and CSS cannot inject markup.
Images in HTML
Use PNG or JPG logos at public https:// URLs in <img src="…"> tags. Many inboxes (including Gmail) do not render SVG images. Ranla returns advisory warnings on template create/get/list when HTML may not render reliably — sends are not blocked.
<img src="https://yourdomain.com/assets/logo.png" alt="Your product" width="36" height="36" />List
GET /templates
Query: limit, cursor, optional status=draft|published.
{
"data": [
{
"id": "…",
"name": "Welcome",
"alias": "welcome",
"status": "published",
"subject": "Hello {{name}}",
"html": "<p>Hi {{name}}</p>",
"text": "Hi {{name}}",
"variables": ["name"],
"published_at": "2026-07-26T12:00:00.000Z",
"created_at": "2026-07-26T11:00:00.000Z",
"updated_at": "2026-07-26T12:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}Create
POST /templates → 201
{
"name": "Welcome",
"alias": "welcome",
"subject": "Hello {{name}}",
"html": "<p>Hi {{name}}</p>",
"text": "Hi {{name}}",
"variables": ["name"]
}Creates a draft. Publish before sending.
Starter catalog
GET /templates/starters — list copyable starters (full-scope key).
POST /templates/from-starter — copy one into your account as published with a fixed alias.
| Alias | Variables |
|---|---|
password-reset |
name, reset_url |
email-verification |
name, verify_url, code |
welcome |
name, dashboard_url |
invoice |
name, amount, invoice_url, invoice_id |
team-invite |
name, inviter_name, team_name, invite_url |
curl -X POST https://api.ranla.ai/templates/from-starter \
-H "Authorization: Bearer $RANLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"alias":"password-reset"}'await client.templates.fromStarter('password-reset')
await client.emails.send({
from: '[email protected]',
to: '[email protected]',
template: {
id: 'password-reset',
variables: { name: 'Ada', reset_url: 'https://app.example.com/reset?token=…' },
},
})Dashboard: Templates → Start from a template. Returns 409 if the name or alias already exists on the account.
Retrieve / update / delete
GET /templates/{id}— UUID or aliasPATCH /templates/{id}— update fieldsDELETE /templates/{id}
Publish / duplicate
POST /templates/{id}
{ "action": "publish" }{ "action": "duplicate", "name": "Welcome (copy)" }Duplicate creates a new draft (alias cleared). name is optional (defaults to … (copy)).
Send with a template
POST /emails
{
"from": "[email protected]",
"to": "[email protected]",
"template": {
"id": "welcome",
"variables": { "name": "Ada" }
}
}template is mutually exclusive with html / text. Subject comes from the template unless you pass subject to override. Only published templates can be used.
SDK
import { Ranla } from '@supersend/ranla'
const client = new Ranla(process.env.RANLA_API_KEY!)
const { template } = await client.templates.create({
name: 'Welcome',
alias: 'welcome',
subject: 'Hello {{name}}',
html: '<p>Hi {{name}}</p>',
})
await client.templates.publish(template.id)
await client.emails.send({
from: '[email protected]',
to: '[email protected]',
template: { id: 'welcome', variables: { name: 'Ada' } },
})React Email (optional peer)
Install @react-email/render (and react) to pass a React element:
npm install @react-email/render reactawait client.emails.send({
from: '[email protected]',
to: '[email protected]',
subject: 'Hello',
react: EmailComponent({ name: 'Ada' }),
})The SDK compiles react to HTML before POST /emails. Mutually exclusive with html / text / template.
Full guide: Send React Email.
CLI
supersendtx templates list
supersendtx templates starters
supersendtx templates from-starter password-reset
supersendtx templates create --name Welcome --subject "Hi {{name}}" --html "<p>Hi {{name}}</p>" --alias welcome --category product --unsubscribe-enabled
supersendtx templates update --id welcome --category product --unsubscribe-enabledPush from your repo
templates push upserts a template from a local file, keyed by --alias, so your repo can be
the source of truth:
# HTML file
supersendtx templates push ./emails/welcome.html --alias welcome --subject "Welcome" --publish
# React Email component, rendered locally
supersendtx templates push ./emails/WelcomeEmail.tsx --alias welcome --props '{"name":"Ada"}' --publish| Flag | Notes |
|---|---|
<file> |
.html, .txt, or a module (.js, .mjs, .cjs, .jsx, .ts, .tsx) with a React component as its default export |
--alias |
Required. Creates the template on first push, updates it afterwards |
--subject |
Required only when creating |
--name |
Display name; defaults to the alias |
--preheader |
Inbox preview text |
--text <file> |
Attach a hand-written plain-text part |
--props <json> |
Props passed to the component when rendering |
--publish |
Cut a published version after pushing |
Module files are imported in your process and rendered with @react-email/render — only
the resulting HTML and text are uploaded. TypeScript and JSX need a loader: install tsx
(npm install -D tsx) or pre-render to .html. See
React Email guide.