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.
| Couche | Active par défaut | Résultat |
|---|---|---|
| Limites de débit | Oui, préréglage Standard | 429 rate_limited |
| Domaines autorisés | Non | Spam, ou 403 origin_not_allowed |
| Vérification humaine | Non | 403 challenge_required ou une page de vérification |
| Honeypot | Oui | +5 au score |
| Score de spam | Oui | Spam à 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.
<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.
| Signal | Raison dans le tableau de bord | Score |
|---|---|---|
| Le honeypot est rempli | honeypot | +5 |
| Envoyé moins de 2 secondes après l'affichage du formulaire | timestamp_fast | +3 |
| L'horodatage d'affichage signé est falsifié ou date de plus de 24 heures | timestamp_invalid | +3 |
| Un lien dans un champ de nom ou d'objet | url_in_name | +3 |
| Les mêmes champs ont été envoyés à ce formulaire dans les dernières 24 heures | duplicate | +3 |
| Trois liens ou plus au total | many_urls | +2 |
| Une phrase de spam connue (22 intégrées) | keyword | +2 |
| Une adresse e-mail sur un domaine d'e-mail jetable | disposable_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_tssigné. 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,surnameousubject, mais pas des mots commecompany,websiteoudomain. - Deux raisons imposent le spam quel que soit le score :
origin_mismatch, issue des domaines autorisés, etcaptcha_unavailablequand 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.
| Option | Rôle |
|---|---|
| Off | Aucune 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 Turnstile | Votre 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
Formulaire HTML
- Le navigateur envoie le formulaire
- Pas encore de token : ikiform.com affiche une courte page de vérification
- Turnstile s'exécute, la page renvoie les mêmes champs avec un token
- 303 vers votre redirection ou la page de remerciement
JavaScript
- challenge(formId) monte une frame ikiform.com masquée
- Turnstile s'exécute, et ne s'affiche que s'il a besoin d'un clic
- submit(formId, data, { turnstileToken })
- 201 avec l'id de la soumission
Serveur avec une clé secrète
- POST avec Authorization: Bearer ik_sk_...
- La vérification Ikiform est ignorée
- 201 avec l'id de la soumission
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.
{
"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"
}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és | Envoi depuis | Correspond |
|---|---|---|
example.com | https://example.com | Oui |
example.com | https://www.example.com | Oui, sous-domaine |
example.com | http://localhost:3000 | Non, ajoutez localhost pendant le développement |
example.com | https://example.co | Non |
app.example.com | https://example.com | Non, 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.