# Guia de instalação para agentes de IA: API Placa & FIPE

> Você é um assistente de programação (Claude Code, Cursor, Gemini CLI, Google Antigravity, Codex, Windsurf, Lovable, Bolt ou similar) e o usuário pediu para integrar a consulta de placa com valor FIPE no projeto dele. Siga este guia na ordem. Ele é a fonte oficial; não invente campos nem endpoints.

## Contexto em 5 linhas

- Serviço: **Placa & FIPE** (https://placaefipe.com.br), consulta de veículos brasileiros pela placa.
- Endpoint principal: `GET https://api.placaefipe.com.br/v1/placas/{placa}`
- Autenticação: cabeçalho `Authorization: Bearer <chave>`. A chave começa com `pf_live_`.
- Resposta: JSON com marca, modelo, versão, ano, cor, combustível, município, UF, situação, dados técnicos e `fipe` (valor do mês).
- Cobrança: 1 crédito por placa encontrada. Erros e placa não encontrada não cobram.

## Regras obrigatórias

1. **A chave nunca vai para o front-end**, app mobile, repositório ou log. Leia sempre de `process.env.PLACAEFIPE_API_KEY` (ou o equivalente da linguagem).
2. **Chame a API só no servidor**: rota de API, server action, edge function, backend. Se o projeto é só front-end, crie uma função de servidor (ex.: Supabase Edge Function, rota `/api` do Next.js, Cloudflare Worker).
3. **Teste com a chave de teste (`pf_test_...`)**: ela devolve um veículo de exemplo e não gasta crédito. Peça ao usuário uma chave de teste para o desenvolvimento e use a de produção (`pf_live_...`) só no deploy. Com a chave de produção, não faça chamadas em loop; para conferir a chave, use `GET /v1/saldo` (grátis).
4. **Todo campo pode ser `null`**, exceto `placa` e `consulta`. Trate isso na tela.
5. **Não prometa dados do proprietário** (nome, CPF, endereço). A API não retorna esses dados.

## Passo 1: identifique a stack

Leia `package.json`, `requirements.txt`, `composer.json`, `go.mod` ou equivalente e descubra:

- linguagem e framework (Next.js, Nuxt, SvelteKit, Express, NestJS, Laravel, Django, FastAPI, Rails, Flutter + backend…);
- onde ficam as rotas de servidor e as variáveis de ambiente;
- se já existe um cliente HTTP padrão (fetch, axios, requests, Guzzle).

## Passo 2: variável de ambiente

Adicione ao arquivo de exemplo de ambiente (`.env.example`, ou crie um) **sem valor real**:

```bash
PLACAEFIPE_API_KEY=
```

Garanta que `.env`, `.env.local` e afins estão no `.gitignore`. Diga ao usuário onde colocar a chave real (ver Passo 7).

## Passo 3: crie o cliente no servidor

Crie **um único módulo** com a função de consulta e reutilize. Modelo em TypeScript:

```ts
// lib/placaefipe.ts  (só servidor)
const BASE = 'https://api.placaefipe.com.br/v1';

export class ErroPlacaEFipe extends Error {
  constructor(public codigo: string, mensagem: string, public status: number) {
    super(mensagem);
  }
}

export async function consultarPlaca(placa: string) {
  const chave = process.env.PLACAEFIPE_API_KEY;
  if (!chave) throw new ErroPlacaEFipe('sem_chave', 'Configure PLACAEFIPE_API_KEY', 500);
  const limpa = placa.toUpperCase().replace(/[^A-Z0-9]/g, '');
  const r = await fetch(`${BASE}/placas/${limpa}`, {
    headers: { Authorization: `Bearer ${chave}` },
    cache: 'no-store',
  });
  const dados = await r.json();
  if (!r.ok) throw new ErroPlacaEFipe(dados.erro?.codigo ?? 'erro', dados.erro?.mensagem ?? 'Erro', r.status);
  return dados as VeiculoPlacaEFipe;
}

export interface VeiculoPlacaEFipe {
  placa: string;
  placa_antiga: string | null;
  marca: string | null;
  modelo: string | null;
  versao: string | null;
  ano_fabricacao: number | null;
  ano_modelo: number | null;
  cor: string | null;
  combustivel: string | null;
  chassi_final: string | null;
  municipio: string | null;
  uf: string | null;
  situacao: string | null;
  origem: string | null;
  tecnico: {
    motor: string | null;
    tipo: string | null;
    especie: string | null;
    segmento: string | null;
    cilindradas: number | null;
    passageiros: number | null;
    eixos: number | null;
  };
  fipe: {
    codigo: string | null;
    marca: string | null;
    modelo: string | null;
    ano_modelo: number | null;
    combustivel: string | null;
    valor: number | null;
    valor_texto: string | null;
    referencia: string | null;
    versoes: { codigo: string; modelo: string; valor: number | null; valor_texto: string | null }[];
  } | null;
  consulta: { id: string; creditos_restantes: number; cobrada: boolean; cache: boolean };
}
```

Em Python, PHP, Go, Supabase e n8n, use os modelos de https://placaefipe.com.br/docs/exemplos.md.

## Passo 4: exponha para a tela (se houver front-end)

Crie uma rota interna do próprio projeto (ex.: `GET /api/placa/[placa]`) que chama o módulo do Passo 3 e devolve o JSON. Proteja essa rota com a autenticação que o projeto já usa, para terceiros não gastarem os créditos do usuário. Se o projeto tem limite de requisições, aplique nela.

## Passo 5: tela

- Campo de placa com máscara que aceite os dois padrões: `AAA-9999` e `AAA9A99`. Converta para maiúsculas.
- Ao consultar: estado de carregamento, depois mostre marca, modelo, versão, ano, cor e FIPE.
- FIPE:
  - `fipe.valor` preenchido → mostre `fipe.valor_texto` e "FIPE de {fipe.referencia}".
  - `fipe.valor` nulo e `fipe.versoes` com itens → deixe o usuário escolher a versão; cada item tem `valor_texto`.
  - `fipe` nulo → "FIPE não encontrada para este veículo".
- Se o projeto salva veículos (oficina, loja, seguro, frota), preencha o formulário com os dados retornados em vez de só exibir.

## Passo 6: erros

Use `erro.codigo` (nunca o texto da mensagem):

| HTTP | `erro.codigo` | Mensagem para o usuário final |
|---|---|---|
| 400 | `placa_invalida` | "Placa inválida. Confira e tente de novo." |
| 401 | `nao_autenticado`, `chave_invalida` | Erro de configuração: avise o administrador (não mostre detalhes da chave). |
| 402 | `sem_creditos` | "Consulta indisponível no momento." e registre um alerta para o administrador comprar créditos. |
| 404 | `placa_nao_encontrada` | "Veículo não encontrado para esta placa." |
| 429 | `limite_excedido` | Espere 1 s e repita uma vez. |
| 503 | `indisponivel` | Repita até 3 vezes com espera de 1 s, 2 s e 4 s. |

## Passo 7: teste e entrega

1. Peça ao usuário a chave (ou que ele a coloque em `.env.local`). Se ele não tem conta: https://placaefipe.com.br/criar-conta (10 consultas grátis).
2. Teste a chave sem gastar crédito: `curl https://api.placaefipe.com.br/v1/saldo -H "Authorization: Bearer $PLACAEFIPE_API_KEY"`.
3. Faça **uma** consulta real com uma placa que o usuário indicar.
4. Rode o lint, o build e os testes do projeto.
5. Responda ao usuário com: arquivos criados ou alterados, onde configurar `PLACAEFIPE_API_KEY` em produção (Vercel, Netlify, Supabase, Railway…), e como testar.

## Opcional: servidor MCP

Se o usuário quiser consultar placas na própria conversa com a IA, configure o MCP remoto `https://api.placaefipe.com.br/mcp` com o cabeçalho `Authorization: Bearer <chave>`. Comandos e arquivos de cada ferramenta: https://placaefipe.com.br/docs/mcp.md

## Referências

- Documentação completa em texto: https://placaefipe.com.br/llms-full.txt
- OpenAPI 3.1: https://placaefipe.com.br/openapi.json
- Campos da resposta: https://placaefipe.com.br/docs/consultar-placa.md
- FIPE e versões: https://placaefipe.com.br/docs/fipe.md
- Erros: https://placaefipe.com.br/docs/erros.md
