Formular-API-Referenz
Technische Details zur Verbindung eines Website-Formulars mit MailContact.
Website-Builder? Starte mit Kontaktformular hinzufügen für Einrichtungsschritte und einen Prompt zum Kopieren.
Kopiere den Formularlink aus den Projekteinstellungen. Er sieht so aus, mit deiner eigenen Formular-ID am Ende:
POST https://mailcontact.app/api/forms/your-form-idEs akzeptiert sowohl FormData (was ein natives HTML-Formular sendet) und application/json. Zugestellte Einsendungen landen im Postfach und lösen deine Benachrichtigungskanäle. In Spam zurückgehaltene Nachrichten warten ohne Benachrichtigung und Kontingentverbrauch auf Prüfung.
Felder
| Feld | erforderlich | Hinweise |
|---|---|---|
name | optional | Als Absender angezeigt. Ohne Namen wird die E-Mail-Adresse genutzt. Höchstens 200 Zeichen. |
email | erforderlich | E-Mail-Adresse des Absenders. Validiert: Fehlende oder ungültige Adressen werden mit 400 abgelehnt. |
subject | optional | Höchstens 300 Zeichen. |
message | erforderlich | Nachrichteninhalt. Darf nicht leer sein und höchstens 5.000 Zeichen enthalten. |
Ein erforderliches Textfeld namens company_website muss vorhanden und leer sein. Ein nicht leerer Wert kennzeichnet Bot-Verkehr und wird ohne Rückmeldung verworfen. Das ist die Honeypot-Trick gegen Spam). Alle anderen unbekannten Felder werden ignoriert.
Das Skript fügt markierten Formularen dieses Feld automatisch hinzu. Fehlt es, folgt FORM_CHECK_MISSING; ein ausgefülltes Feld wird ohne Rückmeldung verworfen. Ein leeres Feld umgeht weder Spam- noch Raten- oder Verifizierungsprüfungen. Leistungsfähigere Bots können die Falle trotzdem erkennen.
Der gehostete Client verwirft ein ausgefülltes Fallenfeld vor Konfigurations- oder Versandanfrage still und liefert { ok: true } um die normale Bestätigung wie bei der Bot-Antwort des Endpunkts zu erhalten. Für direkte API-Anfragen gilt dieselbe serverseitige Falle.
Empfohlen: MailContact-Skript nutzen
Hinzufügen data-mailcontact-form am Formular und lade unser Skript einmal pro Seite. Behalte deine Styles. Das Skript übernimmt Versand, barrierefreie Rückmeldungen, automatische Prüfung und Wiederholungen. Bei Fehlern bewahrt es den Text; nur bestätigter Erfolg setzt das Formular zurück.
Der automatische Handler blockiert weitere Einsendungen während des Versands und zehn Sekunden nach bestätigtem Erfolg. Versandbuttons und Tastaturversand bleiben gesperrt. Felder werden wieder bearbeitbar, die Bestätigung bleibt. Nach Fehlern ist sofortige Wiederholung möglich, sofern der Server keinen Retry-After Wartezeit.
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST" data-mailcontact-form>
<label>Email <input type="email" name="email" maxlength="320" required /></label>
<label>Message <textarea name="message" maxlength="5000" required></textarea></label>
<button type="submit">Send</button>
<p data-contact-status role="status" aria-live="polite" aria-atomic="true"></p>
</form>
<script defer src="https://mailcontact.app/forms/v1.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>Ein Skript unterstützt mehrere und später eingefügte Formulare. Es fügt das verborgene Prüffeld einmal bei Initialisierung ein und prüft beim Senden, ob es noch vorhanden und leer ist. Ein entferntes oder deaktiviertes Feld blockiert den Versand und bewahrt den Entwurf. Es sendet an das jeweilige action, unabhängig vom Hosting des Skripts. Verwende HTTPS oder localhost für die automatische Prüfung. Der Generator enthält außerdem ein natives noscript Fallback; für eine manuelle Einbindung ohne JavaScript nutze das einfache HTML-Beispiel unten.
Du kontrollierst HTML, CSS, Beschriftungen und Buttons. Nur unterstützte Feldnamen müssen gleich bleiben; andere ignoriert die API. Setze data-mailcontact-success="Thanks, we’ll reply soon." am Formular, um den Bestätigungstext anzupassen. Für vollständig eigene Abläufe nutze MailContact.send() unten.
Sprache der Rückmeldungen
Versand-, Prüf-, Bestätigungs- und Fehlermeldungen folgen den Browsersprachpräferenzen. Unterstützt werden Französisch, Englisch, Spanisch, Deutsch, Italienisch und Portugiesisch, einschließlich Varianten wie fr-CA und pt-BR. Die erste unterstützte Browsersprache wird verwendet. Passt keine, erscheinen Rückmeldungen auf Englisch.
Festlegen data-mailcontact-language="fr" bei einem automatischen Formular, um Französisch unabhängig von Browser und anderen Formularen zu erzwingen. Unterstützte Sprachvorgaben haben Vorrang. Leere oder unbekannte Werte nutzen Browsererkennung. Die Einstellung wird bei jeder Einsendung gelesen. Beschriftungen, ursprünglicher Buttoninhalt und data-mailcontact-success bleiben unter deiner Kontrolle. Eigene Bestätigungstexte werden nie automatisch übersetzt. Native HTML-Validierungshinweise steuert weiter der Browser.
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST"
data-mailcontact-form data-mailcontact-language="fr">
<!-- Keep your existing fields, button and status element here. -->
</form>Formulare eines Free-Kontos zeigen einen kleinen Link „Processed by mailcontact.app“. Pro und Plus haben keinen MailContact-Hinweis. Das Skript liest den Tarif des Postfachinhabers und passt sich nach einem Tarifwechsel ohne neue Einbindung an. Die Einstellung kann bis zu eine Minute zwischengespeichert werden. Gestalte das data-mailcontact-branding Element an deine Website anzupassen.
Verwendet deine Website eine Content Security Policy, erlaube die Skriptherkunft in script-src und die Herkunft des Formular-Endpunkts in connect-src und form-action. Für diese Einbindung ist keine Berechtigung für Inline-JavaScript nötig. Das v1 URL erhält kompatible Updates. Künftige inkompatible Änderungen nutzen eine neue Version. Du kannst das weitergereichte mailcontact:success Ereignis für dein eigenes Verhalten nach Erfolg.
Vollständig eigene Oberflächen
Lade dasselbe Skript und rufe dann auf: MailContact.send() aus deinem eigenen Handler. Lass data-mailcontact-form damit der automatische Handler deine Oberfläche nicht verändert. Du kontrollierst Schritte, Ladezustand, Fehler und Bestätigung. Die Funktion übernimmt Anfrage, signierte Verifizierung und erneuten Versand. Sie ändert weder DOM noch Eingabefelder.
const endpoint = "https://mailcontact.app/api/forms/your-form-id";
const form = document.querySelector("#contact-form");
MailContact.prepare(form); // Inject once before the visitor fills the form.
const language = form.getAttribute("data-mailcontact-language") || undefined;
const text = MailContact.getMessages(language);
const config = await MailContact.getConfig({ endpoint, language });
// If config.branding is true, show a visible "Processed by mailcontact.app"
// link to https://mailcontact.app in your own form layout.
async function submit() {
showStatus(text.sending);
try {
await MailContact.send({
endpoint,
data: new FormData(form),
language, // Optional: omit for automatic browser language detection.
onVerification: () => showStatus(text.verification),
brandingElement: document.querySelector("[data-mailcontact-branding]"),
// signal: abortController.signal, // optional cancellation
});
showYourConfirmation();
} catch (error) {
// error.code, error.status and error.retryAfter (seconds or null)
// let you choose your own translated feedback. Keep the draft.
showYourError(error);
}
}MailContact.prepare(form) fügt nur das verborgene Feld hinzu, ohne Submit-Handler oder Designänderung. Rufe es einmal pro eingebundenem Formular vor Interaktion auf. Ein entferntes Feld wird nie neu erstellt, ein vorhandener Wert nie gelöscht. data akzeptiert auch ein Objekt mit name, email, subject, message und dem erforderlichen company_website Wert. Der Client sichert Felder für Prüf-Wiederholungen. Er bestätigt den Empfang oder verwirft die ausgefüllte Falle still mit { ok: true }, und löst aus: MailContact.FormError bei Fehlern. Fehlende Prüffelder verwenden FORM_CHECK_MISSING, bei Netzwerkfehlern wird verwendet: NETWORK_ERROR, bei Abbruch oder Zeitüberschreitung wird verwendet: ABORTED. Es gelten 60 Sekunden Zeitlimit und höchstens ein erneuter Verifizierungsversuch.
MailContact.getConfig({ endpoint }) sendet eine öffentliche GET-Anfrage an die Formular-URL und liefert nur { branding: true | false }. Eigene Oberflächen stellen diesen Hinweis bei Bedarf selbst dar und übergeben sein Element als brandingElement (oder eine Funktion, die es zurückgibt). Bei jedem Versand wird die Servereinstellung geprüft. Bei Free führt ein fehlender, versteckter, unlesbarer oder nicht anklickbarer Link zu https://mailcontact.app löst aus BRANDING_REQUIRED bevor eine Nachricht gesendet wird. Pro und Plus brauchen keinen Link. Dies ist eine Integrationsprüfung im Browser, kein serverseitiger Nachweis des Inhalts fremder Seiten. Identität oder Abrechnung des Inhabers werden nicht offengelegt. React, Vue und andere Frameworks können diese Funktionen nach Laden des Skripts aufrufen. Die direkte API bleibt ebenfalls verfügbar.
Der eigene Client übersetzt FormError.message automatisch; code, status und retryAfter bleiben unverändert. Übergib language: "fr" an send() oder getConfig() um die Browsersprache zu überschreiben. Ein eigener Handler liest das Datenattribut wie oben selbst. MailContact.getMessages(language?) liefert passenden Rückmeldungstext für deine Oberfläche, einschließlich sendingButton, sending, verification, success und wait(seconds). Es liefert ein separates Objekt zurück, damit dein eigener Text andere Formulare nicht verändert. Bei fehlgeschlagenem automatischem Nachweis wird verwendet: VERIFICATION_FAILED. Es werden weder Übersetzungsdienst noch zusätzliche Sprachanfrage genutzt. Die unverarbeiteten JSON-Antworten der API behalten ihre bisherigen Codes und ihre Sprache.
Automatische Prüfung verdächtiger Einsendungen
Das gehostete Skript übernimmt die Verifizierung. Eigene Clients können senden: _verification: "1" um automatische Verifizierung zu unterstützen. Eine verdächtige Anfrage kann HTTP 403 zurückgeben mit code: CHALLENGE_REQUIRED und ein signiertes challenge Objekt. Es erzeugt weder zugestellte Nachricht noch Kontingentverbrauch. Löse die Aufgabe und sende die ursprünglichen Felder erneut, mit der JSON-Lösung in _proof. Das eigenständige /form-challenge.js Hilfsfunktion stellt bereit: window.mailcontactSolveChallenge(challenge, signal?), das diesen JSON-String zurückgibt. Verdächtige individuelle Anfragen mit Pflichtprüfung, aber ohne Unterstützung der Verifizierung, werden in Spam zur Prüfung zurückgehalten. Fehlende Verifizierung umgeht die Prüfung nie.
Der Nachweis läuft nach fünf Minuten ab, gilt nur für genau diese Felder, das Formular und den Client und wird einmal akzeptiert. Bewahre den Entwurf bei Fehlern. Native Browserformulare erhalten stattdessen eine automatische Prüfseite. Stark verdächtige Nachrichten landen ohne Benachrichtigung und Kontingentverbrauch in Spam; die öffentliche Erfolgsantwort verrät die Einstufung nicht.
Einfaches HTML-Formular
Die Version ohne JavaScript: Benenne Felder wie oben und der Browser erledigt den Rest:
<form action="https://mailcontact.app/api/forms/your-form-id" method="POST">
<input type="text" name="name" placeholder="Your name" />
<input type="email" name="email" placeholder="[email protected]" required />
<input type="text" name="subject" placeholder="Subject" />
<textarea name="message" placeholder="Your message" required></textarea>
<button type="submit">Send</button>
<input name="company_website" type="text" tabindex="-1" autocomplete="off"
style="position:absolute;left:-10000px" aria-hidden="true" />
</form>Eine native Formulareinsendung öffnet bei Erfolg die JSON-Antwort des Endpunkts, bei Bedarf eine HTML-Prüfseite. Mit unserem Skript oben bleiben Besucher auf der Seite und sehen die Erfolgsanzeige direkt im Formular.
JSON mit fetch
Senden application/json mit einem Content-Type Header. Gleiche Felder, gleiche Validierung:
const res = await fetch("https://mailcontact.app/api/forms/your-form-id", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "Ada",
company_website: "",
email: "[email protected]",
subject: "Hello",
message: "Trying out the endpoint.",
}),
});
const data = await res.json();
if (data.ok) {
// show your inline "thanks, message sent" state
}Du kannst auch einen POST senden mit FormData Objekt aus JavaScript: Lass das Content-Type Header und übergib new FormData(formElement) als Inhalt.
CORS
CORS ist offen: Der Endpunkt antwortet mit Access-Control-Allow-Origin: * und übernimmt das OPTIONS Preflight, daher funktionieren Einsendungen jeder Herkunft: Domain, localhost, Staging-URL oder statischer Host wie GitHub Pages. Keine Freigabeliste nötig.
Antworten und Fehler
Bei Erfolg liefert der Endpunkt 200 mit {"ok": true}. Das umfasst auch in Spam zurückgehaltene Nachrichten und still verworfene ausgefüllte Prüffelder; eine Postfachzustellung wird damit nicht zugesagt. Validierungsfehler sind JSON im Format {"ok": false, "code": "...", "error": "..."}. Die Verifizierung verwendet {"ok": false, "code": "CHALLENGE_REQUIRED", "challenge": {...}}, oder eine HTML-Seite für native Browser-Einsendungen. Ungültiges JSON, falsche Feldtypen, doppelte Formularfelder und zu lange Inhalte führen zu 400:
| Status | error | wenn |
|---|---|---|
403 | Automatische Prüfung erforderlich. | CHALLENGE_REQUIRED: Löse die signierte Aufgabe und sende die ursprünglichen Felder erneut mit _proof. Ungültige, abgelaufene oder wiederverwendete Nachweise erhalten eine neue Aufgabe. Das gehostete Skript übernimmt automatisch einen Wiederholungsversuch. |
400 | Formularprüfung fehlt. | FORM_CHECK_MISSING: das erforderliche company_website Feld fehlt. Das Skript fügt es bei Initialisierung ein. Native und direkte API-Integrationen müssen es ausdrücklich enthalten. |
400 | Eine gültige E-Mail-Adresse ist erforderlich. | email fehlt, ist ungültig oder länger als 320 Zeichen |
400 | Die Nachricht darf nicht leer sein. | message fehlt oder ist leer |
404 | Unbekanntes Formular. | die Formular-ID der URL existiert nicht |
413 | Anfrageinhalt zu groß. | Anfrageinhalt über 64 KB |
429 | Zu viele Anfragen. | mehr als 20 Formularanfragen pro Minute von einer IP oder 60 angenommene Nachrichten pro Minute in einem Postfach |
429 | Zu viele Anfragen. | Mehr als 5 angenommene Einsendungen pro Minute derselben E-Mail-Adresse an ein Formular, auch über verschiedene IPs. Ein Retry-After Header nennt die Wartezeit. |
429 | Diese Nachricht wurde bereits empfangen. | Derselbe Absender, Betreff und Inhalt wurden in der letzten Minute bereits angenommen. Der Antwortcode lautet DUPLICATE_MESSAGE. Es entstehen keine weitere Nachricht, Benachrichtigung oder Kontingentbelastung. |
429 | Monatskontingent erreicht. | Der Antwortcode lautet MONTHLY_QUOTA_EXCEEDED, mit einem Retry-After Header bis zur nächsten monatlichen Kontingenterneuerung des Kontos. |
429 | Das Postfach kann keine weiteren Nachrichten zur Prüfung annehmen. | SPAM_STORAGE_LIMIT: Das Projekt enthält bereits 500 ungeprüfte Spam-Nachrichten. Es werden keine weiteren Nachrichten empfangen. Nutze einen anderen Kontaktweg. Die Antwort enthält Retry-After. |
415 | Nicht unterstützter Inhaltstyp. | Nutze JSON, URL-codierte oder Multipart-Formulardaten. |
Limits
- Anfrageinhalte sind auf 64 KB begrenzt.
- Ratenlimit: 20 Anfragen pro Minute und IP, auch über Neustarts hinweg. Darüber folgt 429 mit Retry-After.
- Absenderlimit: 5 angenommene Einsendungen pro Minute, Formular und E-Mail-Adresse. Identische Einsendungen desselben Absenders höchstens einmal pro Minute; unterschiedliche Leerzeichen werden normalisiert.
- Feldlängen:
name200,subject300,message5.000 Zeichen; längere Werte werden abgelehnt. E-Mail-Adressen mit mehr als 320 Zeichen werden abgelehnt.
Free enthält 50 Formulareinsendungen pro Monat für ein Projekt. Pro umfasst 1.000 gemeinsame Nachrichten für zehn Projekte; Plus 10.000 für fünfzig Projekte. Empfang und Antworten verbrauchen dasselbe Kontingent. Monatskontingente gelten für das gesamte Konto. Siehe Preise.
Verwandt
Neu hier? Starte mit Erste Schritte. Füge mit Pro und Plus ein Kontakt-E-Mail-Adresse führen in dasselbe Postfach. Das Spamschutz zeigt, wie du unerwünschte Inhalte von einem offenen Endpunkt fernhältst. Für einen fertigen Codeschnipsel nutze das Kontaktformular-Generator oder die Framework-Anleitungen.