Dokumentation

Formular anbinden

Mailiy nimmt Formulardaten per POST entgegen und schickt sie als E-Mail an deine bestätigten Adressen. Es akzeptiert application/x-www-form-urlencoded, multipart/form-data und JSON (max. 128 KB, 50 Felder).

Endpoint: https://v3.mailiy.com/api/submit

Den Schlüssel kannst du statt im Feld access_key auch in die URL schreiben: https://v3.mailiy.com/api/submit/YOUR-KEY

Websites und Formulare

Im Dashboard legst du zuerst eine Website an, darin dann deine Formulare. Empfänger, Absendername, erlaubte Domains und Speicherdauer der Website gelten als Vorgabe für jedes neue Formular. Danach kannst du sie pro Formular ändern.

Dein Tarif legt fest, wie viele Websites, Zustellungen pro Monat und Empfänger je Formular du hast. Die Zustellungen zählen für alle Formulare deines Kontos zusammen und starten am Ersten jedes Monats neu.

Anmeldung und Sicherheit

Du meldest dich mit E-Mail-Adresse und Passwort an. Danach fragt Mailiy immer einen zweiten Faktor ab: einen Code per E-Mail oder einen Code aus deiner Authenticator-App, wenn du eine unter Konto → Sicherheit eingerichtet hast. Dabei bekommst du 10 Wiederherstellungscodes. Bewahre sie offline auf, jeder funktioniert einmal. Ein neues Passwort braucht mindestens 10 Zeichen und darf in keinem bekannten Datenleck vorkommen. Das prüfen wir gegen eine Liste auf unserem eigenen Server in der EU, dein Passwort geht dabei an niemanden sonst.

Unter Konto → Sicherheit siehst du auch, wo du angemeldet bist, und kannst einzelne Geräte abmelden.

Unter Konto → Benachrichtigungen legst du fest, welche E-Mails du bekommst: eine bei jeder Anmeldung, eine Warnung, wenn 90 % und 100 % deines Kontingents verbraucht sind, und einen Monatsbericht. Anmeldung und Warnungen sind am Anfang an, der Bericht ist aus.

Deine Anmeldeadresse änderst du unter Konto → Sicherheit mit deinem Passwort. Wir schicken einen Link an die neue Adresse, erst nach dem Klick gilt sie. Die alte Adresse bekommt eine Nachricht über den Wechsel.

Wenn du dein Konto löschst, nehmen deine Formulare sofort nichts mehr an. 30 Tage lang kannst du die Löschung im Dashboard rückgängig machen, danach löschen wir alle Daten endgültig.

HTML

<form action="https://v3.mailiy.com/api/submit" method="POST">
  <input type="hidden" name="access_key" value="YOUR-KEY">
  <input type="hidden" name="subject" value="Neue Kontaktanfrage">
  <input type="text" name="name" required>
  <input type="email" name="email" required>
  <textarea name="message" required></textarea>
  <label><input type="checkbox" name="consent" value="yes" required> Ich stimme der Verarbeitung zu.</label>
  <input type="checkbox" name="botcheck" class="hidden" style="display:none">
  <button type="submit">Senden</button>
</form>

Ohne JavaScript leitet Mailiy nach dem Absenden auf die Danke-Seite weiter (HTTP 303) oder auf deine eigene URL. Fehler landen mit ?error=code auf derselben Seite.

JavaScript

const res = await fetch("https://v3.mailiy.com/api/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json", Accept: "application/json" },
  body: JSON.stringify({ access_key: "YOUR-KEY", email, message }),
});
const { success, message } = await res.json();

Sendest du JSON oder den Header Accept: application/json, antwortet Mailiy mit JSON statt einer Weiterleitung.

Steuerfelder

Diese Felder steuern den Versand und erscheinen nicht in der E-Mail:

FeldBedeutung
access_keyPflicht. Öffentlicher Schlüssel des Formulars.
subjectBetreff der E-Mail. Überschreibt die Formular-Einstellung.
from_nameAbsendername in der E-Mail.
replyto / emailAntwortadresse. Ohne replyto wird das Feld email genutzt.
redirectURL für die Weiterleitung nach dem Absenden (http/https).
botcheckHoneypot. Unsichtbar lassen; ausgefüllt = Spam.
consentEinwilligung. Pflicht, wenn im Formular aktiviert.
ccemailWeitere Empfänger, getrennt mit Semikolon. Nur Adressen, die in deinem Konto bestätigt sind; andere werden ignoriert.
altcha / h-captcha-response / cf-turnstile-response / g-recaptcha-responseToken des Captcha-Widgets. Füllt das Widget selbst aus.

Spamschutz und Captcha

Jedes Formular hat ein Honeypot-Feld (botcheck), ein Rate-Limit und auf Wunsch erlaubte Domains. Das reicht meistens. Wenn trotzdem Spam ankommt, wählst du unter Einstellungen ein Captcha, für ein Formular oder als Vorgabe der Website.

ALTCHA lässt den Browser eine kleine Rechenaufgabe lösen, ohne Bilderrätsel und ohne Drittanbieter. Die Aufgabe kommt von Mailiy. Das Snippet unter Einrichtung enthält das Widget, sobald ALTCHA aktiv ist:

<altcha-widget challengeurl="https://v3.mailiy.com/api/altcha"></altcha-widget>
<script type="module" src="https://cdn.jsdelivr.net/npm/altcha@3.5.0/dist/main/altcha.js"></script>

Das Skript kommt im Beispiel von jsDelivr. Du kannst die Datei aus dem npm-Paket altcha auch selbst hosten.

hCaptcha, Cloudflare Turnstile und reCAPTCHA gehen auch. Du legst dort ein Konto an, baust deren Widget mit deinem Site-Key ein und trägst den geheimen Schlüssel im Dashboard ein. Mailiy speichert ihn verschlüsselt und zeigt ihn nie wieder an. Die IP-Adresse deiner Besucher geben wir bei der Prüfung nicht weiter.

Fehlt das Token oder ist es falsch, antwortet Mailiy mit captcha_failed (403) und zählt die Einsendung als Spam.

Antworten und Fehlercodes

{ "success": true, "message": "Submission received.", "body": { "data": { "email": "…" }, "message": "Submission received." } }
{ "success": false, "code": "consent_required", "message": "…", "body": { "data": {}, "message": "…" } }

Das Feld body hat denselben Aufbau wie bei web3forms, bestehende Skripte laufen also weiter. Bei 429 steht im Header Retry-After, wie viele Sekunden du warten musst: 60 bei rate_limited (mehr als 5 Einsendungen pro Minute), bis zum Monatsersten bei limit_reached.

CodeHTTP
invalid_body400
origin_not_allowed403
captcha_failed403
form_disabled403
invalid_access_key404
consent_required422
empty_submission422
limit_reached429
rate_limited429
delivery_failed500

Datenschutz-Checkliste

Webhook

Ist eine Webhook-URL gesetzt, schickt Mailiy jede Einsendung zusätzlich als JSON per POST dorthin: { form: { id, name }, created_at, data }. Nur HTTPS-Ziele mit öffentlicher IP sind erlaubt, Weiterleitungen werden nicht verfolgt, Timeout 5 Sekunden.