Node.js (@frontmail/node)
@frontmail/node s’adresse aux serveurs, aux fonctions serverless et aux scripts. Il s’authentifie
avec une clé privée : les vérifications d’origine et Turnstile ne s’appliquent donc pas, et il
donne accès à l’envoi groupé, à l’historique et aux schémas des modèles.
npm install @frontmail/nodeNécessite Node.js 20+ (utilise le fetch intégré). Fonctionne aussi avec Bun, Deno et les runtimes
edge qui fournissent fetch.
Créer un client
Section intitulée « Créer un client »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'});Sans privateKey, le client lit FRONTMAIL_PRIVATE_KEY (et FRONTMAIL_API_URL) dans
l’environnement. N’exposez jamais la clé privée dans un bundle navigateur – gardez-la dans des
variables d’environnement ou un gestionnaire de secrets. Voir
Clés publiques et privées.
Le paquet refuse de fonctionner dans un navigateur web : l’importer affiche un avertissement et
new Frontmail() lève private_key_in_browser (à désactiver avec
dangerouslyAllowPrivateKeyInBrowser: true uniquement pour des outils internes sur des machines de
confiance). Dans le navigateur, utilisez @frontmail/browser avec la clé
publique.
const result = await frontmail.send({ serviceId: 'svc_01J9…', // facultatif – omettez-le pour utiliser le service par défaut templateId: 'tpl_order', params: { order_id: 'A-1042', items: [{ title: 'Chambre', qty: 2, price: 89 }], total: 178, currency: 'EUR', },});console.log(result.messageId, result.status); // 'queued' | 'held'Autres champs d’entrée : idempotencyKey (recommandé lorsque l’envoi est déclenché par quelque chose
qui peut se répéter, p. ex. un webhook – utilisez son identifiant d’événement), attachments,
locale, signal.
locale (p. ex. 'de') envoie l’e-mail dans cette langue du modèle –
correspondance exacte, puis même langue de base (de-AT → de), sinon la langue par défaut.
result.locale est la langue utilisée :
const { locale } = await frontmail.send({ templateId: 'tpl_order', params: { order_id: 'A-1042' }, locale: user.language });Envoi groupé
Section intitulée « Envoi groupé »Envoyez jusqu’à 100 messages en une seule requête. Chaque message est validé et facturé
séparément – un message invalide ne fait pas échouer les autres. sendBatch ne lève pas d’exception
pour les erreurs propres à un message ; vérifiez ok sur chaque résultat.
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);}Un lot compte comme une seule requête pour les rate limits. Au-delà de
100 messages, découpez-les en plusieurs lots. Chaque message peut avoir sa propre locale ; les
résultats réussis indiquent la locale utilisée.
Historique
Section intitulée « Historique »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);
// Page suivanteif (page.nextCursor) await frontmail.history({ cursor: page.nextCursor });
// Ou parcourir tout l’historiquefor await (const m of frontmail.history({ status: 'bounced' })) console.log(m.to);Filtres : status, templateId, serviceId, from, to, q (recherche par destinataire),
limit (≤ 100), cursor. await history() renvoie une page ; for await parcourt toutes les pages
à la demande. L’historique couvre la durée de conservation de votre forfait.
Statut d’un message
Section intitulée « Statut d’un message »const msg = await frontmail.getMessage('msg_01J9Z3K7Q2');// { messageId, status, createdAt, sentAt, templateId, serviceId, events: [{ type, at }, …] }const templates = await frontmail.templates.list(); // schémas de paramètres, utilisés par `frontmail types`const contact = await frontmail.templates.get('tpl_contact');contact.locales; // ['en', 'de', 'pt-BR'] – langue par défaut d’abord, puis les traductionsfrontmail types ajoute les langues de chaque modèle à son commentaire de documentation et génère un
type union pour l’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";Le paquet inclut la CLI frontmail – voir Paramètres typés.
Projet d’exemple : examples/node.