> ## Documentation Index
> Fetch the complete documentation index at: https://dev.igps.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Handling iGps API Errors: 400, 401, 429, and 500 Codes

> Learn how iGps signals errors through HTTP status codes and how to handle authentication failures, validation errors, and rate limits in your integration.

A iGps usa códigos de status HTTP padrão para indicar sucesso ou falha. Entender esses códigos permite construir integrações resilientes que tratam erros de forma elegante.

## Códigos de Status HTTP

| Código | Nome                  | Quando Ocorre                                                                                             |
| ------ | --------------------- | --------------------------------------------------------------------------------------------------------- |
| `200`  | OK                    | Requisição bem-sucedida. Verifique os campos `status` por veículo na resposta.                            |
| `400`  | Bad Request           | O corpo da requisição é inválido (por exemplo, campos obrigatórios ausentes, formato de chassi inválido). |
| `401`  | Unauthorized          | O token de acesso está ausente, é inválido ou expirou.                                                    |
| `429`  | Too Many Requests     | Limite de requisições excedido. Reduza a frequência das requisições e tente novamente.                    |
| `500`  | Internal Server Error | Erro no lado do servidor. Tente novamente com backoff exponencial.                                        |

## Tratando 401 Unauthorized

Uma resposta `401` significa que o token Bearer fornecido está ausente, malformado ou expirou. Os tokens emitidos por `POST /api/v1/auth/token` são válidos por **1 hora**. Quando um `401` ocorre, sua aplicação deve obter um novo token e reenviar a requisição original.

```python theme={null}
import requests

def get_token(client_id, client_secret):
    resp = requests.post(
        "https://api.igps.com.br/api/v1/auth/token",
        json={"client_id": client_id, "client_secret": client_secret}
    )
    resp.raise_for_status()
    return resp.json()["access_token"]

token = get_token(client_id, client_secret)

response = requests.post(
    "https://api.igps.com.br/api/v1/veiculos/posicoes",
    headers={"Authorization": f"Bearer {token}"},
    json={"chassis": chassis_list}
)
if response.status_code == 401:
    token = get_token(client_id, client_secret)  # Renovar token expirado
    response = requests.post(
        "https://api.igps.com.br/api/v1/veiculos/posicoes",
        headers={"Authorization": f"Bearer {token}"},
        json={"chassis": chassis_list}
    )
```

Para evitar erros `401` de forma proativa, acompanhe o horário de emissão do token e renove-o antes que expire, em vez de esperar que a API o rejeite.

## Tratando 429 Too Many Requests

Uma resposta `429` significa que sua aplicação excedeu o limite de requisições da API. A estratégia recomendada é o **backoff exponencial**: aguardar progressivamente mais tempo entre tentativas para reduzir a pressão sobre a API e aumentar a probabilidade de uma resposta bem-sucedida.

```python theme={null}
import time

def query_with_retry(chassis_list, token, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(
            "https://api.igps.com.br/api/v1/veiculos/posicoes",
            headers={"Authorization": f"Bearer {token}"},
            json={"chassis": chassis_list}
        )
        if response.status_code == 429:
            time.sleep(2 ** attempt)
            continue
        return response
    raise Exception("Numero maximo de tentativas excedido")
```

No exemplo acima, os tempos de espera entre as tentativas são de 1 s, 2 s e 4 s, respectivamente. Ajuste `max_retries` e a base do backoff para atender aos requisitos de latência da sua aplicação.

## Erros no Nível do Veículo

É importante distinguir entre **erros no nível HTTP** e **erros no nível do veículo**:

* **Erros HTTP** (4xx / 5xx) indicam que a requisição inteira falhou. Nenhum dado de posição é retornado.
* **`nao_encontrado` no nível do veículo** é retornado dentro de uma resposta **`200 OK`**. A requisição em si foi bem-sucedida, mas um ou mais veículos individuais não puderam ser encontrados.

Portanto, uma resposta `200` ainda pode conter veículos que não foram encontrados. Sempre itere sobre o array `resultados` e verifique o campo `status` para cada veículo antes de tentar ler seus campos `latitude`, `longitude` ou `timestamp`.

Para mais detalhes sobre o status `nao_encontrado`, consulte [Posições de Veículos](/concepts/vehicle-positions).

<Warning>
  Não tente novamente em erros `400`. Estes indicam um problema no corpo da sua requisição que deve ser corrigido antes de tentar novamente.
</Warning>
