Entwickler → Anleitungen

E-Mails in Ihrer App empfangen

Support-Tickets, Antworten auf Benachrichtigungen, Dokumente per E-Mail an einen Bot: E-Mails an eine Adresse Ihrer Domain kommen als ein signierter JSON-POST an Ihrem HTTPS-Endpunkt an, mit Text, HTML und allen Anhängen. Kein Postfach, das abgefragt werden muss, und kein IMAP.

Was Sie brauchen

  • Eine bei NameOcean registrierte Domain: Weiterleitung und Mail-to-Webhook sind dafür kostenlos.
  • Einen HTTPS-Endpunkt unter einer öffentlichen Adresse, der innerhalb von 20 Sekunden antwortet.
  • Die nameocean CLI oder einen API-Schlüssel mit email:write.

1. Weiterleitung für die Domain aktivieren

nameocean
$ nameocean email forwards on example.com

Dadurch zeigt der MX-Eintrag der Domain auf die Mail-Forwarder von NameOcean. Hat die Domain bereits MX-Einträge für Postfächer bei einem anderen Anbieter, bricht der Befehl ab und listet sie auf: Alle E-Mails an die Domain würden hierher umgeleitet. Fügen Sie --replace-mx nur hinzu, wenn Sie genau das möchten.

2. Mail-to-Webhook beantragen

Das Senden von E-Mails an eine URL wird pro Konto nach einer kurzen Prüfung freigeschaltet, um Spam-Relays fernzuhalten. Beantragen Sie es auf der Seite der Domain unter Dashboard → E-Mail-Weiterleitung mit einer kurzen Angabe zum Verwendungszweck. Bis dahin antwortet die API mit 403 not_approved.

3. Eine Adresse an Ihren Endpunkt senden

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"}'

Die Antwort enthält das Signatur-Secret (whsec_…); speichern Sie es in den Einstellungen Ihrer App. Mit localpart * werden alle Adressen der Domain gesendet, die keinen eigenen Alias haben. Eine Domain kann bis zu drei dieser Webhooks haben.

4. Empfangen

Prüfen Sie die Signatur über den unveränderten Body und lesen Sie dann das JSON. Ein kleiner Flask-Empfänger:

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

Was ankommt

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 bleibt gleich, wenn eine E-Mail erneut gesendet wird; nutzen Sie sie also, um Duplikate zu überspringen. in_reply_to und references zeigen Ihnen, auf welche Ihrer eigenen E-Mails jemand geantwortet hat.

Wenn Ihr Endpunkt nicht erreichbar ist

  • Eine 2xx-Antwort bedeutet zugestellt. Bei 408, 429, 5xx, einem Timeout (20 Sekunden) oder fehlender Verbindung wird 6 Stunden lang erneut versucht.
  • Jeder andere 4xx-Code ist endgültig: Die E-Mail wird nicht automatisch erneut gesendet.
  • E-Mails, die nicht gesendet werden konnten, werden 30 Tage lang aufbewahrt. Finden Sie sie mit nameocean email forwards log example.com (oder GET /email/forwarding/example.com/messages) und geben Sie sie frei: Sie werden mit derselben id noch einmal gesendet.
  • Bis zu 500 E-Mails pro Tag und Domain gehen an Webhooks; darüber hinausgehende E-Mails werden ebenso zurückgehalten.