ID du formulaire

Protection anti-spam

Honeypot, horodatages signés, score de spam, vérification humaine, domaines autorisés et limites de débit.

Chaque formulaire bénéficie d'une protection en couches sans configuration : un honeypot, un horodatage d'affichage signé, un score de spam et des limites de débit. Vous pouvez y ajouter une vérification humaine et limiter le formulaire à vos propres domaines.

CoucheActive par défautRésultat
Limites de débitOui, préréglage Standard429 rate_limited
Domaines autorisésNonSpam, ou 403 origin_not_allowed
Vérification humaineNon403 challenge_required ou une page de vérification
HoneypotOui+5 au score
Score de spamOuiSpam à partir de 5

Comment le spam est traité

Un envoi jugé comme spam est stocké avec le statut spam et reçoit quand même une réponse de succès normale : les bots n'apprennent rien. Le spam n'envoie ni webhook ni e-mail, ne compte pas dans votre usage mensuel et est supprimé au bout de 30 jours. Examinez-le dans le tableau de bord ou avec l'API REST ; marquer une soumission comme légitime déclenche alors ses webhooks.

Honeypot

Ajoutez un input masqué que les humains ne remplissent jamais. Le nom par défaut est _gotcha ; vous pouvez le changer par formulaire sous Honeypot field dans les paramètres du formulaire. Les techniques pour le masquer sont sur Formulaires HTML.

Honeypot
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />

Score de spam

Chaque envoi reçoit un score calculé à partir de ces signaux. À partir de 5, il est stocké comme spam.

SignalRaison dans le tableau de bordScore
Le honeypot est remplihoneypot+5
Envoyé moins de 2 secondes après l'affichage du formulairetimestamp_fast+3
L'horodatage d'affichage signé est falsifié ou date de plus de 24 heurestimestamp_invalid+3
Un lien dans un champ de nom ou d'objeturl_in_name+3
Les mêmes champs ont été envoyés à ce formulaire dans les dernières 24 heuresduplicate+3
Trois liens ou plus au totalmany_urls+2
Une phrase de spam connue (22 intégrées)keyword+2
Une adresse e-mail sur un domaine d'e-mail jetabledisposable_email+2
  • L'horodatage d'affichage n'existe que si le formulaire est affiché par le SDK ou le composant shadcn/ui, qui envoient un _ikiform_ts signé. Les envois HTML simples qui ne l'ont pas ne sont pas pénalisés.
  • Un champ de nom est tout champ dont le nom contient name, firstname, lastname, fullname, surname ou subject, mais pas des mots comme company, website ou domain.
  • Deux raisons imposent le spam quel que soit le score : origin_mismatch, issue des domaines autorisés, et captcha_unavailable quand Turnstile est injoignable.

Vérification humaine

Chaque formulaire a un réglage Spam check avec trois options. Il est désactivé par défaut, pour que les intégrations fetch et curl existantes continuent de fonctionner quand vous créez un formulaire.

OptionRôle
OffAucune vérification. Le honeypot, l'horodatage et le score restent actifs.
Ikiform (recommandé)Cloudflare Turnstile exécuté par Ikiform sur ikiform.com. Aucun compte ni clé Cloudflare nécessaire.
Vos propres clés TurnstileVotre widget Turnstile et votre clé secrète. Le nom d'hôte du token est comparé à vos domaines autorisés.

Comment fonctionne la vérification Ikiform

Comment un formulaire obtient un token de vérification humaine, selon son mode d'envoi

Formulaire HTML

  1. Le navigateur envoie le formulaire
  2. Pas encore de token : ikiform.com affiche une courte page de vérification
  3. Turnstile s'exécute, la page renvoie les mêmes champs avec un token
  4. 303 vers votre redirection ou la page de remerciement

JavaScript

  1. challenge(formId) monte une frame ikiform.com masquée
  2. Turnstile s'exécute, et ne s'affiche que s'il a besoin d'un clic
  3. submit(formId, data, { turnstileToken })
  4. 201 avec l'id de la soumission

Serveur avec une clé secrète

  1. POST avec Authorization: Bearer ik_sk_...
  2. La vérification Ikiform est ignorée
  3. 201 avec l'id de la soumission
form.js
import { challenge, submit } from "@ikiform/sdk";

const form = document.querySelector("form");

form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const turnstileToken = await challenge("frm_xxxxxxxxxxxxxxxx");
  const result = await submit("frm_xxxxxxxxxxxxxxxx", new FormData(form), { turnstileToken });
  if (result.ok) form.replaceWith("Thanks, we got it.");
});

Les tokens sont à usage unique et valables 300 secondes : obtenez-en un par envoi. Un envoi JSON sans token reçoit 403 challenge_required avec une challenge_url ; un token dont la vérification échoue reçoit 403 captcha_failed.

403 Forbidden
{
  "ok": false,
  "error": {
    "code": "challenge_required",
    "message": "Complete the human check, then send the form again.",
    "challenge_url": "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx/challenge"
  },
  "request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}
Si Turnstile lui-même est injoignable, l'envoi est accepté et stocké comme spam avec la raison captcha_unavailable, pour que vous puissiez le restaurer au lieu de le perdre.

Vos propres clés Turnstile

Collez votre clé de site et votre clé secrète dans les paramètres du formulaire. Le secret est chiffré au repos. Affichez le widget dans votre formulaire pour qu'il ajoute cf-turnstile-response à l'envoi, ou passez le token à submit dans turnstileToken. Les envois sans token valide reçoivent 403 captcha_failed, y compris ceux avec une clé API secrète.

Domaines autorisés

Listez les domaines où se trouve votre formulaire sous Allowed domains. Un envoi doit alors venir de l'un d'eux ou d'un sous-domaine, d'après l'en-tête Origin, ou le Referer en l'absence d'origine. Laissez la liste vide pour accepter les envois de n'importe quel site.

Domaines autorisésEnvoi depuisCorrespond
example.comhttps://example.comOui
example.comhttps://www.example.comOui, sous-domaine
example.comhttp://localhost:3000Non, ajoutez localhost pendant le développement
example.comhttps://example.coNon
app.example.comhttps://example.comNon, un domaine parent ne correspond pas

When a post comes from another site détermine ce qui arrive en cas de non-correspondance : Mark as spam (par défaut) ou Reject avec 403 origin_not_allowed. Les envois avec une clé API secrète contournent ce contrôle. Les domaines autorisés déterminent aussi quelles cibles _redirect sont suivies et où la frame de vérification Ikiform peut être intégrée.

Limites de débit

Chaque formulaire a un préréglage Rate limit, compté exactement par IP de visiteur et par formulaire. Standard autorise 5 envois par minute, Relaxed 20 par minute et Strict 2 toutes les 10 minutes. Les règles complètes sont sur Limites de débit.