# Solução de problemas

> Correções para erros de CORS, origens divergentes, challenge_required, erros 429, campos desconhecidos e erros de cota.

Comece pela resposta. Toda resposta do Ikiform tem um header `X-Request-Id` e, em erros, um `error.code` estável. Este curl mostra os dois, a partir da mesma origem que o seu site usaria:

`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"}'
```

Vendo erros `5xx` ou timeouts do próprio Ikiform? Confira primeiro [status.ikiform.com](https://status.ikiform.com) para ver incidentes em andamento.

## O navegador diz que o CORS bloqueou a requisição

O endpoint de envio permite qualquer origem, então uma falha de CORS de verdade normalmente significa que a requisição nunca chegou ao Ikiform, ou foi para a URL errada.

- Confira se a URL é `https://ikiform.com/f/<formId>` com o id `frm_` completo, por exemplo `frm_xxxxxxxxxxxxxxxx`, e sem caminho extra no final.
- Você está chamando `/api/v1` a partir de um navegador. A API REST recusa navegadores por design; chame-a a partir do seu servidor.
- Um bloqueador de anúncios, uma extensão de privacidade ou um proxy corporativo bloqueou a requisição. Tente em uma janela anônima sem extensões.
- A própria `Content-Security-Policy` do seu site a bloqueia. Adicione `https://ikiform.com` a `connect-src`, e a `form-action` para envios HTML simples.

Confira o preflight diretamente; ele deve responder `204` devolvendo a sua origem:

`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"
```

## Os envios caem em spam com origin_mismatch

O formulário tem domínios permitidos e o envio veio de outro lugar. O painel mostra `origin_mismatch` entre os motivos de spam.

- Adicione todos os domínios de onde o formulário é servido, incluindo `www`, staging e domínios de preview. Subdomínios de um domínio listado já correspondem.
- Adicione `localhost` enquanto desenvolve localmente.
- Envios do seu próprio servidor não têm `Origin`. Envie uma chave secreta, que pula a verificação.
- Com **Reject** escolhido em vez de **Mark as spam**, os mesmos envios recebem `403 origin_not_allowed`.

## 403 challenge_required

A verificação de spam do formulário está definida como **Ikiform** e o envio não tinha token do Turnstile.

1. Código no navegador: chame `challenge(formId)` do SDK logo antes de cada envio e passe o token para `submit` como `turnstileToken`.
2. Código no servidor: envie `Authorization: Bearer ik_sk_...` com uma chave secreta; chaves secretas pulam a verificação.
3. Envios HTML simples nunca veem este código; eles recebem a página de verificação. Se você o vê em um envio de formulário, algo está enviando `Accept: application/json`.
4. Testando com curl? Desative a verificação em um formulário de teste, ou use uma chave secreta.

`403 captcha_failed` significa que um token foi enviado mas não passou na verificação. Os tokens são de uso único e expiram após 300 segundos, então obtenha um novo a cada tentativa.

## 429 rate_limited

- Leia o `Retry-After` e espere esse número de segundos.
- Testando na mão? O preset Standard permite 5 envios por minuto de um mesmo IP, e 3 em 10 segundos. Mude um formulário de teste para Relaxed.
- Enviando do seu servidor em nome de cada visitante? Todos os envios compartilham o IP do seu servidor. Envie do navegador, ou escolha Relaxed ou Custom.
- Muitas pessoas atrás da mesma rede de escritório ou de evento também compartilham um IP. O Relaxed permite 20 por minuto.

## 422 com Unknown field

O formulário tem campos definidos e o envio mandou um nome que não está na definição. `error.fields` indica qual, por exemplo `{ "website": ["Unknown field \"website\""] }`.

- Adicione o campo à definição, ou remova o input.
- Renomeie o input para começar com `_` se ele for só um marcador para você; nomes reservados são descartados, não validados.
- Confira se o nome do honeypot corresponde à configuração **Honeypot field** do formulário.
- Ids de campo são snake_case em minúsculas: `firstName` no seu markup não é a mesma coisa que `first_name` na definição.

## 429 quota_exceeded

O workspace recebeu 2 vezes o seu limite mensal neste mês e para de aceitar envios até o próximo mês começar ou o workspace fazer upgrade. Veja [Uso mensal](https://ikiform.com/pt-br/docs/limits.md#monthly-usage).

## Os envios não aparecem

- Olhe no filtro de spam. Spam recebe uma resposta de sucesso normal, então o visitante não percebe.
- Confira se o formulário não está pausado e se o id no seu `action` corresponde ao do painel.
- Um envio pelo navegador que mostra a página de erro do Ikiform foi rejeitado; a página mostra o motivo.

## Os webhooks falham

- `no_matching_signature`: verifique contra o corpo bruto, antes de qualquer parse de JSON, e confira se você copiou o segredo `whsec_` certo. Cole uma entrega no [verificador](https://ikiform.com/pt-br/docs/webhooks.md#verifier).
- `timestamp_too_old`: o relógio do seu servidor está errado, ou você está repetindo uma entrega antiga.
- Timeouts: responda em até 15 segundos e faça o trabalho demorado depois.
- Redirecionamentos não são seguidos. Use a URL final, incluindo a barra no final que o seu framework espera.
- O endpoint foi desativado depois de 5 dias de falhas ou de um `410`. Corrija e depois reative-o na página do endpoint.
