# Tratamento de Erros

> Como a API FiscalAPI reporta erros e como lidar com eles.

URL: https://docs.fiscalapi.com.br/docs/referencia/error-handling


A FiscalAPI segue o formato [RFC 7807 Problem Detail](https://datatracker.ietf.org/doc/html/rfc7807) para todas as respostas de erro. Isso garante uma estrutura consistente e previsível para tratamento de erros em qualquer linguagem.

## ## Formato da resposta de erro

```json
{
  "type": "urn:fiscalapi:error:parametro_ausente",
  "title": "PARAMETRO_AUSENTE",
  "status": 400,
  "detail": "Informe pelo menos um parametro: cpf, cnpj ou ie",
  "instance": "https://api.fiscalapi.com.br/api/consultar",
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-03-20T10:30:00Z"
}
```

## ## Campos do erro

| Campo        | Tipo    | Descrição                           |
| ------------ | ------- | ----------------------------------- |
| `type`       | string  | URI identificador do tipo de erro   |
| `title`      | string  | Código do erro                      |
| `status`     | integer | HTTP status code                    |
| `detail`     | string  | Descrição legível do erro           |
| `instance`   | string  | URL da requisição que causou o erro |
| `request_id` | string  | ID único da requisição              |
| `timestamp`  | string  | Data/hora do erro em ISO 8601       |

## ## Erros do Cliente (4xx)

| Código                  | Status | Descrição                                                                                                                                                                                                                                                                                                         |
| ----------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PARAMETRO_AUSENTE`     | 400    | Parâmetro obrigatório não informado                                                                                                                                                                                                                                                                               |
| `PARAMETRO_CONFLITANTE` | 400    | Mais de um documento informado (envie apenas um)                                                                                                                                                                                                                                                                  |
| `DOCUMENTO_INVALIDO`    | 400    | CPF, CNPJ ou IE com formato inválido                                                                                                                                                                                                                                                                              |
| `UF_NAO_SUPORTADA`      | 400    | Estado não suportado para este endpoint                                                                                                                                                                                                                                                                           |
| `API_KEY_ERROR`         | 403    | API Key ausente, inválida ou revogada. Chave revogada no Dashboard (ou substituída ao regenerar a principal) e chave de conta desativada respondem com `detail` `API key revoked`; revogar uma chave não afeta as outras da conta. Veja [Autenticação](/docs/getting-started/authentication#erro-de-autenticação) |
| `ACESSO_NEGADO`         | 403    | A chave é válida, mas não tem acesso a este endpoint (chave demo só consulta `/api/consultar`)                                                                                                                                                                                                                    |
| `RATE_LIMIT_EXCEEDED`   | 429    | Limite de requisições excedido                                                                                                                                                                                                                                                                                    |

## ## Erros do Servidor (5xx)

| Código                  | Status | Descrição                                                                                                                                 |
| ----------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `ERRO_INTERNO`          | 500    | Erro interno do servidor                                                                                                                  |
| `PROCESSAMENTO_FALHOU`  | 502    | Falha ao processar a consulta no estado. Até outubro de 2026 um código legado também era devolvido neste caso; trate pelo status HTTP 502 |
| `TODAS_FONTES_FALHARAM` | 502    | Todas as fontes de dados falharam                                                                                                         |
| `SITE_INDISPONIVEL`     | 503    | Portal da SEFAZ temporariamente indisponível                                                                                              |

## ## Boas práticas

* **Sempre verifique o status code** antes de processar o corpo da resposta
* **Use o `request_id`** ao entrar em contato com o suporte ([contato@fiscalapi.com.br](mailto:contato@fiscalapi.com.br)) para agilizar a investigação
* **Para erros 429**, respeite o header `Retry-After` antes de reenviar a requisição
* **Para erros 502/503**, implemente retry com backoff exponencial — a SEFAZ pode estar temporariamente fora do ar
* **Para erros 400**, corrija os parâmetros da requisição antes de reenviar
* **Para `403` com `API key revoked`**, não repita a requisição: a chave foi revogada ou a conta está desativada. Confira em **Chave API** no Dashboard e troque pela chave ativa do sistema; se a conta estiver desativada, fale com o suporte ([contato@fiscalapi.com.br](mailto:contato@fiscalapi.com.br))

## ## Exemplo de tratamento de erros

<Tabs items="[&#x22;JavaScript&#x22;, &#x22;Python&#x22;, &#x22;PHP&#x22;]">
  <Tab value="JavaScript">
    ```javascript
    const response = await fetch(url, {
      headers: { "X-API-Key": "fapi_sua_chave_aqui" },
    });

    if (!response.ok) {
      const error = await response.json();
      console.error(`[${error.title}] ${error.detail}`);

      switch (error.status) {
        case 400:
          // Corrija os parametros da requisicao
          throw new Error(`Parametro invalido: ${error.detail}`);
        case 403:
          if (error.title === "ACESSO_NEGADO") {
            // Chave valida sem acesso a este endpoint (ex.: chave demo)
            throw new Error(`Acesso negado: ${error.detail}`);
          }
          // API_KEY_ERROR: chave ausente, invalida ou revogada
          throw new Error("Credenciais invalidas");
        case 429:
          // Limite excedido — aguarde e tente novamente
          const retryAfter = response.headers.get("Retry-After");
          await new Promise((r) => setTimeout(r, retryAfter * 1000));
          // Reenviar requisicao...
          break;
        case 502:
        case 503:
          // Fonte indisponivel — retry com backoff exponencial
          break;
        default:
          throw new Error(`Erro inesperado: ${error.detail}`);
      }
    }

    const data = await response.json();
    ```
  </Tab>

  <Tab value="Python">
    ```python
    import requests
    import time

    response = requests.get(url, headers={"X-API-Key": "fapi_sua_chave_aqui"})

    if not response.ok:
        error = response.json()
        print(f"[{error['title']}] {error['detail']}")

        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 60))
            time.sleep(retry_after)
            # Reenviar requisicao...
        elif response.status_code in (502, 503):
            # Retry com backoff exponencial
            pass
        elif response.status_code == 400:
            raise ValueError(f"Parametro invalido: {error['detail']}")
        elif response.status_code == 403:
            if error["title"] == "ACESSO_NEGADO":
                # Chave valida sem acesso a este endpoint (ex.: chave demo)
                raise PermissionError(f"Acesso negado: {error['detail']}")
            # API_KEY_ERROR: chave ausente, invalida ou revogada
            raise PermissionError("API Key invalida")

    data = response.json()
    ```
  </Tab>

  <Tab value="PHP">
    ```php
    $response = Http::withHeaders([
        'X-API-Key' => 'fapi_sua_chave_aqui',
    ])->get($url);

    if ($response->failed()) {
        $error = $response->json();
        Log::error("[{$error['title']}] {$error['detail']}");

        if ($response->status() === 429) {
            $retryAfter = $response->header('Retry-After') ?? 60;
            sleep((int) $retryAfter);
            // Reenviar requisicao...
        }
    }

    $data = $response->json();
    ```
  </Tab>
</Tabs>

<Callout type="info">
  Sempre inclua o `request_id` ao reportar problemas ao suporte ([contato@fiscalapi.com.br](mailto:contato@fiscalapi.com.br)). Isso permite localizar sua requisição nos logs do servidor imediatamente.
</Callout>
