# Dépannage

> Solutions aux erreurs CORS, origines non conformes, challenge_required, erreurs 429, champs inconnus et erreurs de quota.

Commencez par la réponse. Chaque réponse d'Ikiform a un en-tête `X-Request-Id` et, pour les erreurs, un `error.code` stable. Cette commande curl affiche les deux, depuis la même origine que celle de votre site :

`Terminal`:

```bash
curl -i https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Origin: https://example.com" \
  -d '{"email":"ada@example.com"}'
```

Vous voyez des erreurs `5xx` ou des timeouts venant d'Ikiform lui-même ? Consultez d'abord [status.ikiform.com](https://status.ikiform.com) pour les incidents en cours.

## Le navigateur indique que CORS a bloqué la requête

L'endpoint de soumission autorise toutes les origines, donc un vrai échec CORS signifie généralement que la requête n'a jamais atteint Ikiform, ou qu'elle est partie vers la mauvaise URL.

- Vérifiez que l'URL est `https://ikiform.com/f/<formId>` avec l'id `frm_` complet, par exemple `frm_xxxxxxxxxxxxxxxx`, sans chemin supplémentaire.
- Vous appelez `/api/v1` depuis un navigateur. L'API REST refuse les navigateurs par conception ; appelez-la depuis votre serveur.
- Un bloqueur de publicités, une extension de confidentialité ou un proxy d'entreprise a bloqué la requête. Essayez une fenêtre de navigation privée sans extension.
- La `Content-Security-Policy` de votre propre site la bloque. Ajoutez `https://ikiform.com` à `connect-src`, et à `form-action` pour les envois HTML classiques.

Vérifiez directement le preflight ; il doit répondre `204` en renvoyant votre origine :

`Terminal`:

```bash
curl -i -X OPTIONS https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx \
  -H "Origin: https://example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: content-type"
```

## Les soumissions arrivent dans le spam avec origin_mismatch

Le formulaire a des domaines autorisés et l'envoi est venu d'ailleurs. Le tableau de bord affiche `origin_mismatch` parmi les raisons de spam.

- Ajoutez chaque domaine depuis lequel le formulaire est servi, y compris `www`, les domaines de staging et de prévisualisation. Les sous-domaines d'un domaine listé correspondent déjà.
- Ajoutez `localhost` pendant le développement en local.
- Les envois depuis votre propre serveur n'ont pas d'`Origin`. Envoyez une clé secrète, qui contourne ce contrôle.
- Avec **Reject** au lieu de **Mark as spam**, les mêmes envois reçoivent `403 origin_not_allowed`.

## 403 challenge_required

Le contrôle anti-spam du formulaire est réglé sur **Ikiform** et l'envoi n'avait pas de token Turnstile.

1. Code navigateur : appelez `challenge(formId)` du SDK juste avant chaque envoi, et passez le token à `submit` dans `turnstileToken`.
2. Code serveur : envoyez `Authorization: Bearer ik_sk_...` avec une clé secrète ; les clés secrètes contournent la vérification.
3. Les envois HTML classiques ne voient jamais ce code ; ils reçoivent la page de vérification à la place. Si vous le voyez sur un envoi de formulaire, quelque chose envoie `Accept: application/json`.
4. Vous testez avec curl ? Désactivez la vérification sur un formulaire de test, ou utilisez une clé secrète.

`403 captcha_failed` signifie qu'un token a été envoyé mais que sa vérification a échoué. Les tokens sont à usage unique et expirent au bout de 300 secondes : obtenez-en un nouveau à chaque tentative.

## 429 rate_limited

- Lisez `Retry-After` et attendez ce nombre de secondes.
- Vous testez à la main ? Le préréglage Standard autorise 5 envois par minute depuis une IP, et 3 en 10 secondes. Passez un formulaire de test sur Relaxed.
- Vous envoyez depuis votre serveur pour chaque visiteur ? Tous les envois partagent l'IP de votre serveur. Envoyez depuis le navigateur, ou choisissez Relaxed ou Custom.
- Beaucoup de personnes derrière le réseau d'un bureau ou d'un événement partagent aussi une IP. Relaxed autorise 20 envois par minute.

## 422 avec Unknown field

Le formulaire a des champs définis et l'envoi contient un nom absent de la définition. `error.fields` l'indique, par exemple `{ "website": ["Unknown field \"website\""] }`.

- Ajoutez le champ à la définition, ou retirez l'input.
- Renommez l'input pour qu'il commence par `_` s'il ne sert que de marqueur pour vous ; les noms réservés sont retirés, pas validés.
- Vérifiez que le nom du honeypot correspond au réglage **Honeypot field** du formulaire.
- Les ids de champs sont en snake_case minuscule : `firstName` dans votre markup n'est pas la même chose que `first_name` dans la définition.

## 429 quota_exceeded

L'espace de travail a reçu ce mois-ci 2 fois sa limite mensuelle et n'accepte plus de soumissions jusqu'au début du mois suivant ou jusqu'à un changement de palier. Voir [Usage mensuel](https://ikiform.com/fr/docs/limits.md#monthly-usage).

## Les soumissions n'apparaissent pas

- Regardez sous le filtre spam. Le spam reçoit une réponse de succès normale, donc le visiteur ne peut pas s'en rendre compte.
- Vérifiez que le formulaire n'est pas en pause, et que l'id dans votre `action` correspond au tableau de bord.
- Un envoi depuis un navigateur qui affiche la page d'erreur d'Ikiform a été refusé ; la page en indique la raison.

## Les webhooks échouent

- `no_matching_signature` : vérifiez par rapport au corps brut, avant toute analyse JSON, et contrôlez que vous avez copié le bon secret `whsec_`. Collez une livraison dans le [vérificateur](https://ikiform.com/fr/docs/webhooks.md#verifier).
- `timestamp_too_old` : l'horloge de votre serveur est décalée, ou vous rejouez une ancienne livraison.
- Timeouts : répondez en moins de 15 secondes et faites le travail lent ensuite.
- Les redirections ne sont pas suivies. Utilisez l'URL finale, y compris la barre oblique finale qu'attend votre framework.
- L'endpoint a été désactivé après 5 jours d'échecs ou un `410`. Corrigez-le, puis réactivez-le depuis la page de l'endpoint.
