Antes de integrar, saiba quais campos vêm preenchidos de verdade. Medimos 48 placas reais: três campos que todo mundo espera vêm nulos em 100% delas.
Quem vai integrar uma API de placa costuma perguntar o preço e o tempo de resposta. As duas perguntas certas são outras: quais campos vêm preenchidos de verdade e o que acontece quando a fonte cai.
Este texto responde as duas com número medido, inclusive onde o número é constrangedor para nós.
Uma consulta por placa devolve o registro do veículo: marca, modelo, ano de fabricação e modelo, cor, combustível, município e UF de emplacamento, chassi, situação, e os identificadores de registro.
O que quase ninguém avisa antes de você integrar é que parte dos campos documentados vem vazia na maioria das placas — e não por falha, mas porque o registro de origem não os preenche.
Não é amostra escolhida a dedo: são 48 placas tiradas do nosso cache de produção, distribuídas de 1970 a 2026 e cobrindo automóvel, moto, caminhão, caminhonete, camioneta, utilitário e micro-ônibus.
| campo | veio preenchido |
|---|---|
| Descrição do motor | 0 de 48 |
| Descrição da transmissão | 0 de 48 |
| Quantidade de portas | 0 de 48 |
| Versão | 3 de 48 (~6%) |
| Número do câmbio | 5 de 48 |
| Número do motor | 24 de 32 |
| Potência · tipo de carroceria | 31 de 32 |
| Cilindradas | 32 de 32 |
Os três primeiros nunca vieram. Em nenhuma placa, de nenhuma década. Eles existem no schema do fornecedor; a produção não os preenche.
E a versão — que é o campo que mais gente quer, porque é o que distingue um
1.0 de um 1.0 Turbo — aparece em 6% dos casos, sem regra que permita
prever quando. Testamos a hipótese de que dependia da marca e ela caiu:
Chevrolet 1 de 4, Fiat 2 de 4, Toyota 0 de 4, Volkswagen 0 de 4.
Se o seu produto depende de identificar a versão pela placa, não integre sem testar com as suas placas primeiro. A versão legível existe em outra rota, mais cara — é uma decisão de custo, não de integração.
Alguns campos voltam com o literal "Desconhecido" quando a fonte não sabe —
enquanto outros, no mesmo veículo, voltam null. É a mesma ausência em dois
formatos.
O estrago é sutil: um if (veiculo.tipo_carroceria) dá verdadeiro para
"não sei", e a sua tela exibe "Desconhecido" como se fosse a carroceria.
Na nossa saída isso é normalizado — o sentinela vira null antes de sair do
servidor. Se você integra outra fonte, teste esse caso explicitamente.
codigoFipe é escalar na consulta de placa e array na consulta técnica,
no mesmo fornecedor. Quem reaproveita o parser de uma rota na outra quebra — e
quebra em silêncio, porque array[0] de um escalar é undefined, não erro.
Mais de um código FIPE, aliás, é o normal: significa que a placa não distingue a versão sozinha. É ambiguidade a resolver com o usuário final, não retentativa.
Este é o mais importante, e vale contar inteiro porque custou seis dias.
Até 17/09/2026, qualquer resposta ruim do fornecedor virava 400 "A placa é inválida ou não foi encontrada". O gateway dele caiu por sete minutos de madrugada e as quatro placas de um cliente voltaram esse 400 — em 146 a 397 milissegundos, quando uma consulta real leva de 4 a 26 segundos e uma placa inexistente de verdade leva 12.
Ele concluiu, com método, que "a fonte não estava conectada". Estava certo. A nossa API é que dizia a coisa errada: culpava a placa por uma falha nossa.
Hoje o comportamento é outro, e é o que você deve esperar de qualquer API que leve integração a sério:
| situação | resposta |
|---|---|
| Placa não existe na base | 400 — é sobre a placa |
| Fornecedor fora, corpo não-JSON, 5xx, timeout | 503 com Retry-After — e não cobra |
| Rate limit do fornecedor | 503 — repita depois |
A regra para quem integra: trate 400 como "não insista, a placa está errada" e 503 como "repita em 30 segundos". Se a API que você usa devolve o mesmo código para os dois casos, você vai mandar o seu usuário conferir uma placa que está certa.
Estes são os pontos em que a nossa API não segue a convenção óbvia — e é exatamente onde um assistente de código completa errado com confiança:
400, não 422. O corpo vem como
{errors: {message, fields: []}}.data: null. É {error: true, message} e
mais nada.401, não 403.Depende do que você está perguntando, e a diferença não é técnica:
Servir situação de semanas atrás como atual é defeito de informação, não economia.
Vale dizer, mesmo vendendo o produto:
Uma API de placa é boa para identificar o veículo e conferir o registro. Ela não é boa para descobrir a versão comercial, e não substitui as bases de débito e restrição.
Antes de fechar integração com qualquer fornecedor, faça duas perguntas que raramente estão na documentação: quais campos vêm preenchidos nas MINHAS placas e o que a API responde quando a fonte de vocês cai. A segunda é a que aparece às três da manhã.
A nossa está em API de Consulta de Veículos, com o contrato completo e as armadilhas acima documentadas — inclusive as que já foram defeito nosso.