Reciprok Docs

ADR-05, Email (Resend)

Resend plutôt qu'un self-host SMTP. Pourquoi.

Statut : Accepté Date : 2026-04 Sujet : Choix du provider email pour Reciprok

Contexte

Reciprok envoie et reçoit beaucoup d'emails :

  1. Catalogues envoyés aux organisateurs (HTML riche, lien magic, branding)
  2. Requalifications (emails pré-rédigés par l'IA, threadés)
  3. Réponses entrantes (organisateurs et membres répondent aux threads)
  4. Notifications internes (commission à facturer, demande inactive…)
  5. Liens magic envoyés aux membres pour leur dashboard

Volume estimé au démarrage : 300-1000 emails / mois.

Critères :

  • Délivrabilité (les catalogues doivent arriver en inbox, pas en spam)
  • Webhooks entrants pour parser automatiquement les réponses
  • Tracking ouvert/cliqué pour détecter quand un catalogue n'est pas consulté
  • Templates typés (on est en TypeScript partout)
  • Faible coût au démarrage (volume bas)
  • API simple, intégration rapide

Alternatives considérées

Option 1, Self-host Postfix / Haraka

Monter un MTA sur le serveur Hostinger, gérer SPF/DKIM/DMARC à la main, exposer une API maison.

Pour :

  • Zéro coût récurrent
  • Cohérent avec la philosophie self-host du reste de la stack

Contre :

  • Délivrabilité catastrophique : un IP fraîche d'un VPS Hostinger n'a aucune réputation. Les catalogues partent direct en spam Gmail/Outlook
  • Temps d'opération : warm-up d'IP, gestion des bounces, dégroupages, monitoring de la blacklist Spamhaus, etc.
  • Webhooks entrants à coder (parser MIME, gérer les attachments, le threading)
  • Retours négatifs (bounces, unsubscribes) à gérer manuellement
  • ROI temps largement négatif pour un produit qui démarre

Option 2, Postmark

Service réputé pour la délivrabilité transactionnelle.

Pour :

  • Excellente délivrabilité
  • API simple
  • Webhooks bien documentés

Contre :

  • Plus cher (~$15/mois pour 10k emails, pas de free tier)
  • Pas de templates React natifs
  • DX moins moderne que Resend

Option 3, AWS SES

Service email d'AWS, ultra-bon marché.

Pour :

  • Quasi-gratuit ($0.10 / 1000 emails)
  • Fiable

Contre :

  • DX nettement inférieure (config IAM, sandbox initial, validation d'identité, etc.)
  • Pas de templates ni de tracking out of the box
  • Webhooks entrants demandent SNS + Lambda, overkill
  • On veut éviter d'introduire AWS dans la stack pour un seul service

Option 4, Resend (retenu)

Service email moderne fondé par les anciens de React Email, très orienté DX.

Pour :

  • Free tier 3 000 emails/mois, couvre largement le démarrage Reciprok
  • Plan Pro $20/mois pour 50 000 emails, couvre toute la phase de croissance
  • Délivrabilité excellente (Resend gère SPF/DKIM/DMARC automatiquement, IPs warm)
  • SDK TypeScript first-class maintenu par l'équipe
  • react-email intégré : on compose les templates en JSX, validés par TS
  • Webhooks pour delivered, opened, clicked, bounced, complained, branchés sur notre flux email_message
  • Inbound parsing : on configure un domaine in.reciprok.com chez Resend, ils POST les emails entrants en JSON sur notre webhook
  • Multi-environnement : domaines séparés par env (preprod / prod) sans config supplémentaire

Contre :

  • Provider relativement jeune (lancé en 2023)
  • Lock-in modéré : si on veut migrer, il faut réécrire le wrapping client (~1 jour)
  • Templates react-email nous lient à leur écosystème (acceptable, c'est OSS et maintenu activement)

Décision

Resend comme provider unique pour l'email sortant et entrant.

apps/server/src/lib/mailer.ts
import { Resend } from 'resend';
import { CatalogEmail } from '@reciprok/emails';

export const resend = new Resend(process.env.RESEND_API_KEY);

export async function sendCatalog(args: { to: string; organizerName: string; catalogUrl: string }) {
  return resend.emails.send({
    from: 'Reciprok <demandes@reciprok.com>',
    to: args.to,
    subject: 'Votre sélection de lieux',
    react: CatalogEmail({ organizerName: args.organizerName, catalogUrl: args.catalogUrl }),
  });
}

Webhook events : https://app.reciprok.com/webhooks/resend reçoit les POST Resend (email.sent, delivered, opened, bounced, clicked, complained). Signature vérifiée via Svix (svix-id, svix-timestamp, svix-signature) avec le secret RESEND_WEBHOOK_SECRET. Hors du préfixe /api pour une URL stable.

Conséquences

Positives :

  • Free tier suffit pour démarrer = 0€/mois
  • Délivrabilité gérée par eux (vrai différenciateur vs self-host)
  • Templates typés avec react-email
  • Inbound + outbound dans le même provider, single source of truth

Négatives :

  • Dépendance à un provider tiers
  • Si Resend a une panne, les emails sont en attente (acceptable, on peut buffer en DB)
  • Changement de provider plus tard demande de réécrire le wrapping (~1 jour)

Voir aussi

On this page