API
API formulaires
L'adresse publique qui reçoit un formulaire depuis ton site, ses réponses et ses erreurs, et la lecture des formulaires et des réponses avec une clé.
Un formulaire se crée dans l’application (voir Créer un formulaire). Son adresse d’envoi reçoit les réponses depuis n’importe quelle page, sans clé. Avec une clé à accès complet, l’API liste tes formulaires et lit leurs réponses : c’est ce qu’utilise Host pour proposer un formulaire à un site qu’il héberge.
Pour recevoir chaque réponse sans interroger l’API, utilise un webhook.
POST /f/:public_id
Envoie une réponse au formulaire. Pas de clé : l’identifiant public n’ouvre que l’envoi de réponses à ce formulaire.
Le corps est en JSON, en application/x-www-form-urlencoded ou en multipart/form-data, 64 Ko au plus, une valeur par champ. Les noms sont les variables du formulaire (prenom, email…). Une case cochée vaut oui, on ou true.
<form action="https://api.mail.hgdc.ch/f/k7m2p9x4q8ab" method="POST"> <input name="prenom" required> <input name="email" type="email" required> <textarea name="message"></textarea> <label><input type="checkbox" name="consentement" value="oui"> J'accepte de recevoir vos nouvelles</label> <input type="text" name="_gotcha" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px"> <button type="submit">Envoyer</button></form>Avec Accept: application/json, la réponse est en JSON. Statut 200 :
{ "ok": true, "message": "Merci, votre message a bien été envoyé.", "redirect_url": "https://ton-site.ch/merci" }redirect_url n’est là que si le formulaire a une page de remerciement. Sans Accept: application/json (formulaire HTML classique), la réponse est une redirection 303 vers cette page, ou vers la page de remerciement de Mail.
Champs spéciaux
| Champ | Rôle |
|---|---|
_gotcha | Piège à robots : laisse-le caché et vide. Rempli, l’envoi semble réussir mais rien n’est gardé. |
cf-turnstile-response | Jeton de Cloudflare Turnstile, posé par son widget. Obligatoire quand le formulaire a Turnstile. |
Erreurs
Toujours { "ok": false, "error": { "code", "message" } }. Le message s’adresse au visiteur, en vouvoiement : tu peux l’afficher tel quel.
| Statut | code | Quand |
|---|---|---|
| 404 | not_found | Identifiant inconnu. |
| 403 | origin_not_allowed | La page n’est pas sur un des sites autorisés du formulaire. |
| 403 | form_closed | Le formulaire est en pause. |
| 413 | too_large | Plus de 64 Ko. |
| 429 | rate_limited | Trop d’envois en peu de temps depuis cette adresse IP, ou pour ce formulaire. |
| 422 | captcha_failed | Le jeton Turnstile manque ou n’est pas valide. |
| 422 | validation_error | Un champ est à corriger : errors donne un message par champ. |
{ "ok": false, "error": { "code": "validation_error", "message": "Certains champs sont à corriger." }, "errors": { "email": "Cette adresse e-mail n'est pas valide." }}Origine et CORS
Le formulaire n’accepte que les pages de ses sites autorisés, lus dans l’en-tête Origin (sinon Referer). Sans site autorisé, toute page peut l’envoyer. La requête OPTIONS d’un navigateur est acceptée, et la réponse porte Access-Control-Allow-Origin pour une origine permise.
GET /forms
Clé à accès complet. Renvoie les 100 formulaires les plus récents, avec leurs champs et leur adresse d’envoi.
curl https://api.mail.hgdc.ch/forms \ -H "Authorization: Bearer $AGENTMAIL_API_KEY"{ "object": "list", "data": [ { "object": "form", "id": "jd7f3k9m2p5q8r1t4v6w0x3y", "public_id": "k7m2p9x4q8ab", "name": "Contact", "status": "active", "endpoint": "https://api.mail.hgdc.ch/f/k7m2p9x4q8ab", "fields": [], "allowed_origins": ["ton-site.ch"], "turnstile_site_key": null, "response_count": 12, "created_at": "2026-10-15T09:00:00.000Z" } ]}Types de champ : text, email, phone, textarea, choice, checkbox, consent.
GET /forms/:id
Lit un formulaire. :id est l’identifiant ou l’identifiant public. Même forme qu’un élément de la liste. Un formulaire d’un autre espace renvoie 404 not_found.
GET /forms/:id/responses
Lit les réponses, les plus récentes d’abord. limit de 1 à 100 (50 par défaut), puis after avec le next_cursor reçu.
{ "object": "list", "has_more": false, "next_cursor": null, "data": [ { "object": "form_response", "id": "m2k8p4x7q1ab9c3d5e6f0g2h", "values": { "prenom": "Léa", "email": "lea@exemple.ch", "message": "Bonjour", "consentement": "oui" }, "email": "lea@exemple.ch", "contact_id": "kn4d7b2x9q1m6v3r8c0w5h2t", "consent": { "status": "confirmed", "text": "J'accepte de recevoir vos nouvelles", "at": "2026-10-15T09:12:00.000Z" }, "created_at": "2026-10-15T09:12:00.000Z" } ]}Si ça ne marche pas
403 origin_not_allowed: le site qui envoie le formulaire n’est pas dans la liste des sites autorisés. Ajoute son domaine dans les réglages du formulaire.422 captcha_failed: le widget Turnstile n’a pas transmis son jeton. Vérifie quecf-turnstile-responseest bien dans le formulaire.429 rate_limited: trop de soumissions depuis la même adresse. Réessaie dans une minute.
Cette page t'a aidé ?
Merci, c'est noté.