Développeurs → Guides

Recevoir des e-mails dans votre application

Tickets de support, réponses aux notifications, documents envoyés à un bot : les e-mails adressés à une adresse de votre domaine arrivent sur votre point de terminaison HTTPS sous la forme d'une seule requête POST JSON signée, avec le texte, le HTML et toutes les pièces jointes. Aucune boîte aux lettres à interroger, pas d'IMAP.

Prérequis

  • Un domaine enregistré chez NameOcean : la redirection et l'envoi des e-mails vers un webhook sont gratuits pour ces domaines.
  • Un point de terminaison HTTPS sur une adresse publique qui répond en moins de 20 secondes.
  • La CLI nameocean, ou une clé API avec email:write.

1. Activez la redirection pour le domaine

nameocean
$ nameocean email forwards on example.com

Cette opération fait pointer l'enregistrement MX du domaine vers les serveurs de redirection d'e-mails de NameOcean. Si le domaine possède déjà des enregistrements MX, pour des boîtes aux lettres hébergées ailleurs, la commande s'arrête et les affiche : tous les e-mails du domaine seraient alors redirigés ici. N'ajoutez --replace-mx que si c'est bien ce que vous voulez.

2. Demandez l'accès aux e-mails vers webhook

L'envoi d'e-mails vers une URL est activé par compte après une brève vérification, afin d'empêcher les relais de spam. Sur la page du domaine, dans Tableau de bord → Redirection d'e-mails, faites-en la demande en indiquant en une ligne l'usage prévu. D'ici là, l'API répond 403 not_approved.

3. Envoyez une adresse vers votre point de terminaison

nameocean
$ nameocean email inbound add example.com support https://app.example.com/hooks/mail
curl
$ curl -X POST https://nameocean.net/api/v1/email/forwarding/example.com/webhooks \
    -H "Authorization: Bearer $NAMEOCEAN_API_KEY" -H "Content-Type: application/json" \
    -d '{"localpart": "support", "url": "https://app.example.com/hooks/mail"}'

La réponse contient le secret de signature (whsec_…) ; conservez-le dans les paramètres de votre application. Le localpart * envoie toutes les adresses du domaine qui n'ont pas d'alias propre. Un domaine peut avoir jusqu'à trois webhooks de ce type.

4. Recevez-les

Vérifiez la signature sur le corps brut, puis lisez le JSON. Un petit récepteur Flask :

app.py
import base64, hashlib, hmac, json, os, time

from flask import Flask, abort, request

app = Flask(__name__)
SECRET = os.environ["NAMEOCEAN_WEBHOOK_SECRET"]  # whsec_...


def verified(header, body, tolerance=300):
    fields = dict(part.split("=", 1) for part in header.split(",") if "=" in part)
    ts = int(fields.get("t", "0"))
    if abs(time.time() - ts) > tolerance:
        return False
    expected = hmac.new(SECRET.encode(), f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, fields.get("v1", ""))


@app.post("/hooks/mail")
def mail():
    body = request.get_data()
    if not verified(request.headers.get("X-NameOcean-Signature", ""), body):
        abort(401)
    mail = json.loads(body)
    print(mail["envelope"]["from"], "→", mail["envelope"]["to"], mail["subject"])
    for a in mail["attachments"]:
        data = base64.b64decode(a["content_base64"])
        print("  attachment", a["filename"], a["content_type"], len(data), "bytes")
    return "", 204  # any 2xx: delivered

Contenu reçu

POST https://app.example.com/hooks/mail
X-NameOcean-Event: email.received
X-NameOcean-Delivery: 6f1c2a4e-8b3d-4f5a-9c7e-1d2b3a4c5e6f
X-NameOcean-Signature: t=1794300000,v1=5f2b…

{
  "id": "6f1c2a4e-8b3d-4f5a-9c7e-1d2b3a4c5e6f",
  "event": "email.received",
  "received_at": "2026-11-11T09:30:12+00:00",
  "envelope": {"from": "alice@example.org", "to": "support@example.com"},
  "from": "Alice <alice@example.org>",
  "to": "support@example.com",
  "cc": null,
  "reply_to": null,
  "subject": "Order 1042",
  "date": "Wed, 11 Nov 2026 09:30:05 +0000",
  "message_id": "<…@example.org>",
  "in_reply_to": null,
  "references": null,
  "text": "Hi…",
  "html": "<p>Hi…</p>",
  "headers": [["From", "Alice <alice@example.org>"], …],
  "attachments": [{"filename": "invoice.pdf", "content_type": "application/pdf", "content_id": null,
                   "size": 48211, "content_base64": "JVBERi0…"}],
  "spam_score": 0.4,
  "size": 66120
}

L'id reste identique lorsqu'un e-mail est renvoyé : utilisez-le pour ignorer les doublons. in_reply_to et references vous indiquent à quel e-mail envoyé par vous la personne a répondu.

Si votre point de terminaison est indisponible

  • Une réponse 2xx signifie que l'e-mail est livré. En cas de 408, 429, 5xx, de délai dépassé (20 secondes) ou d'absence de connexion, l'envoi est retenté pendant 6 heures.
  • Tout autre code 4xx est définitif : l'e-mail n'est pas renvoyé automatiquement.
  • Les e-mails qui n'ont pas pu être envoyés sont conservés 30 jours. Retrouvez-les avec nameocean email forwards log example.com (ou GET /email/forwarding/example.com/messages) et libérez-les : ils sont renvoyés une fois de plus, avec le même id.
  • Jusqu'à 500 e-mails par jour et par domaine sont envoyés aux webhooks ; au-delà, les e-mails sont conservés de la même manière.