Node.js (@frontmail/node)
@frontmail/node ist für Server, Serverless-Funktionen und Skripte gedacht. Es authentifiziert sich
mit dem privaten Schlüssel, daher entfallen Origin- und Turnstile-Prüfungen, und es schaltet
Batch-Versand, Verlauf und Vorlagenschemas frei.
npm install @frontmail/nodeBenötigt Node.js 20+ (nutzt das eingebaute fetch). Funktioniert auch in Bun, Deno und
Edge-Runtimes, die fetch bereitstellen.
Client erstellen
Abschnitt betitelt „Client erstellen“import { Frontmail } from '@frontmail/node';
const frontmail = new Frontmail({ privateKey: process.env.FRONTMAIL_PRIVATE_KEY!, // sk_… // retry: { retries: 3 }, timeoutMs: 15_000, apiUrl: 'https://api.frontmail.dev'});Ohne privateKey liest der Client FRONTMAIL_PRIVATE_KEY (und FRONTMAIL_API_URL) aus der
Umgebung. Geben Sie den privaten Schlüssel nie in ein Browser-Bundle – bewahren Sie ihn in
Umgebungsvariablen oder einem Secret Manager auf. Siehe
Öffentliche und private Schlüssel.
Das Paket verweigert die Ausführung im Webbrowser: Beim Import dort wird eine Warnung protokolliert,
und new Frontmail() wirft private_key_in_browser (abschaltbar mit
dangerouslyAllowPrivateKeyInBrowser: true – nur für interne Tools auf vertrauenswürdigen
Rechnern). Im Browser verwenden Sie @frontmail/browser mit dem öffentlichen
Schlüssel.
const result = await frontmail.send({ serviceId: 'svc_01J9…', // optional – ohne Angabe wird der Standarddienst verwendet templateId: 'tpl_order', params: { order_id: 'A-1042', items: [{ title: 'Zimmer', qty: 2, price: 89 }], total: 178, currency: 'EUR', },});console.log(result.messageId, result.status); // 'queued' | 'held'Weitere Eingabefelder: idempotencyKey (empfohlen, wenn der Versand von etwas ausgelöst wird, das
sich wiederholen kann, z. B. einem Webhook – verwenden Sie dessen Event-ID), attachments, locale,
signal.
locale (z. B. 'de') versendet die E-Mail in dieser Sprache der Vorlage –
exakte Übereinstimmung, dann dieselbe Basissprache (de-AT → de), sonst die Standardsprache.
result.locale ist die verwendete Sprache:
const { locale } = await frontmail.send({ templateId: 'tpl_order', params: { order_id: 'A-1042' }, locale: user.language });Batch-Versand
Abschnitt betitelt „Batch-Versand“Senden Sie bis zu 100 Nachrichten in einer Anfrage. Jede Nachricht wird einzeln validiert und
abgerechnet – eine ungültige Nachricht lässt die anderen nicht scheitern. sendBatch wirft bei
Fehlern einzelner Nachrichten keine Ausnahme; prüfen Sie ok bei jedem Ergebnis.
const results = await frontmail.sendBatch([ { serviceId: 'svc_01J9…', templateId: 'tpl_reminder', params: { name: 'Jana' }, idempotencyKey: 'reminder-42-jana' }, { serviceId: 'svc_01J9…', templateId: 'tpl_reminder', params: { name: 'Petr' }, idempotencyKey: 'reminder-42-petr' },]);
for (const r of results) { if (!r.ok) console.error(r.index, r.error.code); else console.log(r.index, r.messageId, r.status);}Ein Batch zählt für die Rate Limits als eine Anfrage. Mehr als 100
Nachrichten teilen Sie in Blöcke auf. Jede Nachricht kann ein eigenes locale haben; erfolgreiche
Ergebnisse enthalten das verwendete locale.
Verlauf
Abschnitt betitelt „Verlauf“const page = await frontmail.history({ status: 'failed', templateId: 'tpl_order', from: '2026-09-01T00:00:00Z', limit: 50,});
for (const m of page.items) console.log(m.messageId, m.status, m.to, m.subject);
// Nächste Seiteif (page.nextCursor) await frontmail.history({ cursor: page.nextCursor });
// Oder über alles iterierenfor await (const m of frontmail.history({ status: 'bounced' })) console.log(m.to);Filter: status, templateId, serviceId, from, to, q (Suche nach Empfänger), limit
(≤ 100), cursor. Mit await history() erhalten Sie eine Seite; for await durchläuft alle
Seiten nach Bedarf. Der Verlauf reicht so weit zurück wie der Aufbewahrungszeitraum Ihres Tarifs.
Nachrichtenstatus
Abschnitt betitelt „Nachrichtenstatus“const msg = await frontmail.getMessage('msg_01J9Z3K7Q2');// { messageId, status, createdAt, sentAt, templateId, serviceId, events: [{ type, at }, …] }Vorlagen
Abschnitt betitelt „Vorlagen“const templates = await frontmail.templates.list(); // Parameterschemas, genutzt von `frontmail types`const contact = await frontmail.templates.get('tpl_contact');contact.locales; // ['en', 'de', 'pt-BR'] – zuerst die Standardsprache, dann die Übersetzungenfrontmail types ergänzt den Doc-Kommentar jeder Vorlage um ihre Sprachen und erzeugt einen
Union-Typ für die Option locale:
/** Contact form (tpl_contact) – languages: en (default), de, pt-BR */export interface ContactFormParams { /* … */ }/** Languages of tpl_contact (default first) – for the `locale` send option. */export type ContactFormLocale = "en" | "de" | "pt-BR";Das Paket enthält die CLI frontmail – siehe Typisierte Parameter.
Beispielprojekt: examples/node.