Sviluppatori → Guide

Ricevere email nella Sua app

Ticket di assistenza, risposte alle notifiche, documenti inviati a un bot: le email indirizzate a un indirizzo del Suo dominio arrivano al Suo endpoint HTTPS come un'unica richiesta POST JSON firmata, con il testo, l'HTML e tutti gli allegati. Nessuna casella da interrogare periodicamente e niente IMAP.

Cosa serve

  • Un dominio registrato su NameOcean: per questi domini l'inoltro e l'invio delle email a un webhook sono gratuiti.
  • Un endpoint HTTPS su un indirizzo pubblico che risponda entro 20 secondi.
  • La CLI nameocean, oppure una chiave API con email:write.

1. Attivi l'inoltro per il dominio

nameocean
$ nameocean email forwards on example.com

Questa operazione punta il record MX del dominio ai server di inoltro email di NameOcean. Se il dominio ha già record MX, per caselle di posta ospitate altrove, il comando si interrompe e li elenca: tutta la posta del dominio verrebbe spostata qui. Aggiunga --replace-mx solo se è proprio ciò che desidera.

2. Richieda l'inoltro a webhook

L'invio delle email a un URL viene abilitato per singolo account dopo una breve verifica, per tenere lontani i relay di spam. Nella pagina del dominio, in Dashboard → Inoltro email, ne faccia richiesta indicando brevemente come intende utilizzarlo. Fino ad allora l'API risponde 403 not_approved.

3. Inoltri un indirizzo al Suo endpoint

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 risposta contiene il secret di firma (whsec_…); lo conservi nelle impostazioni della Sua app. Con localpart * vengono inoltrati tutti gli indirizzi del dominio che non hanno un alias proprio. Un dominio può avere fino a tre di questi webhook.

4. Riceva i messaggi

Verifichi la firma sul body grezzo, poi legga il JSON. Un piccolo receiver in 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

Cosa arriva

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
}

id rimane invariato quando un messaggio viene inviato di nuovo, quindi lo usi per scartare i duplicati. in_reply_to e references indicano a quale dei Suoi messaggi qualcuno ha risposto.

Quando il Suo endpoint non è raggiungibile

  • Una risposta 2xx indica che il messaggio è stato consegnato. In caso di 408, 429, 5xx, timeout (20 secondi) o mancata connessione, l'invio viene ritentato per 6 ore.
  • Qualsiasi altro 4xx è definitivo: il messaggio non viene reinviato automaticamente.
  • I messaggi che non è stato possibile inviare vengono conservati per 30 giorni. Li trovi con nameocean email forwards log example.com (o GET /email/forwarding/example.com/messages) e li rilasci: verranno inviati ancora una volta, con lo stesso id.
  • Vengono inoltrati ai webhook fino a 500 messaggi al giorno per dominio; quelli oltre il limite vengono trattenuti allo stesso modo.