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.
email:write.$ 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.
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.
$ nameocean email inbound add example.com support https://app.example.com/hooks/mail
$ 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.
Prüfen Sie die Signatur über den unveränderten Body und lesen Sie dann das JSON. Ein kleiner Flask-Empfänger:
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
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.
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.