# Erros

> Todos os códigos de erro que o Ikiform retorna, com status HTTP, causa e correção.

Os envios de formulário e a API REST compartilham o mesmo envelope de erro. Requisições JSON o recebem com o status HTTP correspondente; envios de formulário pelo navegador recebem uma página de erro hospedada com a mesma mensagem e o mesmo status.

## O envelope de erro

`Erro`:

```json
{
  "ok": false,
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Please slow down."
  },
  "request_id": "req_01k7v2c9t3e8m5q4x6z0a1b2c3"
}
```

- `error.code` é estável; use-o nas suas condições. `error.message` é um texto em inglês simples para pessoas e pode mudar.
- `error.fields` aparece em erros de validação, indexado pelo id do campo, cada um com uma lista de mensagens. Erros sobre o corpo inteiro usam a chave `_form`.
- `error.challenge_url` aparece em `challenge_required`.
- `request_id` corresponde ao header `X-Request-Id` que toda resposta traz.
- Respostas com limite de taxa atingido trazem `Retry-After` em segundos. Os dois headers podem ser lidos pelo código no navegador.

## Códigos

| Status | Código | Onde |
| --- | --- | --- |
| 400 | [`invalid_body`](#invalid-body) | Envio |
| 400 | [`invalid_request`](#invalid-request) | API |
| 401 | [`unauthorized`](#unauthorized) | API |
| 402 | [`plan_required`](#plan-required) | Envio |
| 403 | [`forbidden`](#forbidden) | Ambos |
| 403 | [`origin_not_allowed`](#origin-not-allowed) | Envio |
| 403 | [`form_paused`](#form-paused) | Envio |
| 403 | [`captcha_failed`](#captcha-failed) | Envio |
| 403 | [`challenge_required`](#challenge-required) | Envio |
| 404 | [`not_found`](#not-found) | Ambos |
| 405 | [`method_not_allowed`](#method-not-allowed) | API |
| 409 | [`idempotency_in_progress`](#idempotency-in-progress) | Envio |
| 413 | [`payload_too_large`](#payload-too-large) | Envio |
| 415 | [`unsupported_media_type`](#unsupported-media-type) | Envio |
| 415 | [`unsupported_charset`](#unsupported-charset) | Envio |
| 422 | [`validation_failed`](#validation-failed) | Envio |
| 422 | [`files_not_supported`](#files-not-supported) | Envio |
| 422 | [`too_deep`](#too-deep) | Envio |
| 422 | [`idempotency_mismatch`](#idempotency-mismatch) | Envio |
| 429 | [`rate_limited`](#rate-limited) | Ambos |
| 429 | [`quota_exceeded`](#quota-exceeded) | Envio |
| 500 | [`server_error`](#server-error) | Ambos |

### 400 invalid_body

|   |   |
| --- | --- |
| Mensagem | `The request body could not be read.` |
| Causa | JSON ou multipart malformado, um array ou string JSON em vez de um objeto, ou uma chave de idempotência com mais de 255 caracteres. |
| Correção | Envie um único objeto JSON, ou deixe o navegador ou o `FormData` montar o corpo. |

### 400 invalid_request

|   |   |
| --- | --- |
| Mensagem | `The request is invalid.` |
| Causa | `limit`, `status`, `form_id` ou `cursor` é inválido. A mensagem indica o parâmetro. |
| Correção | Use `limit` de 1 a 100, `status` `received` ou `spam`, um id `frm_` real e cursores exatamente como foram retornados. |

### 401 unauthorized

|   |   |
| --- | --- |
| Mensagem | `A valid API key is required.` |
| Causa | Sem header `Authorization`, não é um token Bearer, ou a chave é desconhecida, revogada ou expirada. |
| Correção | Envie `Authorization: Bearer ik_sk_...` com uma chave secreta válida. |

### 402 plan_required

|   |   |
| --- | --- |
| Mensagem | `This form isn't accepting submissions right now.` |
| Causa | O workspace não tem plano ativo. Isso só pode acontecer depois que a cobrança for ativada. |
| Correção | Escolha um plano no painel em **Settings**. |

### 403 forbidden

|   |   |
| --- | --- |
| Mensagem | `You do not have access to this resource.` |
| Causa | A chave de API está malformada, pertence a outro workspace, é publicável na API REST ou não tem o escopo necessário. |
| Correção | Use uma chave secreta deste workspace com o escopo indicado na mensagem. |

### 403 origin_not_allowed

|   |   |
| --- | --- |
| Mensagem | `This form does not accept submissions from this site.` |
| Causa | O envio veio de um site fora dos domínios permitidos do formulário e o formulário rejeita divergências, ou uma chave publicável foi usada a partir de um domínio que não está listado na chave. |
| Correção | Adicione o site em **Allowed domains** ou aos domínios da chave. Para envios de servidor, use uma chave secreta. |

### 403 form_paused

|   |   |
| --- | --- |
| Mensagem | `This form is not accepting submissions right now.` |
| Causa | O formulário está pausado no painel. |
| Correção | Retome o formulário. |

### 403 captcha_failed

|   |   |
| --- | --- |
| Mensagem | `The captcha check failed. Please try again.` |
| Causa | O token do Turnstile está ausente, expirou, já foi usado ou não passou na verificação. |
| Correção | Obtenha um token novo a cada envio. Com suas próprias chaves, confira se a site key corresponde ao segredo. |

### 403 challenge_required

|   |   |
| --- | --- |
| Mensagem | `Complete the human check, then send the form again.` |
| Causa | O formulário usa a verificação humana do Ikiform e um envio JSON chegou sem token. |
| Correção | Chame `challenge(formId)` do SDK e passe o token, ou use `error.challenge_url`. Envios de servidor podem enviar uma chave secreta no lugar. |

### 404 not_found

|   |   |
| --- | --- |
| Mensagem | `Not found.` |
| Causa | O formulário não existe, foi excluído ou desativado, ou o id ou a rota estão errados. Também é retornado em um `GET` para `/f/<formId>`. |
| Correção | Copie o endpoint da visão geral do formulário e envie para ele em vez de abri-lo em uma aba. |

### 405 method_not_allowed

|   |   |
| --- | --- |
| Mensagem | `This method is not allowed here.` |
| Causa | Um preflight do navegador na API REST, que é só de servidor para servidor. |
| Correção | Chame `/api/v1` a partir do seu backend. |

### 409 idempotency_in_progress

|   |   |
| --- | --- |
| Mensagem | `A request with this idempotency key is still being processed.` |
| Causa | Uma requisição com esta chave de idempotência ainda está sendo processada. |
| Correção | Espere um momento e tente de novo com a mesma chave; você vai receber a primeira resposta. |

### 413 payload_too_large

|   |   |
| --- | --- |
| Mensagem | `The submission is too large.` |
| Causa | O corpo, um nome de campo, um valor ou o número de campos passou do limite. A mensagem diz qual. |
| Correção | Veja [Limites](https://ikiform.com/pt-br/docs/limits.md#submissions). Divida textos grandes em vários campos ou guarde arquivos em outro lugar e envie um link. |

### 415 unsupported_media_type

|   |   |
| --- | --- |
| Mensagem | `Send the form as urlencoded, multipart or JSON.` |
| Causa | O `Content-Type` não é urlencoded, multipart nem JSON, ou está ausente. |
| Correção | Defina `Content-Type: application/json` ao enviar JSON. |

### 415 unsupported_charset

|   |   |
| --- | --- |
| Mensagem | `Only UTF-8 is supported.` |
| Causa | O corpo não é UTF-8, ou declara outro charset. |
| Correção | Codifique em UTF-8. Adicione `accept-charset="utf-8"` a formulários HTML antigos. |

### 422 validation_failed

|   |   |
| --- | --- |
| Mensagem | `Some fields are invalid.` |
| Causa | Os campos falharam na validação. `error.fields` associa ids de campo a mensagens. |
| Correção | Mostre as mensagens ao lado dos campos. Veja [Campos](https://ikiform.com/pt-br/docs/fields.md#errors). |

### 422 files_not_supported

|   |   |
| --- | --- |
| Mensagem | `File uploads are not supported yet.` |
| Causa | O envio contém um arquivo. O upload de arquivos ainda não existe. |
| Correção | Remova os inputs de arquivo, ou faça upload dos arquivos em outro lugar e envie o link. |

### 422 too_deep

|   |   |
| --- | --- |
| Mensagem | `The JSON body is nested too deeply.` |
| Causa | O corpo JSON tem mais de 3 níveis de aninhamento, contando o objeto de topo. |
| Correção | Achate os dados, por exemplo `{ "address_city": "London" }`. |

### 422 idempotency_mismatch

|   |   |
| --- | --- |
| Mensagem | `This idempotency key was already used with a different payload.` |
| Causa | Esta chave de idempotência já foi usada neste formulário nas últimas 24 horas com campos diferentes. |
| Correção | Use uma chave nova para dados novos. Mantenha a mesma chave só para novas tentativas idênticas. |

### 429 rate_limited

|   |   |
| --- | --- |
| Mensagem | `Too many requests. Please slow down.` |
| Causa | Acima de um limite de taxa. `Retry-After` diz quantos segundos esperar. |
| Correção | Espere e tente de novo. Se visitantes reais atingirem o limite, mude o [limite de taxa](https://ikiform.com/pt-br/docs/rate-limits.md) do formulário. |

### 429 quota_exceeded

|   |   |
| --- | --- |
| Mensagem | `This form isn't accepting submissions right now.` |
| Causa | O workspace recebeu 2 vezes o seu limite mensal de envios neste mês. |
| Correção | Faça upgrade, ou espere o próximo mês. Veja [Uso mensal](https://ikiform.com/pt-br/docs/limits.md#monthly-usage). |

### 500 server_error

|   |   |
| --- | --- |
| Mensagem | `Something went wrong on our side.` |
| Causa | Algo falhou do lado do Ikiform. |
| Correção | Tente de novo com backoff e uma chave de idempotência. Se continuar acontecendo, informe o `request_id`. |

## O que não é erro

- Spam recebe o mesmo `201` ou redirecionamento de um envio real. Procure-o no filtro de spam do painel.
- Um `_redirect` não permitido é ignorado, e o navegador cai na página de agradecimento hospedada.
- Um `_replyto` que não seja um único endereço de e-mail válido é ignorado.

## Novas tentativas

- Tente de novo um `429` depois do `Retry-After`, e `500`, `409` ou erros de rede com backoff. Envie uma [chave de idempotência](https://ikiform.com/pt-br/docs/frameworks.md#idempotency) para que uma nova tentativa nunca crie um duplicado.
- Não repita outros erros `4xx` sem mudanças. Corrija a requisição primeiro.
