Manage email content templates from the CLI.
Email Templates
Customize the content of transactional emails that AscendKit sends to your users. Every email AscendKit delivers — verification, password reset, magic link, welcome, and journey emails — is rendered from a template. You can modify the default templates or create new ones for use in journeys.
Templates support HTML and plain-text bodies with {{variable}} placeholders that are filled at send time (e.g., {{userName}}, {{appName}}, {{verificationLink}}). Every update creates a new immutable version, so you can review and roll back changes.
Variable scope
Variables are resolved from the context of the send:
- Auth templates receive auth-specific links such as
{{verificationLink}},{{resetLink}}, and user fields such as{{userName}}and{{userEmail}}. - Journey and campaign templates receive user fields, environment variables set with
ascendkit vars set, and variables explicitly attached to the journey node or campaign send. - Survey invite templates receive the survey link only when the send path attaches a survey.
Event properties used for journey routing are not automatically template variables. If a template needs an event value, copy it into an environment variable, campaign variable, or journey node variable intentionally.
Missing variables render as empty values and are reported as warnings where the CLI or portal can detect them. Use ascendkit template show <template-id> to inspect the latest version and expected placeholders.
List templates
ascendkit template list
ascendkit template list --query "welcome"
ascendkit template list --system true
ascendkit template list --query "receipt"
Create a template
ascendkit template create \
--name "Welcome Email" \
--slug welcome-email \
--subject "Welcome to {{appName}}" \
--body-html "<h1>Welcome, {{userName}}!</h1>" \
--body-text "Welcome, {{userName}}!" \
--category marketing
View a template
ascendkit template show tpl_abc123
Update a template
ascendkit template update tpl_abc123 \
--subject "New subject line" \
--change-note "Updated subject for A/B test"
# --html and --text are accepted as aliases for --body-html and --body-text
ascendkit template update tpl_abc123 \
--html "<h1>Hello, {{userName}}!</h1>" \
--text "Hello, {{userName}}!"
ascendkit template update tpl_abc123 \
--category transactional \
--change-note "This journey email is operational, not marketing"
Each update creates a new immutable version. Previous versions are preserved.
Tip: Run
ascendkit template update <id> --helpto see all available flags before editing.
Template categories
Templates support a category field:
marketinginjects the unsubscribe footer andList-Unsubscribeheaders for journey sends.transactionalskips unsubscribe injection for operational emails like password resets, magic links, OTPs, and receipts.
The CLI defaults new templates to marketing. Set --category transactional when the email should never present an unsubscribe action.
View version history
ascendkit template version list tpl_abc123
ascendkit template version show tpl_abc123 2
Delete a template
ascendkit template remove tpl_abc123
Personalizing templates for your brand
When customizing templates for your app, follow this workflow:
- Set environment variables first — use
ascendkit vars set dashboardUrl "https://yourapp.com/dashboard"so templates can reference{{dashboardUrl}}dynamically. Note:{{appName}}is automatically resolved from your environment name - Use
{{variable}}placeholders — don't hardcode your app name or URLs in template HTML. If you rename your app or change domains, you only need to update the environment variable - Review linked surveys — if you update survey invite templates, also review the survey questions themselves with
ascendkit survey showto ensure they match your branding - Verify after updating — run
ascendkit template show tpl_xxxafter updates to confirm the HTML and variables rendered correctly - Check for warnings — the CLI will warn you if a template update removes variables that were present in the previous version
Why templates live here rather than in your codebase
Copy changes ship without a deploy. Fixing a typo in a verification email, or rewording a welcome message, does not need a pull request, a review, and a release.
Versioning is what makes that safe. Every update creates a new version rather than overwriting, so a change that reads badly in production can be traced and reverted rather than reconstructed from memory.
The trade-off is real: template content is no longer in your repository, so it is not in your code review process and not in your git history. For teams that want copy reviewed like code, authoring templates through the CLI in a scripted, committed file gives you both — the file lives in your repo, and the CLI applies it.
Always write both bodies
Every template has an HTML body and a plain-text body. Sending HTML alone is a deliverability problem, not just an accessibility one: messages with no text alternative score worse with spam filters, and some clients render nothing useful.
The plain-text version is not a fallback nobody sees. Text-only clients, accessibility tooling, and some corporate mail gateways use it directly.
Keep transactional email plain
For verification, password reset, and magic-link email, a one-line message with a single button consistently outperforms a designed template. Heavy markup and tracking make a transactional message look promotional to filters, which is the opposite of what you want when the message is required for someone to sign in.
Save the designed templates for campaigns, where the content genuinely is marketing and the recipient expects it.
Troubleshooting
A variable renders as an empty string
The placeholder does not match a field on the user record, or that field is unset for the recipient. Check spelling against Variable scope above, and remember that optional fields are frequently empty.
Template changes are not appearing
Confirm which environment is active. Templates are per environment, so editing development and testing production is a common mismatch — see CLI Setup.
A template cannot be deleted
Templates in use by an active journey or scheduled campaign are protected. Remove the reference first, then delete.
Related
- Email Identity — domain verification, which decides whether any of this arrives
- Campaigns — pairing a template with an audience
- Journeys — sending templates on each user's own clock