Typed params (npx frontmail types)
Template params are validated on the server, but you can catch mistakes much earlier: the
frontmail CLI downloads your templates’ param schemas and generates TypeScript types. After
that, send() knows which params each template needs.
Generate
Section titled “Generate”FRONTMAIL_PRIVATE_KEY=sk_… npx frontmail types --out src/frontmail-env.d.tsThe frontmail CLI ships with @frontmail/node. Install it as a dev dependency
(npm install -D @frontmail/node) or run it without installing:
npx -p @frontmail/node frontmail types.
| Option | Default | Meaning |
|---|---|---|
--out <file> |
frontmail-env.d.ts |
Where to write the declarations |
--module <pkg> |
SDK packages found in your package.json (all SDKs if none) |
Package whose FrontmailTemplates interface is augmented; repeat for several |
--api-url <url> |
$FRONTMAIL_API_URL or https://api.frontmail.dev |
API base URL |
--stdout |
– | Print the declarations instead of writing a file |
-h, --help |
– | Show help |
The private key is read from the FRONTMAIL_PRIVATE_KEY environment variable (there is no flag for
it, so it doesn’t end up in your shell history). The command calls GET /v1/templates; run it
locally or in CI, never in the browser. Make sure the output file is included by your
tsconfig.json.
What it generates
Section titled “What it generates”For a project that depends on @frontmail/browser:
// Generated by `frontmail types`. Do not edit by hand – re-run the command instead./* eslint-disable */
/** Contact form (tpl_01J9ZCONTACT) */export interface ContactFormParams { /** Your name */ name: string; /** email address */ email: string; topic?: "sales" | "support" | "other"; /** multi-line text */ message: string; newsletter?: boolean;}
/** Order confirmation (tpl_01J9ZORDER) */export interface OrderConfirmationParams { order_id: string; items: Array<{ title: string; qty: number; price: number; }>; total: number; /** date – ISO 8601 (`YYYY-MM-DD` or full timestamp) */ delivery_date?: string;}
/** Template id → params. */export interface FrontmailTemplates { "tpl_01J9ZCONTACT": ContactFormParams; "tpl_01J9ZORDER": OrderConfirmationParams;}
export type FrontmailTemplateId = keyof FrontmailTemplates;
declare module "@frontmail/browser" { interface FrontmailTemplates { "tpl_01J9ZCONTACT": ContactFormParams; "tpl_01J9ZORDER": OrderConfirmationParams; }}Type mapping: string, text, email, url, html → string; number → number;
boolean → boolean; date → string; enum → union of literals; list → array of objects
from itemFields. Params with a default are optional.
import { send } from '@frontmail/browser';
await send('svc_01J9…', 'tpl_01J9ZCONTACT', { name: 'Jana', email: 'jana@example.com', message: 'Hi' }); // ✓await send('svc_01J9…', 'tpl_01J9ZCONTACT', { name: 'Jana' });// ~~~~~~~~~~~~~~ Property 'email' is missingThe template ID argument autocompletes known IDs. Unknown IDs still compile with loose
Record<string, unknown> params, so adding a template doesn’t break your build.
Regenerate types after changing a template’s schema – for example in a prebuild script or a CI
step that fails when the committed file is out of date.