Documentação da API
Integre a consulta veicular ZapCar no seu sistema — do zero à primeira consulta. Autenticação por chave, cobrança por saldo, respostas em JSON e PDF.
Novidades da API
Últimas mudanças na API. A maioria é aditiva; o item marcado Atenção pode exigir ajuste de quem já integra.
11/09/2026
- Novo — a logo da sua empresa nos PDFs (white-label). Quem cadastra a logo no portal (Configurações › Personalização dos PDFs) passa a receber, no
GET /v1/consultas/:id/pdf, o relatório com a identidade da própria empresa. Vale paraconsulta,consulta-completa,gravame,renajude para os relatórios desenhados pela ZapCar (debitos,debitos-estadual,decodificacao-chassi,decodificacao-motor,score-credito). Quando o documento é o emitido pela base, a logo é aplicada na cópia servida, no topo da 1ª página, e o conteúdo é deslocado para baixo (nada é encolhido); o arquivo gravado não muda. Documentos oficiais (crlv, ATPV-e, código de segurança) seguem intactos. A logo é sempre a do dono da chave de API. Nada mudou no endpoint, nocontent-typenem no JSON dedados— mas se você extrai texto do PDF por posição, revise: a 1ª página ganha uma faixa no topo e a paginação pode mudar. Sem logo cadastrada, o PDF continua exatamente como era.
09/09/2026
- Consulta Simples — nova base estadual; o PDF passa a ser desenhado pela ZapCar no mesmo layout. O serviço
consultapassou a ser atendido por outra base estadual. Nenhum campo mudou de nome ou tipo no JSON dedados; o tri-estado (vazio significa não informado, nunca “nada consta”) e o bloconao_verificadocontinuam iguais. Duas mudanças aditivas:comunicacaodevendasvolta a vir preenchido (a base nova informa o comunicado de venda) eexerciciolicenciamentovolta a trazer o ano do último licenciamento;origem_de_emplacamentopassa a vir vazio. OGET /v1/consultas/:id/pdfcontinua entregando um documento no mesmo layout de antes (mesmas seções: dados da consulta, quadro de avisos, resumo, informações do veículo, multas e débitos, restrições, proprietário), agora gerado pela ZapCar a partir dos dados, porque a base nova não emite documento próprio. Itens que a base não respondeu saem como NÃO INFORMADO, não como “nada consta”. Se você usa o JSON (recomendado), nada a fazer. - Consulta Simples — nova versão da base estadual (V2). O serviço
consultapassou a ser atendido pela versão 2 da base estadual da mesma fonte (segunda troca de versão em dois dias; a anterior foi em 08/09). Nenhum campo mudou de nome ou tipo no JSON dedados; o tri-estado (vazio significa não informado, nunca “nada consta”) e o bloconao_verificadocontinuam iguais. Campos condicionais comoexerciciolicenciamento,origem_de_emplacamentoe os valores de débito seguem vindo quando a base os devolve. OGET /v1/consultas/:id/pdfcontinua entregando o documento emitido pela base; como a versão mudou, o layout e a paginação do arquivo podem variar de novo — se você extrai texto do PDF por posição, revise. Se você usa o JSON (recomendado), nada a fazer. Um eventual retorno à versão anterior é feito do nosso lado, sem mudança no contrato. - Janela de polling — Atenção. A base estadual que atende a Consulta Simples e a Consulta Completa passou a levar até ~2 minutos numa placa consultada pela primeira vez no dia (medido em produção em 09/09; a mesma placa, repetida, volta em segundos). Quem desiste em 60s, como o exemplo antigo desta página fazia, abandona uma consulta que vai concluir e que já foi debitada. Recomendação nova: intervalo de 3–5s e teto de 5 minutos — ou, melhor, o webhook
query.completed, que dispensa o polling.processandonunca é erro. Nada mudou no contrato da API: mesmos endpoints, mesmos campos. - Correção — falhas em série por “serviço indisponível”. Entre 08/09 (10:46) e 09/09 (09:30), consultas do serviço
consultafalharam comerro_codigo: CIRCUIT_OPENeretryable: truesem que a base fosse consultada — um defeito interno nosso na proteção contra fornecedor fora do ar, já corrigido. Todas foram estornadas automaticamente. Se você guardou essas placas como problemáticas, pode reprocessá-las.
08/09/2026
- Consulta Simples — trocou a versão da base estadual. O serviço
consultapassou a ser atendido por outra versão da base estadual da mesma fonte. Nenhum campo mudou de nome ou tipo no JSON dedados, e o tri-estado (vazio significa não informado, nunca “nada consta”) continua igual. Mudança aditiva:exerciciolicenciamentoeorigem_de_emplacamento, que vinham sempre vazios desde 28/08, voltam a vir preenchidos quando a base os devolve. OGET /v1/consultas/:id/pdfcontinua entregando o documento emitido pela base; como a versão da base mudou, o layout e a paginação do arquivo podem variar — se você extrai texto do PDF por posição, revise. Se você usa o JSON (recomendado), nada a fazer.
02/09/2026
- Novo —
erro_codigona consulta que falhou. OGET /v1/consultas/:idcomstatus: "erro"passa a trazer um código estável do motivo (PROVIDER_TIMEOUT,QUERY_NOT_FOUND,INVALID_PLATE…) e o campoerropassa a descrever o que aconteceu em vez da frase genérica. Oretryableagora deriva desse código. A lista completa está em Consultar o resultado. - Novo — proteção contra pedido duplicado. Se você enviar o mesmo serviço para o mesmo identificador (placa, chassi, motor ou documento) enquanto a solicitação anterior ainda está em processamento, o
POST /v1/consultasresponde200comreaproveitada: true, oidda consulta existente evalor_cobrado: 0— nada é cobrado de novo. Vale para retry de rede e para reenvio por engano. Continue usandoIdempotency-Keyquando puder: ela cobre também o caso em que a primeira consulta já terminou. - Comportamento — falha definitiva termina mais rápido. Quando a base responde “veículo não encontrado” ou o dado enviado é inválido, a consulta vai para
errona primeira tentativa, sem as retentativas internas que antes atrasavam o resultado em vários minutos. Falhas transitórias (base fora do ar, timeout) continuam sendo retentadas. - Comportamento — estorno automático. Toda consulta que termina em
erroé estornada automaticamente; um processo de reconciliação confirma o estorno mesmo se houver falha momentânea no momento do erro. O campoerroinforma quando o valor foi devolvido ao saldo. - Novo — FIPE dentro da Consulta Completa. Envie
"incluir_fipe": truenoPOST /v1/consultascomservico: "consulta-completa"e o resultado trazdados.fipe, no mesmo formato doPOST /v1/fipe— uma chamada só. O preço da FIPE é somado ao da Completa (vejaopcionais.incluir_fipe.preco_adicionalnoGET /v1/servicos). Se a FIPE não estiver disponível para a placa, a Completa é entregue normalmente,dados.fipevemnullcomdados.fipeErro, e só a parcela da FIPE é estornada.
29/08/2026
- Atenção — mudou o layout dos PDFs que a ZapCar desenha. Em
debitos,debitos-estadual,decodificacao-chassi,decodificacao-motorescore-credito, oGET /v1/consultas/:id/pdfpassou a entregar o arquivo no mesmo padrão visual dos documentos emitidos pelas bases — seções em faixa, grade “rótulo: valor” e quadro de avisos —, para que todos os PDFs da plataforma tenham a mesma cara. Nada mudou no endpoint, nocontent-type, no fluxo nem no JSON dedados: muda o layout e a paginação. Se você extrai texto do PDF por posição, recorta páginas ou espera um número fixo de folhas, revise. Se você usa o JSON (recomendado), nada a fazer. - Gravame e RENAJUD — o mesmo vale para o relatório de reserva. Esses dois entregam o documento da base desde 28/08; o relatório ZapCar que aparece quando a base não emite documento também passou para o novo padrão visual. Nenhuma mudança de campo.
- Score ZapCar — onde ele está. Lembrete, não mudança: o score de risco 0–100 da Consulta Completa vem no JSON (
risconoGET /v1/consultas/:id) e no painel. Ele não está no PDF desde que a Completa passou a entregar o documento da base — se você o exibe para o seu usuário, leia do JSON.
28/08/2026
- Atenção — o PDF mudou de documento. Em
consulta,consulta-completa,gravameerenajud, oGET /v1/consultas/:id/pdfpassou a entregar o documento emitido pela própria base consultada, e não mais o laudo desenhado pela ZapCar. O endpoint, ocontent-typee o fluxo são os mesmos — o que muda é o layout e a paginação do arquivo. Se você extrai texto do PDF por posição, recorta páginas ou espera um número fixo de folhas, revise. O JSON dedadosnão mudou por causa disso. - Atenção — serviço
historico-proprietariosdescontinuado. O slug saiu do catálogo e novas consultas são recusadas. O campohistorico_proprietariosnão é mais devolvido em consulta nenhuma, inclusive na Completa: nenhuma fonte do stack entrega a cadeia de donos anteriores. Todas devolvem apenas oproprietarioatual. A relação de donos consta na certidão de prontuário do DETRAN de emplacamento. - Gravame — mais de um registro por veículo.
dados.ocorrencias[]passa a trazer todos os registros de gravame do veículo, cada um com agente financeiro, documento, número do gravame, contrato e datas. Os campos de topo continuam descrevendo o registro principal, sem mudança de nome ou tipo — é aditivo. O documento oficial da base lista todos. - Gravame — novos campos do veículo.
marcamodelo,cor,municipio,combustivelemotorpassam a vir preenchidos quando a base os devolve. Antes não existiam nesse serviço. - RENAJUD — base sem resposta agora é ERRO, não “nada consta”. Quando a base de restrições judiciais não responde, a consulta falha (com estorno) em vez de devolver um veículo limpo. Se o seu código tratava resposta vazia como “sem bloqueio”, esse caso deixou de existir — passe a tratar o erro.
- Novo —
retryablena consulta que falhou. OGET /v1/consultas/:idcomstatus: "erro"passa a trazerretryable:truequando a base caiu e a mesma consulta tende a funcionar minutos depois,falsequando repetir só muda a fatura (placa inexistente, contrato, credencial). O campo é OMITIDO quando não classificamos — ausente significa “não sabemos”, e nãofalse. Trate os três casos. - Gravame —
codigofinanceiraagora vemnull, e o número do registro ganhou campo próprio. A base atual não devolve código de financeira — devolve o CNPJ dela, que já estava emdocumentofinanceira. O número do gravame no SNG, que antes ia empurrado paracodigofinanceirapor falta de lugar, passou a ter o camponumerogravame. Se você liacodigofinanceiraesperando o número do registro, migre paranumerogravame. - Atenção —
documentodo proprietário pode vir MASCARADO. Algumas bases devolvem o CPF/CNPJ do titular parcialmente ("***.490.411-**"). Antes nós removíamos a pontuação de tudo, e a máscara virava"490411"— seis dígitos que pareciam um documento e não eram. Agora a pontuação só sai quando restam 11 ou 14 dígitos; fora disso o valor volta como a base mandou. Valide o tamanho antes de usar:veiculo.proprietario.documentonem sempre é um documento completo, etipoDocumentovemnullquando não dá para afirmar. - Consulta Simples — o PDF também passou a ser o documento da base. Vale o mesmo aviso do item de cima sobre layout e paginação. Quando a base não emite documento, o relatório ZapCar continua sendo entregue — o endpoint responde igual nos dois casos.
- Consulta Simples — duas reduções de cobertura.
comunicacaodevendaspassou a vir vazio (a fonte atual não tem o campo; vazio significa não informado, nunca “nada consta”). Edatalicenciamentotraz a data limite do licenciamento, não mais o ano do exercício —exerciciolicenciamentovem vazio.
27/08/2026
- Atenção —
dados.debitosda Consulta Completa deixou de sair zerado. O bloco sempre devolvia0em todos os itens; agora traz os valores reais apurados na consulta, maisestadopor item (SEM_DEBITO,CONSTA,CONSTA_SEM_VALOR,NAO_INFORMADO) etotal_parcial. Se o seu código assumia zero — somando esse bloco a outro, ou pulando a seção de débitos —, revise.total_parcial: truesignifica que existe débito sem valor informado: ototalé um piso. Edebitos: nullé “não verificado”, não “não deve”. - Novo endpoint — imagens da Consulta Completa.
GET /v1/consultas/:id/imagens/:tipo/:indiceentrega as fotos de leilão, as imagens de vistoria/anúncio e o certificado do laudo CSV. Elas não viajam mais dentro do JSON (o retorno passava de 8 MB):fotosLeilaoagora é uma lista deindice+url. Detalhes em Imagens da Consulta Completa. - Novo bloco
dados.renainf. Infrações RENAINF cometidas fora da UF de emplacamento, com auto, enquadramento, órgão autuador, valor e situação de pagamento. Três estados:null= base não respondeu,total: 0= respondeu sem infração,total: N= há infrações. Não some RENAINF aos débitos estaduais — são universos diferentes, e a soma inventa um total que não existe. - Novo bloco
dados.csv— Certificado de Segurança Veicular. Sinal forte: o CSV é exigido depois de alteração ou reparo estrutural. O campoobservacaotraz a ressalva da fonte e deve ser repassada junto com o dado. A maior parte do conteúdo está dentro da imagem do certificado, emimagem_url. - Novos blocos
dados.blocosedados.offline— o terceiro estado, explícito.blocosdiz, base por base, se elarespondeue quantas ocorrências trouxe;offline: trueavisa que a resposta veio de cache da fonte, não da base viva. Use os dois antes de escrever “nada consta” para o seu cliente. - Novo bloco
dados.informacoesAvulsas. Pares descrição/valor do registro (status e vencimento do licenciamento, instituição alienadora, indicadores extrajudiciais). Vem a lista inteira, então campo novo aparece aqui em vez de sumir. restricoesganhourestricaoGeraleveiculoBaixado.restricaoGeralé um indicador amplo e não equivale a restrição administrativa — ele acende até por multa RENAINF. O texto real está emrestricao1..4. Tratar os dois como sinônimo inventa impedimento de transferência.- Reforço de tri-estado. Mais campos de
restricoespassam a devolvernullquando a fonte não verificou o item, em vez defalse.if (!restricoes.sinistro)trata “não verificado” como “sem sinistro” — teste os três estados. - O que a Completa não traz.
anoUltimoLicenciamentopode virnull, e o blocoleilao(lote, pátio, data, comitente) costuma virnull— as fotos continuam chegando emfotosLeilao. O campohistoricoProprietariosdeixou de existir em 28/08/2026: a cadeia de donos anteriores não é mais entregue por nenhuma consulta — as fontes atuais devolvem apenas o proprietário atual.
26/08/2026
- Consulta Completa — bloco
veiculomais completo. O bloco normalizado ganhouficha_pesados(eixos, capacidade de carga, peso bruto total, capacidade de tração e tanque — preenchido só em caminhão, ônibus e implemento) efaturamento(tipo_documento,documentoeufde quem recebeu o veículo 0km). Aditivo: nenhum campo existente mudou de nome ou de tipo. - Leilão agora tem três fontes.
veiculo.leilaoganhou o contadorfotos. A foto do veículo em pátio é prova positiva por si só: quandofotos > 0, o veículo passou por leilão mesmo comocorrencias: 0— isso significa apenas que a base de ocorrências não trouxe lote e comitente.leilao: nullcontinua sendo “nenhuma fonte verificou”. - Débito confirmado sem valor agora aparece. Quando a base do estado responde “existe débito, valor não informado”, o item entra em
veiculo.debitos[]comvalor_centavos: 0evalor_informado: false. Antes ele era descartado e a resposta parecia dizer “sem débito” sobre um carro devendo. Nunca somevalor_centavossem olharvalor_informado: o total é um piso, não o devido. - Atenção —
veiculo.sinistropode virnull. O provedor devolvenullnesse campo quando não verifica, e passamos a preservar isso em vez de converter parafalse. Se o seu código fazif (!veiculo.sinistro), ele passou a tratar “não verificado” como “sem sinistro”. Teste os três estados:true,falseenull. O mesmo vale pararecall. - CRLV — Mato Grosso do Sul (MS) agora atendido. A emissão do CRLV de MS entrou na API — exige só
placa+uf, sem CPF nem RENAVAM. O estado tinha preço cadastrado mas nenhum emissor; agora tem. Confirme o preço emGET /v1/servicos→crlv.preco_por_uf. - Novo serviço — 2ª via do ATPV-e. Emissão da Autorização para Transferência de Propriedade de Veículo eletrônica. Slug
atpve; exige só aplaca— semuf, semcpf, semrenavam. Entrega documento em PDF (não devolve JSON de dados). Cobertura nacional e preço único, diferente docrlv, que é por UF. - É emissão, não consulta. Leva cerca de 1 minuto. O status fica
processandonesse intervalo — amplie o polling ou use o webhookquery.completedem vez de desistir em 30s. - Consulta Completa — fotos de leilão. A Completa passa a trazer o bloco
dados.fotosLeilao: imagens do veículo em pátio de leilão, quando existirem, e também no PDF do laudo. É aditivo — nenhum campo existente mudou. Três estados, iguais aos do blocoleilao:null= a base de imagens não respondeu (não verificado),[]= respondeu e não há foto, lista = fotos encontradas.nulle[]significam coisas diferentes: ausência de foto não prova ausência de leilão.
06/08/2026
- Novo serviço — Score de Crédito. Análise de crédito e localização por
documento(CPF ou CNPJ, sem placa): dados da Receita Federal, score, renda presumida, e-mail/endereço presumidos e participação em empresas. Slugscore-credito; entrega JSON (dados) e PDF. - Novo serviço — Débitos Estaduais. Débitos do veículo direto na base do estado (IPVA, licenciamento, DPVAT, multas e dívida ativa). Slug
debitos-estadual; exigeplaca,uferenavam— e, em algumas UFs,documento(CPF/CNPJ) ouchassi(verdebitos-estadual.campos_por_ufemGET /v1/servicos). Não confundir comdebitos(código de barras, agregado).
12/08/2026
- CRLV — Pernambuco (PE) agora atendido. A emissão do CRLV de PE já está disponível na API — exige só
placa+uf. Confirme o preço e os campos emGET /v1/servicos→crlv.preco_por_uf.
04/08/2026
- Novo endpoint — Tabela FIPE por placa.
POST /v1/fipedevolve os valores FIPE do veículo na hora (endpoint síncrono: semid, sem polling, sem PDF). Custa R$ 0,25 por consulta, com estorno automático se falhar ou não houver FIPE. Detalhes em POST /v1/fipe.
31/07/2026
- Novos serviços — Decodificação de Chassi e de Motor. Decodificam um
chassiou número demotor(sem placa) em dados do veículo + sugestões da Tabela FIPE. Slugsdecodificacao-chassiedecodificacao-motor; entregam JSON (dados) e PDF. - CRLV — mais estados atendidos. Consulte sempre a lista viva em
GET /v1/servicos→crlv.preco_por_uf. - CRLV — 2ª via automática (melhoria transparente). Se a 1ª via falhar, tentamos um provedor alternativo automaticamente. Você não muda nada — só aumenta a taxa de sucesso.
- Catálogo mais preciso. O
requerde cada serviço emGET /v1/servicosagora reflete os campos certos (ex.:chassi/motornas decodificações e os campos por UF no CRLV).
cpf (CPF/CNPJ) e/ou renavam além de placa e uf. Hoje: CPF + RENAVAM em BA, PA, SP, TO, MT · só CPF/CNPJ em MG · só RENAVAM em PR, PI · só placa + uf em RJ e demais. Emitindo sem os campos exigidos, a resposta é 400 CRLV_DADOS_OBRIGATORIOS. Antes de emitir, leia o requer da UF em crlv.preco_por_uf.Introdução
A API ZapCar coloca a consulta veicular dentro do seu sistema. Você envia a placa (ou o chassi/motor na decodificação) e, quando o serviço pedir, a UF, o RENAVAM ou o CPF/CNPJ; nós consultamos as fontes oficiais e devolvemos o resultado em JSON e/ou PDF — o mesmo dado que aparece no painel.
É uma API REST comum: você faz chamadas HTTPS e recebe respostas em JSON (UTF-8). Não precisa instalar nada — qualquer linguagem que faça requisições HTTP (JavaScript, PHP, Python, etc.) já serve. O fuso das datas é America/São_Paulo.
Endpoints de relance
Primeiros passos
Do zero à primeira consulta em 4 passos. Se você só quer confirmar que está tudo certo, faça os passos 1 e 2.
Gere sua chave
zc_live_…. Ele aparece uma única vez — guarde num lugar seguro.Faça a primeira chamada (teste rápido)
200, sua chave é válida e a API está no ar.curl https://api.zapcarconsulta.com.br/v1/servicos \ -H "Authorization: Bearer zc_live_sua_chave_aqui"
Crie uma consulta
id e o status processando. Guarde esse id.curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{"servico":"consulta","placa":"ABC1D23"}'Veja o resultado
id até o status virar concluido — aí vêm os dados e a pdf_url.curl https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID \ -H "Authorization: Bearer zc_live_sua_chave_aqui"
Autenticação
Toda chamada precisa da sua chave no cabeçalho Authorization, no formato Bearer. (Também aceitamos o cabeçalho X-API-Key.)
Authorization: Bearer zc_live_sua_chave_aqui
X-API-Key: zc_live_sua_chave_aqui
Sem chave válida, a resposta é 401. Trate a chave como uma senha: guarde no servidor (variável de ambiente), nunca no navegador, em apps ou em repositórios. Se desconfiar que vazou, revogue e gere outra — leva segundos.
Como funciona — assíncrono em 2 passos
A consulta depende de fontes externas e leva de alguns segundos a alguns minutos. Por isso você não recebe o resultado na mesma resposta: primeiro cria a consulta, depois busca o resultado.
Crie a consulta
POST em /v1/consultas com o serviço e a placa. O saldo é debitado na hora e você recebe um id com status "processando".
Busque o resultado
GET em /v1/consultas/{id}, repetindo a cada poucos segundos até o status virar "concluido" (aí vêm os dados e o pdf_url) ou "erro".
⚠️ A diferença entre criar e consultar (erro mais comum)
São endpoints parecidos, mas o método e a URL mudam. Trocar isso é o motivo nº 1 de receber 404 Rota não encontrada:
| Você quer | Método | URL |
|---|---|---|
| Criar | POST | /v1/consultas (sem id) |
| Ver resultado | GET | /v1/consultas/{id} (com id) |
| Baixar PDF | GET | /v1/consultas/{id}/pdf |
POST /v1/consultas/{id} não existe → 404. Para ver um resultado use GET com o id; para criar use POST sem o id.Acompanhar o resultado (polling)
Depois de criar a consulta, você "pergunta" pela resposta de tempos em tempos até ela ficar pronta. Isso se chama polling. Uma boa regra: consultar a cada 3–5 segundos, com teto de 5 minutos. Menos que isso abandona consulta que vai concluir — e que já foi debitada.
Em dia normal a maioria conclui em segundos. A base estadual (Consulta Simples e Completa), porém, chega a ~2 minutos numa placa consultada pela primeira vez no dia — a mesma placa, repetida, volta em segundos. O status passa por:
| status | O que significa | O que fazer |
|---|---|---|
processando | Ainda buscando na base consultada. | Espere 3–5s e consulte de novo. Pode levar até ~2 min na base estadual. |
concluido | Pronto. Vêm "dados" (quando o serviço tem JSON) e "pdf_url". | Use os dados / baixe o PDF. |
erro | Não foi possível concluir. | O valor é estornado. Reenvie a consulta. |
pdf_url enquanto o status for processando — ele ainda não existe e a API responde 400 PDF_NOT_READY. Espere o concluido.CE, DF, ES, PB, RJ, RN, RS e SC é processada pelo DETRAN de forma assíncrona — pode levar de segundos a alguns minutos. Nesses casos o status fica processando por mais tempo: não trate isso como erro nem desista em 60s. Duas formas de acompanhar: (1) aumente a janela de polling; ou, melhor, (2) cadastre um webhook e reaja ao evento query.completed — aí você só chama GET /v1/consultas/:id quando o resultado já está pronto, sem polling longo. Se a emissão falhar, o valor é estornado e o status vira erro.Veja um exemplo de polling pronto na seção Exemplos em código.
Cobrança e saldo
Cada consulta desconta do saldo da sua carteira o valor vigente do catálogo da API (veja em GET /v1/servicos). Os valores da API seguem o catálogo de integrações (GET /v1/servicos) e podem diferir das condições disponíveis no Portal do Cliente. Exemplo: a Tabela FIPE é gratuita no painel e cobrada por requisição na API. O débito acontece no POST, antes do processamento.
Sem saldo suficiente, a criação falha com 402 SALDO_INSUFICIENTE e nada é cobrado. Se a consulta for criada mas falhar no provedor, o valor é estornado automaticamente — você não paga por erro.
Limites de uso
A API aceita por padrão até 120 requisições por minuto. Ao ultrapassar, as chamadas recebem 429 RATE_LIMITED — respeite o intervalo e reenvie. Precisa de mais volume? Fale com o suporte que ajustamos.
Listar serviços e preços
Retorna o catálogo de serviços com o preço vigente de cada um. Para o CRLV, o preço vem por UF. É a chamada mais simples — use-a para testar sua chave.
{
"servicos": [
{ "servico": "consulta", "nome": "Consulta Simples", "requer": ["placa"], "preco": 5.99 },
{ "servico": "consulta-completa", "nome": "Consulta Completa", "requer": ["placa"], "preco": 38.99,
"opcionais": { "incluir_fipe": { "preco_adicional": 0.25, "descricao": "Embute a Tabela FIPE da placa em dados.fipe." } } },
{ "servico": "gravame", "nome": "Gravame", "requer": ["placa"], "preco": 6.99 },
{ "servico": "renajud", "nome": "Renajud", "requer": ["placa"], "preco": 6.99 },
{ "servico": "debitos", "nome": "Débitos + Código de Barras", "requer": ["placa"], "preco": 19.99 },
{ "servico": "debitos-estadual", "nome": "Débitos Estaduais", "requer": ["placa","uf"], "preco": 2.99,
"observacao": "Serviço por estado. Os campos exigidos variam por UF — ver campos_por_uf.", "campos_por_uf": [ "..." ] },
{ "servico": "decodificacao-chassi", "nome": "Decodificação de Chassi", "requer": ["chassi"], "preco": 2.99 },
{ "servico": "decodificacao-motor", "nome": "Decodificação de Motor", "requer": ["motor"], "preco": 2.99 },
{ "servico": "score-credito", "nome": "Score de Crédito", "requer": ["documento"], "preco": 12.99 },
{ "servico": "fipe", "nome": "Tabela FIPE", "requer": ["placa"], "preco": 0.25,
"sincrono": true, "endpoint": "POST /v1/fipe",
"observacao": "Retorna os valores FIPE do veículo na hora (sem PDF, sem polling)." },
{ "servico": "codigo-seguranca", "nome": "Código de Segurança", "requer": ["placa","renavam"], "preco": 19.99 },
{ "servico": "atpve", "nome": "2ª via do ATPV-e", "requer": ["placa"], "preco": 39.99 },
{ "servico": "crlv", "nome": "CRLV Digital", "requer": ["placa","uf"],
"observacao": "Alguns estados exigem CPF/CNPJ e/ou RENAVAM — ver \"requer\" de cada UF.",
"preco_por_uf": [
{ "uf": "AP", "preco": 29.99, "requer": ["placa","uf"] },
{ "uf": "BA", "preco": 29.99, "requer": ["placa","uf","cpf","renavam"] },
{ "uf": "CE", "preco": 44.99, "requer": ["placa","uf"] },
{ "uf": "GO", "preco": 29.99, "requer": ["placa","uf"] }
] }
],
"desconto_api": null
}GET /v1/servicos com a sua chave — preços personalizados e o Grupo de Desconto da API alteram o valor cobrado.Consultar saldo
Retorna o saldo atual da sua carteira, em reais. Útil para monitorar e recarregar antes de acabar.
{ "saldo": 465.01 }Criar uma consulta
Cria a consulta, debita o saldo e devolve o identificador para você acompanhar. O corpo (body) vai em JSON:
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
servico | string | Sim | Slug do serviço (ver Catálogo). Ex.: "consulta", "gravame", "crlv". |
placa | string | Depende | Placa (com ou sem hífen). Ex.: "ABC1D23". Obrigatória em todos, exceto decodificação de chassi/motor. |
chassi | string | Depende | Obrigatório só em "decodificacao-chassi". |
motor | string | Depende | Obrigatório só em "decodificacao-motor". |
uf | string | Depende | UF de 2 letras. Obrigatória no "crlv". |
renavam | string | Depende | RENAVAM. Obrigatório no "codigo-seguranca" e em CRLV de algumas UFs. |
cpf | string | Depende | CPF/CNPJ do proprietário. Obrigatório no CRLV de algumas UFs (ver Catálogo). |
incluir_fipe | boolean | Não | Só em "consulta-completa": embute a Tabela FIPE da placa em dados.fipe (mesmo resultado do POST /v1/fipe). Cobra o preço da FIPE junto; se a FIPE falhar, só essa parcela é estornada e dados.fipe vem null com dados.fipeErro. |
curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "consulta", "placa": "ABC1D23" }'{
"id": "6f1c2e2a-1b3d-4a9e-8f7c-2a1b3c4d5e6f",
"servico": "consulta",
"status": "processando",
"valor_cobrado": 5.99,
"saldo_restante": 465.01,
"resultado_url": "/v1/consultas/6f1c2e2a-..."
}{ "erro": "Saldo insuficiente", "codigo": "SALDO_INSUFICIENTE", "saldo": 12.50 }{
"id": "6f1c2e2a-1b3d-4a9e-8f7c-2a1b3c4d5e6f",
"servico": "consulta",
"status": "processando",
"valor_cobrado": 0,
"saldo_restante": 465.01,
"resultado_url": "/v1/consultas/6f1c2e2a-...",
"reaproveitada": true,
"mensagem": "Essa solicitação já está sendo processada. Você não precisa realizar uma nova."
}reaproveitada: true — trate como sucesso e acompanhe o id retornado. Depois que a anterior termina, um novo POST cria (e cobra) uma consulta nova.Consultar o resultado
Devolve o estado atual da consulta. Use o id que veio no passo anterior. Enquanto processa, o status é processando; quando conclui, inclui os dados (para os serviços com JSON) e a pdf_url.
{
"id": "6f1c2e2a-...",
"servico": "consulta",
"placa": "ABC1D23",
"status": "concluido",
"valor_cobrado": 5.99,
"criado_em": "2026-07-23T09:14:02-03:00",
"dados": { "dados_do_veiculo": { "...": "..." }, "restricoes_e_impedimentos": { "...": "..." } },
"proprietario": { "nome": "JOAO DA SILVA", "documento": "12345678901" },
"ultimo_licenciamento": 2024,
"nao_verificado": ["restricao_judicial", "restricao_administrativa"],
"pdf_url": "/v1/consultas/6f1c2e2a-.../pdf"
}{
"veiculo": {
"placa": "ABC1D23", "renavam": "12345678901", "chassi": "9BWZZZ377VT004251",
"marca": "VW", "modelo": "POLO SENSE", "ano_fabricacao": 2019, "ano_modelo": 2020,
"cor": "BRANCA", "combustivel": "FLEX", "especie": "PASSAGEIRO", "categoria": "PARTICULAR",
"municipio": "SALVADOR", "uf": "BA",
"proprietario": { "nome": "JOAO DA SILVA", "documento": "12345678901" },
"situacao": "EM CIRCULACAO", "baixado": false,
"recall": false,
"sinistro": true,
"leilao": { "consta": true, "ocorrencias": 0, "fotos": 6 },
"restricoes": [
{ "tipo": "FINANCEIRA", "ativa": false, "descricao": null },
{ "tipo": "RENAJUD", "ativa": false, "descricao": null }
],
"debitos": [
{ "tipo": "MULTA", "descricao": "Multas", "valor_centavos": 97617, "valor_informado": true },
{ "tipo": "IPVA", "descricao": "IPVA", "valor_centavos": 0, "valor_informado": false }
],
"debitos_total_centavos": 97617,
"ficha_pesados": {
"eixos": null, "capacidade_carga_kg": null, "peso_bruto_total_kg": null,
"capacidade_maxima_tracao_kg": null, "capacidade_tanque_litros": null
},
"faturamento": { "tipo_documento": "CNPJ", "documento": "59104422002446", "uf": "SP" },
"ultimo_licenciamento": 2024
}
}null, false e ausência como coisas diferentes. sinistro e recall vêm nullquando a fonte não verificou o item — não é “sem sinistro”. leilao: null significa que nenhuma das três fontes respondeu; já leilao.fotos > 0 confirma a passagem por leilão mesmo com ocorrencias: 0. E em debitos[], um item com valor_informado: false é um débito REAL de valor desconhecido: debitos_total_centavos é o mínimo devido, não o total.{ "id": "6f1c2e2a-...", "status": "processando", ... }{
"id": "6f1c2e2a-...",
"servico": "gravame",
"placa": "ABC1D23",
"status": "erro",
"erro": "A base consultada está temporariamente indisponível. Isso costuma se resolver em alguns minutos — tente novamente. O valor foi devolvido ao seu saldo.",
"erro_codigo": "PROVIDER_UNAVAILABLE",
"retryable": true
}erro_codigo diz por que a consulta falhou; retryable diz se vale repetir. Os dois podem estar ausentes em consultas anteriores a 02/09/2026.
| erro_codigo | retryable | O que aconteceu |
|---|---|---|
INVALID_PLATE | false | Placa inválida. Também: INVALID_CHASSIS, INVALID_ENGINE, INVALID_RENAVAM, INVALID_DOCUMENT, MISSING_REQUIRED_FIELD, UF_UNAVAILABLE. |
QUERY_NOT_FOUND | false | A base consultou e não encontrou registro para os dados enviados. |
PROVIDER_TIMEOUT | true | A base demorou além do limite. Repita em alguns minutos. |
PROVIDER_UNAVAILABLE | true | A base está fora do ar ou instável. Repita em alguns minutos. Também: CIRCUIT_OPEN. |
PROVIDER_INVALID_RESPONSE | true | A base respondeu de forma incompleta. |
PROVIDER_ERROR | false | A base recusou a consulta. Também: PROVIDER_NO_DOCUMENT (documento não emitido), PROVIDER_AUTH_ERROR. |
PROCESSING_INTERRUPTED | true | O processamento foi interrompido do nosso lado. Também: QUEUE_UNAVAILABLE. |
INTERNAL_ERROR | false | Falha interna da ZapCar, já reportada à equipe. Também: PDF_GENERATION_FAILED, ADAPTER_ERROR, CONFIG_ERROR. |
dados — o resultado é só o PDF, em pdf_url.nao_verificado lista as categorias que a base estadual não checou nesta consulta. Uma restrição que aparece nessa lista vem como "" em dados — e isso é ausência de verificação, não ausência de restrição. Trate os três estados separadamente: "NADA CONSTA" (verificado e limpo), texto descritivo (restrição ativa) e vazio + presente em nao_verificado (não informado). A base estadual atual verifica financiamento, RENAJUD, roubo/furto, veículo baixado e comunicação de venda; não verifica restricao_judicial, restricao_administrativa, restricao_tributaria e restricao_guincho, que só aparecem quando há ocorrência descrita em restricoes[] — espere essas quatro em nao_verificado na maioria das consultas.Baixar o PDF
Retorna o documento — o mesmo do painel. Disponível quando o status é concluido; antes disso responde 400 PDF_NOT_READY. Na Consulta Simples o documento é gerado pela ZapCar no layout do laudo da base estadual, a partir do mesmo dados que a API devolve; itens que a base não respondeu saem como NÃO INFORMADO. Consultas feitas entre 28/08 e 09/09/2026 continuam entregando o PDF emitido pela base da época.
Content-Type, não na extensão. Quase todos os serviços devolvem application/pdf, mas alguns emissores de documento oficial entregam imagem — nesses casos a resposta sai como image/png ou image/jpeg, com a extensão certa no Content-Disposition. Salvar tudo como .pdf gera arquivo que não abre. Se o arquivo guardado estiver corrompido, a API responde 422 DOCUMENTO_CORROMPIDO em vez de entregar bytes quebrados.curl -L https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID/pdf \ -H "Authorization: Bearer zc_live_sua_chave_aqui" \ -o relatorio.pdf
dados e monte o seu próprio documento com a sua marca. O pdf_url fica ali como atalho para quem quiser o relatório pronto.Imagens da Consulta Completa
Baixa uma imagem da Consulta Completa: foto do veículo em pátio de leilão, imagem de vistoria/anúncio ou o certificado do laudo CSV. Só a Consulta Completa tem imagens; nos demais serviços a resposta é 404 IMAGEM_NOT_FOUND.
Você não monta essas URLs à mão: elas já vêm prontas dentro de dados, em fotosLeilao[].url, imagensOutras[].url e csv[].imagem_url / csv[].pdf_url.
| Parâmetro | Valores | Descrição |
|---|---|---|
tipo | leilao · outra · csv-imagem · csv-pdf | O que a imagem é. Só "leilao" é prova de passagem por leilão. |
indice | inteiro ≥ 0 | Posição no array correspondente dentro de dados: fotosLeilao[i], imagensOutras[i], csv[i]. |
fotosLeilao com itens significa que o veículo passou por leilão, mesmo que leilao venha null — isso quer dizer apenas que a base de ocorrências não trouxe lote e comitente.curl -L https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID/imagens/leilao/0 -H "Authorization: Bearer zc_live_sua_chave_aqui" -o leilao_0.png
A resposta é o binário, com o Content-Type real (image/png, image/jpeg ou application/pdf) — confie nele, não na extensão que você escolher.
404 IMAGEM_NOT_FOUND. O PDF do laudo dessas consultas continua disponível normalmente.Tabela FIPE por placa
Retorna os valores da Tabela FIPE do veículo a partir da placa. Ao contrário dos demais serviços, este endpoint é síncrono: a resposta vem na mesma chamada — sem id, sem polling e sem PDF.
GET /v1/servicos (serviço fipe).| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
placa | string | Sim | Placa do veículo (com ou sem hífen). Ex.: "ABC1D23". |
curl -X POST https://api.zapcarconsulta.com.br/v1/fipe \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "placa": "ABC1D23" }'{
"id": "6f1c2e2a-1b3d-4a9e-8f7c-2a1b3c4d5e6f",
"servico": "fipe",
"placa": "ABC1D23",
"veiculo": { "marca": "VW", "modelo": "CROSSFOX", "ano_modelo": "2007" },
"fipe": [
{
"codigo_fipe": "005225-6",
"marca": "VW - Volkswagen",
"modelo": "CROSSFOX 1.6 Mi Total Flex 8V",
"ano_modelo": "2007",
"combustivel": "Gasolina",
"sigla_combustivel": "G",
"valor": "R$ 26.799,00",
"mes_referencia": "maio de 2022",
"referencia_fipe": 285,
"score": 101,
"codigo_marca": "60",
"codigo_modelo": "2398",
"tipo_modelo": 1
}
],
"valor_cobrado": 0.25,
"saldo_restante": 464.76
}O campo fipe é uma lista: pode trazer mais de uma correspondência (o score indica a precisão — maior é melhor). Escolha a de maior score quando houver várias.
| HTTP | Código | Quando acontece |
|---|---|---|
| 402 | SALDO_INSUFICIENTE | Saldo menor que R$ 0,25. Nada é cobrado. |
| 404 | FIPE_NAO_DISPONIVEL | Placa válida, mas sem FIPE correspondente. Valor estornado. |
| 502 | FIPE_ERRO | Falha ao consultar a fonte. Valor estornado. |
| 503 | FIPE_INDISPONIVEL | Serviço temporariamente fora. Valor estornado. |
Webhooks (receber sem polling)
Em vez de perguntar de tempos em tempos se a consulta ficou pronta, você registra uma URL sua e a ZapCar avisa quando o evento acontece. É o caminho recomendado para o CRLV-e assíncrono e para volumes maiores — economiza requisições e chega antes.
secret — que aparece uma única vez, na criação. Guarde-o: é com ele que você valida cada entrega. Dá para rotacionar o secret e disparar um evento de teste (webhook.test) sem gastar saldo.Eventos disponíveis
| Evento | Quando dispara |
|---|---|
query.completed | A consulta chegou ao estado final com sucesso. Busque o resultado em GET /v1/consultas/:id. |
query.failed | A consulta falhou em definitivo (depois das tentativas). O valor é estornado. |
vehicle.restriction.created | O monitoramento detectou restrição nova na placa (inclui roubo/furto). |
vehicle.gravame.created | O monitoramento detectou gravame registrado. |
vehicle.gravame.removed | O monitoramento detectou baixa de gravame. |
vehicle.debt.created | O monitoramento detectou débito novo. |
vehicle.document.changed | O monitoramento detectou mudança na situação documental. |
webhook.test | Você mesmo disparou pelo painel, para conferir a integração. |
vehicle.* só existem para placas que você colocou no Monitoramento: eles nascem da comparação entre uma consulta e a anterior, não de uma vigilância em tempo real.O que chega no seu endpoint
Um POST com corpo JSON e três cabeçalhos próprios:
| Cabeçalho | Conteúdo |
|---|---|
X-ZapCar-Event | Nome do evento (ex.: query.completed). |
X-ZapCar-Delivery | Id desta tentativa de entrega — útil no suporte. |
X-ZapCar-Signature | Assinatura HMAC no formato t=<timestamp>,v1=<hmac>. |
{
"id": "b2c3d4e5-6f70-...", // id do EVENTO — use para idempotência
"type": "query.completed",
"created_at": "2026-08-19T12:00:00.000Z",
"data": {
"id": "a1b2c3d4-...", // id da consulta (GET /v1/consultas/:id)
"servico": "CONSULTA_COMPLETA",
"status": "CONCLUIDO"
}
}GET /v1/consultas/:id. É proposital: o que trafega até a sua URL fica mínimo, e o dado sensível só sai por chamada autenticada com a sua chave.Validar a assinatura
Assine <timestamp>.<corpo bruto> com HMAC-SHA256 usando o seu secret e compare com o v1 do cabeçalho. Use o corpo exatamente como chegou: se você fizer parse e re-serializar o JSON antes de assinar, a assinatura não bate.
const crypto = require("crypto");
// Corpo BRUTO (Buffer), não req.body já parseado — a assinatura é sobre os bytes.
app.post("/webhooks/zapcar", express.raw({ type: "application/json" }), (req, res) => {
const header = req.get("X-ZapCar-Signature") || "";
const t = /t=(\d+)/.exec(header)?.[1];
const v1 = /v1=([a-f0-9]+)/.exec(header)?.[1];
if (!t || !v1) return res.sendStatus(400);
// Rejeita evento antigo: barra o replay de uma entrega capturada.
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return res.sendStatus(400);
const esperado = crypto
.createHmac("sha256", process.env.ZAPCAR_WEBHOOK_SECRET)
.update(t + "." + req.body.toString("utf8"))
.digest("hex");
// Comparação em tempo constante.
const a = Buffer.from(esperado), b = Buffer.from(v1);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(401);
const evento = JSON.parse(req.body.toString("utf8"));
// Responda 2xx RÁPIDO e processe depois (fila). Demorar aqui vira retry nosso.
res.sendStatus(200);
processarDepois(evento); // ignore se evento.id já foi processado
});Reentrega e duplicatas
| Regra | Comportamento |
|---|---|
| O que conta como sucesso | Qualquer resposta 2xx. Outro status — ou timeout — conta como falha. |
| Tempo para responder | Responda em poucos segundos. Passando do limite, a entrega vira falha e será retentada. |
| Tentativas | Até 6, com backoff exponencial a partir de 10s (10s, 20s, 40s, 80s…). |
| Endpoint desativado | Não é retentado. A entrega fica marcada como falha no histórico. |
| Duplicatas | Um retry reenvia o MESMO id de evento. Guarde os ids já processados e ignore repetidos. |
| Histórico | As últimas entregas de cada endpoint aparecem no painel, com status, código HTTP e erro. |
id do evento — não pela ordem de chegada, que também não é garantida.Catálogo de serviços
O campo servico aceita os slugs abaixo. Aceitamos também os apelidos consulta-simples, gravames e codigo-de-seguranca.
| Slug | Serviço | Requer | Entrega |
|---|---|---|---|
consulta | Consulta Simples | placa | JSON do veículo + PDF |
consulta-completa | Consulta Completa | placa | JSON estruturado (por seção) + PDF |
gravame | Gravame | placa | JSON cru do provedor + PDF |
renajud | RENAJUD | placa | JSON cru do provedor + PDF |
debitos | Débitos + Cód. de Barras | placa | JSON cru do provedor + PDF |
decodificacao-chassi | Decodificação de Chassi | chassi | JSON do provedor + PDF |
decodificacao-motor | Decodificação de Motor | motor | JSON do provedor + PDF |
score-credito | Score de Crédito | documento (CPF ou CNPJ) | JSON do provedor + PDF |
debitos-estadual | Débitos Estaduais | placa, uf, renavam (+ documento/chassi em algumas UFs) | JSON do provedor + PDF |
crlv | CRLV Digital | placa, uf (+ cpf/renavam em algumas UFs) | Documento em PDF (sem JSON) |
atpve | 2ª via do ATPV-e | placa | Documento em PDF (sem JSON) |
codigo-seguranca | Código de Segurança | placa, renavam | PDF com o código (sem JSON) |
JSON completo do campo dados por serviço. Campos sem valor vêm null, vazios ou são omitidos. Na consulta simples, os campos de restrição (restricao_financeira, restricao_administrativa, restricao_judicial, restricao_renajud, roubo_furto, comunicacao_venda) vêm como "CONSTA" / "NAO CONSTA"; veiculo_baixado: true indica sucata de leilão (perda total); e restricoes[] lista só bloqueios que não têm campo próprio.
Consulta Simples (consulta)
{
"dados_do_veiculo": {
"placa": "ABC1D23",
"chassi": "9BWZZZ377VT004251",
"renavam": "00987495364",
"marca": "VW",
"modelo": "NIVUS HIGHLINE TSI",
"anofabricacao": "2022",
"anomodelo": "2022",
"cor": "PRATA",
"combustivel": "GASOLINA",
"tipoveiculo": "AUTOMOVEL",
"municipio": "SAO PAULO",
"uf": "SP"
},
"informacoes_tecnicas_e_adicionais": {
"motor": "D4FB1234567",
"cilindradas": "999",
"especie": "PASSAGEIRO",
"categoria": "PARTICULAR",
"carroceria": "INEXISTENTE",
"capacidadedepassageiros": "5",
"quantidadedeeixos": "2",
"situacaodochassi": "NORMAL",
"procedencia": "NACIONAL"
},
"restricoes_e_impedimentos": {
"situacao_veiculo": "EM CIRCULACAO",
"roubo_e_furto": "NADA CONSTA",
"restricoes": [],
"intencao_de_financiamento": {
"restricaofinanceira": "NADA CONSTA",
"restricaorenajud": "NADA CONSTA",
"restricaojudicial": "",
"restricaoadministrativa": "",
"restricaotributaria": "",
"restricaoguincho": "",
"agente": "",
"nomedofinanciado": ""
}
},
"debitos_estaduais": {
"debitosdeipva": "0",
"debitosdelicenciamento": "150,00",
"debitosdedpvat": "0",
"debitosdemultas": "0",
"exerciciolicenciamento": "2024"
},
"comunicacao_de_vendas": { "comunicacaodevendas": "NADA CONSTA" },
"proprietario_s_": {
"proprietario_atual": "JOAO DA SILVA",
"documento": "12345678901"
}
}Consulta Completa (consulta-completa)
{
"placa": "ABC1D23",
"chassi": "9BWZZZ377VT004251",
"renavam": "00987495364",
"marcaModelo": "VW/NIVUS HIGHLINE TSI",
"anoFabricacao": 2022,
"anoModelo": 2022,
"cor": "PRATA",
"combustivel": "GASOLINA",
"tipoVeiculo": "AUTOMOVEL",
"especie": "PASSAGEIRO",
"categoria": "PARTICULAR",
"potencia": 128,
"cilindrada": 999,
"quantidadeEixos": 2,
"capacidadePassageiros": 5,
"procedencia": "NACIONAL",
"chassiRemarcado": false,
"situacaoLicenciamento": "LICENCIADO",
"licenciadoAte": "2025",
"anoUltimoLicenciamento": 2024,
"numeroDocumentoFaturado": "12345678901",
"ufFaturamento": "SP",
"proprietario": {
"nome": "JOAO DA SILVA",
"nomeLegal": null,
"documento": "12345678901",
"tipoDocumento": "CPF",
"situacao": "REGULAR",
"telefones": [],
"emails": [],
"enderecos": [
{ "logradouro": "RUA X", "numero": "100", "bairro": "CENTRO",
"cep": "01000-000", "municipio": "SAO PAULO", "uf": "SP", "complemento": "" }
]
},
"restricoes": {
"rouboOuFurto": false,
"sinistro": null,
"restricaoRenajud": false,
"restricaoRfb": null,
"restricaoAdministrativa": null,
"restricaoRenainf": true,
"recall": false,
"intencaoVenda": false,
"anuncioVenda": false,
"restricaoGeral": true,
"veiculoBaixado": false,
"restricao1": "INDICADOR MULTA RENAINF",
"restricao2": null,
"restricao3": null,
"restricao4": null,
"ocorrencia": null
},
"debitos": {
"dpvat": 0,
"ipva": 3821.78,
"licenciamento": 0,
"multa": 0,
"total": 3821.78,
"estado": {
"dpvat": "SEM_DEBITO",
"ipva": "CONSTA",
"licenciamento": "SEM_DEBITO",
"multa": "CONSTA_SEM_VALOR"
},
"total_parcial": true
},
"gravames": [
{
"numeroRestricao": null, "dataRestricao": null, "ufRestricao": null,
"status": null, "nomeAgente": null, "documentoAgente": null,
"dataContrato": null, "ufContrato": null, "numeroContrato": null,
"documentoFinanciado": null, "nomeFinanciado": null
}
],
"leilao": null,
"renainf": {
"total": 2,
"ocorrencias": [
{
"autoInfracao": "T000123456",
"dataInfracao": "14/03/2025 08:41",
"infracao": "TRANSITAR EM VELOCIDADE SUPERIOR A MAXIMA PERMITIDA",
"orgaoAutuador": "DER", "ufOrgaoAutuador": "MG",
"codigoInfracao": "74550", "valor": 130,
"dataNotificacao": "02/04/2025",
"valorPago": null, "dataPagamento": null, "exigibilidade": "EXIGIVEL"
}
]
},
"csv": [
{
"identificacao": "CSV-2024-000123",
"tipo": null, "dataInspecao": null, "municipioUf": null,
"itl": null, "itlCnpj": null, "escopo": null, "mensagem": null,
"observacao": "Laudo apresentado como cortesia. Consulte as bases oficiais.",
"imagem_url": "/v1/consultas/{id}/imagens/csv-imagem/0",
"pdf_url": "/v1/consultas/{id}/imagens/csv-pdf/0"
}
],
"informacoesAvulsas": [
{ "codigo": "12", "descricao": "STATUS LICENCIAMENTO", "valor": "LICENCIADO" },
{ "codigo": "18", "descricao": "LICENCIAMENTO ATE", "valor": "31/12/2025" }
],
"fotosLeilao": [
{ "indice": 0, "url": "/v1/consultas/{id}/imagens/leilao/0" },
{ "indice": 1, "url": "/v1/consultas/{id}/imagens/leilao/1" }
],
"imagensOutras": [],
"blocos": {
"BIN_NACIONAL": { "respondeu": true, "quantidade": 1, "descricao": null },
"BIN_ESTADUAL": { "respondeu": true, "quantidade": 1, "descricao": null },
"RENAJUD": { "respondeu": true, "quantidade": 0, "descricao": null },
"RENAINF": { "respondeu": true, "quantidade": 2, "descricao": null },
"RECALL": { "respondeu": true, "quantidade": 0, "descricao": null },
"ALERTAS": { "respondeu": true, "quantidade": 1, "descricao": null },
"CSV": { "respondeu": true, "quantidade": 1, "descricao": null },
"IMAGENS_VEICULO":{ "respondeu": true, "quantidade": 2, "descricao": null },
"PROPRIETARIO_ATUAL_VEICULO": { "respondeu": true, "quantidade": 1, "descricao": null }
},
"offline": false
}Gravame (gravame)
{
"placa": "ABC1D23",
"ufplaca": "SP",
"chassi": "9BWZZZ377VT004251",
"renavam": "00987495364",
"anofabricacao": 2022,
"anomodelo": 2022,
"statusdoveiculo": "ALIENADO FIDUCIARIAMENTE",
"descricaostatus": "INCLUSAO DE GRAVAME",
"financeiranome": "BANCO XPTO S.A.",
"documentofinanceira": "60701190000104",
"codigofinanceira": null,
"numerogravame": "8918837",
"nomefinanciado": "JOAO DA SILVA",
"documentoproprietarioatual": "12345678901",
"numerocontrato": "000123456",
"ufgravame": "SP",
"datagravame": "2022-05-14",
"datagravamevigencia": null,
"marcamodelo": "M.BENZ/ATEGO 2425",
"cor": "BRANCA",
"municipio": "RIO DE JANEIRO",
"combustivel": "DIESEL",
"motor": "ABC123456",
"ocorrencias": [
{ "numero_gravame": "8918837", "nome_agente": "BANCO XPTO S.A.",
"doc_agente": "60701190000104", "numero_contrato": "000123456",
"uf_placa": "SP", "ativo": true }
]
}RENAJUD (renajud)
{
"placa": "ABC1D23",
"renavam": "00987495364",
"marca": "VW",
"ano_fabricacao": "2022",
"ano_modelo": "2022",
"base": "SP",
"cor": "PRATA",
"combustivel": "GASOLINA",
"especie": "PASSAGEIRO",
"tipo": "AUTOMOVEL",
"motor": "D4FB1234567",
"eixos": "2",
"capacidade_passageiros": "5",
"municipio": "SAO PAULO",
"procedencia": "NACIONAL",
"consta_renajud": "SIM",
"quantidade_bloqueio_ativo_localizado": 1,
"quantidade_ocorrencias_exibidas_e_disponivel_pelo_detran": 1,
"quantidade_ocorrencia_total": "1",
"renajud": [
{
"consta_restricao": "SIM",
"chassi": "9BWZZZ377VT004251",
"placa": "ABC1D23",
"quantidade_ocorrencias": "1",
"tipo_restricao_judicial": "TRANSFERENCIA",
"codigo_tribunal": "TJSP",
"nome_tribunal": "TRIBUNAL DE JUSTICA DE SP",
"codigo_orgao_judicial": "0001",
"nome_orgao_judicial": "1A VARA CIVEL",
"numero_processo": "0000000-00.2024.8.26.0000",
"data_inclusao": "2024-06-01"
}
]
}Débitos + Cód. de Barras (debitos)
{
"success": true,
"statusCode": 2,
"msg": "CONSULTA CONCLUIDA COM SUCESSO",
"paid": true,
"uuidRequest": "161461e8-87f4-46b3-85b4",
"registros": [
{
"descricao": "IPVA 2025",
"tipo": "IPVA",
"valor": 1240.55,
"subtotal": 1240.55,
"dataVencimento": "2025-03-31",
"statusPagamento": "EM ABERTO",
"linhaDigitavel": "85800000015-3 35910000...",
"codigoBarra": "858000000153359100...",
"detalhes": [
{ "chave": "Exercício", "grupo": "IPVA", "valor": "2025" }
]
}
]
}Decodificação de Chassi (decodificacao-chassi)
{
"placa": "ABC1D23",
"placa_mercosul": "ABC1D23",
"chassi": "9C2KD0540CR506454",
"motor": "KD05E1234567",
"marca": "HONDA",
"modelo": "NXR150 BROS ESD",
"cor": "VERMELHA",
"ano_fabricacao": "2011",
"ano_modelo": "2012",
"tipo": "MOTOCICLO",
"especie": "PASSAGEIRO",
"uf": "BA",
"combustivel": "ALCOOL/GASOLINA",
"municipio": "CONCEICAO DO JACUIPE",
"importado": "NAO",
"tipo_possivel": [
{
"referencia": "julho/2026",
"tipo_codigo": "811154-3",
"ano_modelo": "2012",
"tipo_veiculo": "MOTOCICLETA",
"marca": "HONDA",
"modelo": "NXR 150 BROS ESD",
"combustivel": "GASOLINA",
"valor": "R$ 9.800,00"
}
]
}Decodificação de Motor (decodificacao-motor)
{
"placa": "ABC1D23",
"chassi": "9C2KD0540CR506454",
"motor": "KD05E1234567",
"marca": "HONDA",
"modelo": "NXR150 BROS ESD",
"cor": "VERMELHA",
"ano_fabricacao": "2011",
"ano_modelo": "2012",
"tipo": "MOTOCICLO",
"uf": "BA",
"combustivel": "ALCOOL/GASOLINA",
"tipo_possivel": [ /* mesmas sugestões da Tabela FIPE do chassi */ ]
}Score de Crédito (score-credito)
{
"dados receita federal": {
"tipo_pessoa": "Física",
"nome": "FULANO DE TAL",
"situacao_receita": "REGULAR",
"data_nascimento_fundacao": "01/01/1990",
"nome_mae": "CICLANA DE TAL"
},
"score": {
"ocorrencias": [
{ "tipo_score": "score portfolio", "score": "780", "probabilidade_inadimplencia": "3,2" }
]
},
"email": { "registro_localizado": "S", "informado": "fulano@exemplo.com" },
"numero_endereco": {
"dados": [ { "endereco": "RUA EXEMPLO", "numero": "100", "bairro": "CENTRO", "cidade": "SAO PAULO", "uf": "SP", "cep": "01000000" } ]
},
"renda_presumida": { "faixa": "R$ 3.000,00 a R$ 5.000,00", "valor_presumido": "R$ 4.200,00 ao mês" }
}Débitos Estaduais (debitos-estadual)
{
"veiculo": { "placa": "ABC1D23", "renavam": "12345678901", "marca": "VW", "modelo": "GOL", "uf": "SP" },
"ipvas": [ { "ano": "2024", "valor": 512.30, "vencimento": "2024-03-15", "status": "EM ABERTO" } ],
"licenciamentos": [ { "ano": "2024", "valor": 98.91, "vencimento": "2024-10-31" } ],
"dpvats": [ { "exercicio": "2024", "valor": 0.0 } ],
"multas": [ { "ait": "X000000000", "infracao": "Avançar o sinal vermelho", "orgao": "DETRAN-SP", "valor": 195.23, "vencimento": "2024-05-20" } ],
"dividaativa": []
}dados.debitos saía sempre zerado; agora traz os valores reais (IPVA, licenciamento, DPVAT e multas), mais estado por item e total_parcial. Se o seu código tratava esse bloco como sempre zero, revise. Leia estado antes do número: CONSTA_SEM_VALOR significa “deve, valor não informado” — nesse caso total_parcial: true e o total é um piso, não o devido. debitos: null é “não verificado”. Para código de barras e linha digitável, continue usando o serviço debitos.Decodificação de Chassi e de Motor
Diferente dos demais serviços, estes não usam placa: identifique o veículo pelo chassi (serviço decodificacao-chassi) ou pelo número do motor (serviço decodificacao-motor). A resposta traz os dados do veículo em dados e sugestões da Tabela FIPE em tipo_possivel[] (pode vir vazio quando não há correspondência). Também há PDF em pdf_url.
curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "decodificacao-chassi", "chassi": "9C2KD0540CR506454" }'curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "decodificacao-motor", "motor": "KD05E1234567" }'Documentos em PDF (CRLV, ATPV-e e Código de Segurança)
Esses três não devolvem dados — o resultado é um documento em PDF. Quando o status vira concluido, baixe pela pdf_url (ou GET /v1/consultas/{id}/pdf). A resposta não tem o campo dados.
| Serviço | Slug | Campos obrigatórios |
|---|---|---|
| CRLV Digital | crlv | placa + uf — algumas UFs exigem também cpf e renavam |
| 2ª via do ATPV-e | atpve | placa — e nada mais |
| Código de Segurança | codigo-seguranca | placa + renavam |
preco_por_uf nem lista de estados atendidos, ao contrário do CRLV. Enviar uf é aceito, mas não decide preço nem disponibilidade. Por ser emissão, leva cerca de 1 minuto.GET /v1/servicos → crlv.preco_por_uf. Pedir uma UF fora dessa lista responde 422 SERVICO_INDISPONIVEL. Faltando o CPF/RENAVAM que a UF exige, a resposta é 400 CRLV_DADOS_OBRIGATORIOS.requer de cada UF em crlv.preco_por_uf — leia de lá em vez de fixar no código.curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "crlv", "placa": "ABC1D23", "uf": "SP", "cpf": "12345678909", "renavam": "00987495364" }'curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "crlv", "placa": "ABC1D23", "uf": "RJ" }'curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "servico": "codigo-seguranca", "placa": "ABC1D23", "renavam": "00987495364" }'{
"id": "6f1c2e2a-...",
"servico": "crlv",
"placa": "ABC1D23",
"uf": "SP",
"status": "concluido",
"valor_cobrado": 29.99,
"criado_em": "2026-07-29T09:14:02-03:00",
"pdf_url": "/v1/consultas/6f1c2e2a-.../pdf"
}Exemplos em código
O fluxo completo (criar → esperar → resultado) em algumas linguagens. Troque a chave e a placa.
cURL (terminal)
# 1. Cria a consulta (debita o saldo). Guarde o "id" da resposta.
curl -X POST https://api.zapcarconsulta.com.br/v1/consultas \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{"servico":"consulta","placa":"ABC1D23"}'
# 2. Ver o resultado (troque COLE_O_ID). Repita até status = "concluido".
curl https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID \
-H "Authorization: Bearer zc_live_sua_chave_aqui"
# 3. Baixar o PDF (quando concluído).
curl -L https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID/pdf \
-H "Authorization: Bearer zc_live_sua_chave_aqui" \
-o relatorio.pdfJavaScript / Node.js
const BASE = "https://api.zapcarconsulta.com.br";
const CHAVE = "zc_live_sua_chave_aqui";
async function consultarVeiculo(placa) {
// 1. cria a consulta (debita o saldo)
const criar = await fetch(BASE + "/v1/consultas", {
method: "POST",
headers: {
"Authorization": "Bearer " + CHAVE,
"Content-Type": "application/json",
},
body: JSON.stringify({ servico: "consulta", placa }),
});
if (criar.status === 402) throw new Error("Saldo insuficiente");
const { id } = await criar.json();
// 2. faz polling até concluir (a cada 5s, por até ~5 min).
// A base estadual leva até ~2 min numa placa fria: "processando" nunca é erro.
for (let i = 0; i < 60; i++) {
await new Promise((r) => setTimeout(r, 5000));
const res = await fetch(BASE + "/v1/consultas/" + id, {
headers: { "Authorization": "Bearer " + CHAVE },
});
const c = await res.json();
if (c.status === "concluido") return c; // c.dados + c.pdf_url
if (c.status === "erro") {
// c.retryable: true = a base caiu, tente de novo. false = definitivo
// (placa inexistente, contrato). Ausente = não classificamos.
if (c.retryable) continue; // volta ao topo do laço
throw new Error("Consulta falhou (estornada)");
}
}
throw new Error("Tempo esgotado");
}
consultarVeiculo("ABC1D23").then((c) => console.log(c.dados));PHP
<?php
$BASE = "https://api.zapcarconsulta.com.br";
$CHAVE = "zc_live_sua_chave_aqui";
$H = ["Authorization: Bearer $CHAVE", "Content-Type: application/json"];
// 1. cria a consulta
$ch = curl_init("$BASE/v1/consultas");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => $H,
CURLOPT_POSTFIELDS => json_encode(["servico" => "consulta", "placa" => "ABC1D23"]),
]);
$id = json_decode(curl_exec($ch), true)["id"];
curl_close($ch);
// 2. polling até concluir
do {
sleep(3);
$ch = curl_init("$BASE/v1/consultas/$id");
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $H]);
$c = json_decode(curl_exec($ch), true);
curl_close($ch);
} while ($c["status"] === "processando");
print_r($c["dados"]);Testar no Postman
Se preferir clicar em vez de programar, use o Postman. Importe a coleção pronta (gerada do catálogo, sempre com os serviços vigentes) ou a descrição OpenAPI 3.0 — e cole a sua chave na variável api_key. Ou monte as requisições à mão:
Configure a autenticação
zc_live_…. Isso vale para cada requisição.Teste a conexão (GET)
https://api.zapcarconsulta.com.br/v1/servicos → Send. Se vier 200, está funcionando.Crie a consulta (POST)
https://api.zapcarconsulta.com.br/v1/consultas. Aba Body → raw → escolha JSON → cole { "servico": "consulta", "placa": "ABC1D23" } → Send. Copie o id.Veja o resultado (GET)
https://api.zapcarconsulta.com.br/v1/consultas/COLE_O_ID → Send, repetindo até concluido.id na URL. Para ver um resultado é sempre GET com id; para criar é POST sem id.Códigos de erro
Erros seguem o formato { "erro": "...", "codigo": "..." } com o status HTTP correspondente.
| HTTP | Código | Repetir? | Quando acontece |
|---|---|---|---|
| 400 | CHASSI_INVALIDO | não | Chassi inválido. |
| 400 | CONSULTA_WITHOUT_DATA | não | Consulta sem dados para gerar o documento. |
| 400 | CRLV_DADOS_OBRIGATORIOS | não | Faltam campos exigidos pela UF (CPF/RENAVAM). |
| 400 | DEBITOS_DADOS_OBRIGATORIOS | não | Faltam campos exigidos pela UF. |
| 400 | DOCUMENTO_INVALIDO | não | CPF/CNPJ inválido. |
| 400 | IDEMPOTENCY_KEY_INVALIDA | não | Idempotency-Key fora do formato (8–255 chars). |
| 400 | MOTOR_INVALIDO | não | Número do motor inválido. |
| 400 | PDF_NOT_READY | sim | Pediu o PDF antes de a consulta concluir. Espere o status "concluido". |
| 400 | PLACA_INVALIDA | não | Placa em formato inválido. |
| 422 | DOCUMENTO_CORROMPIDO | não | O arquivo guardado não é um documento válido (PDF/PNG/JPEG). Refaça a consulta. |
| 400 | RENAVAM_INVALIDO | não | RENAVAM inválido. |
| 400 | SERVICO_INVALIDO | não | O campo "servico" não corresponde a nenhum serviço. |
| 400 | UF_INDISPONIVEL | não | UF indisponível para o serviço. |
| 400 | UF_INVALIDA | não | UF ausente ou diferente de 2 letras. |
| 400 | VALIDATION_ERROR | não | Corpo da requisição inválido (vem com "detalhes" por campo). |
| 401 | CUSTOMER_NOT_FOUND | não | Conta associada à chave não encontrada. |
| 401 | INVALID_API_KEY | não | A chave é inválida, foi revogada ou não existe. |
| 401 | MISSING_API_KEY | não | Cabeçalho Authorization: Bearer <chave> ausente. |
| 402 | SALDO_INSUFICIENTE | não | Saldo menor que o preço. A resposta traz o "saldo" atual. |
| 404 | CONSULTA_NOT_FOUND | não | O id não existe ou não pertence à sua conta. |
| 404 | FIPE_NAO_DISPONIVEL | não | Sem FIPE para esta placa. |
| 404 | PDF_NOT_FOUND | não | PDF não disponível para esta consulta. |
| 404 | ROTA_NAO_ENCONTRADA | não | Método ou URL não batem com nenhum endpoint. |
| 409 | IDEMPOTENCY_IN_PROGRESS | sim | Requisição idêntica ainda em processamento; repita em instantes. |
| 422 | IDEMPOTENCY_KEY_REUSED | não | Mesma Idempotency-Key com payload diferente. |
| 422 | SERVICO_INDISPONIVEL | não | Serviço sem preço/config (ex.: UF não atendida no CRLV). |
| 429 | RATE_LIMITED | sim | Muitas requisições no intervalo. Aguarde e tente de novo. |
| 500 | INTERNAL_ERROR | sim | Erro interno inesperado. |
| 502 | FIPE_ERRO | sim | Falha transitória ao consultar a FIPE. |
| 503 | CIRCUIT_OPEN | sim | Fornecedor temporariamente indisponível (circuito aberto). |
| 503 | FIPE_INDISPONIVEL | sim | Provedor FIPE temporariamente indisponível. |
| 504 | PROVIDER_TIMEOUT | sim | Tempo de resposta do fornecedor excedido. |
Problemas comuns
404 "Rota não encontrada"
Método ou URL não batem. Quase sempre é: (a) usar POST com o id na URL — para ver resultado é GET; (b) usar GET em /v1/consultas sem id para criar — criar é POST; ou (c) a URL está digitada errada.
401 chave não fornecida / inválida
Faltou o cabeçalho Authorization: Bearer …, ou a chave está errada/revogada. No Postman, confira a aba Authorization em cada requisição.
400 ao baixar o PDF
É PDF_NOT_READY: você pediu o PDF antes de a consulta concluir. Consulte o resultado até o status virar concluido e só então baixe o PDF.
402 saldo insuficiente
Sua carteira não tem o valor do serviço. Recarregue no painel (Carteira) e tente de novo.
Resultado voltou vazio ou "não encontrado"
A consulta funcionou, mas a base consultada não encontrou o veículo. Confira se a placa é real e está correta — placa inventada não retorna dados.
Boas práticas
- ›Guarde a chave no servidor (variável de ambiente). Nunca a exponha no navegador ou em apps.
- ›Faça polling com intervalo de 3–5s e teto de ~5 minutos; não consulte em loop apertado nem desista em 60s.
- ›Monitore o saldo com GET /v1/saldo e recarregue antes de acabar.
- ›Guarde o id de cada consulta: use-o para rebaixar o PDF ou reconsultar o resultado depois.
- ›Trate o status "erro" — o valor é estornado, mas convém reenviar a consulta.
- ›Ao revogar uma chave, ela para na hora. Gere a nova antes de trocar em produção.
Pronto para começar?
Crie sua conta, gere a chave e faça a primeira consulta.