Skip to content
Vai integrar a API REST da Zarv com ajuda de IA? Copie a instrução que aponta o modelo para esta documentação.
Ver a instrução
Você vai integrar a API REST da Zarv. Use a documentação oficial como fonte da verdade.

- Página desta integração: https://developers.zarv.com/api/lens/coleta
- Autenticação Bearer JWT e hosts: https://developers.zarv.com/setup
- Índice das APIs: https://developers.zarv.com/api
- Índice da documentação em markdown: https://developers.zarv.com/llms.txt
- Documentação completa em um arquivo: https://developers.zarv.com/llms-full.txt

Os specs OpenAPI publicados são a fonte da verdade para rotas e schemas — use o spec da API que você escolher antes de escrever qualquer request.

Antes de escrever qualquer código, leia a página desta integração. Siga exatamente os nomes de campos, endpoints, callbacks e formatos que estiverem documentados — não invente parâmetros nem endpoints, e não deduza comportamento a partir de outras APIs que você conhece. Se algo de que você precisa não estiver na documentação, diga que não está em vez de supor.

Minha tarefa: [ex.: escolher a API certa e fazer a primeira chamada autenticada]

Coleta ​

A Coleta é a etapa em que o caso ganha matéria: um caso aberto, os envolvidos declarados e os documentos enviados. O que acontece aqui decide a qualidade de tudo o que vem depois — a análise só cruza o que a Coleta trouxe.

O jeito curto de fazer a Coleta inteira é abrir o caso e mandar os arquivos: o Lens identifica cada um, lê com o agente certo e monta o caso a partir das leituras — inclusive os envolvidos e o relato.

1. Abrir o caso ​

sh
curl -X POST "https://services.zarv.com/api/v1/lens/$WORKSPACE_ID/research" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "domain": "auto",
    "objective": "sinistro",
    "status": "CREATED",
    "incidentType": "colisao",
    "reportAddress": "Av. Paulista, 1000 - São Paulo/SP",
    "reportTime": "2026-11-03T23:48:00-03:00",
    "reportText": "Colisão traseira no cruzamento, sem vítimas.",
    "doubts": ["O condutor estava autorizado a dirigir?"]
  }'

domain, objective e status são obrigatórios; o resto pode vir depois, do PUT ou da montagem. O caso nasce na raia Abertura do quadro.

Declare o incidentType

Ele decide quais dimensões rodam na análise: a dimensão de Posse só roda em roubo e furto, a de Física precisa da dinâmica de uma colisão. Vazio, o fluxo deduz do relato — e um roubo que não diz "roubo" no texto roda como colisão, em silêncio.

Os valores: colisao, roubo, furto, desvio_de_carga, coleta_nao_autorizada, divergencia_operacional.

reportTime com o fuso do lugar do fato

Um furto declarado às 23:48 em Ribeirão Pires é 2026-11-03T23:48:00-03:00, que em UTC é 02:48 do dia 4. Quem formatar sem saber onde o fato aconteceu imprime o dia errado — e a dimensão de Cronologia compara datas.

Na leitura, o Lens devolve a data como declarada ("2026-11-03 23:48"), sem converter.

2. Enviar os documentos ​

Uma chamada só, com todos os arquivos do caso em Base64. Ela responde 202 sem chamar modelo nenhum: os arquivos vão para a fila, e um worker trabalha depois.

sh
curl -X POST "https://services.zarv.com/api/v1/lens/$WORKSPACE_ID/research/$RESEARCH_ID/document" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      { "fileName": "bo.pdf",       "contentType": "application/pdf", "base64": "...", "agentReader": true, "autoCreate": true },
      { "fileName": "apolice.pdf",  "contentType": "application/pdf", "base64": "...", "agentReader": true, "autoCreate": true },
      { "fileName": "crlv.pdf",     "contentType": "application/pdf", "base64": "...", "agentReader": true, "autoCreate": true },
      { "fileName": "frente.jpg",   "contentType": "image/jpeg",      "base64": "...", "agentReader": true },
      { "fileName": "traseira.jpg", "contentType": "image/jpeg",      "base64": "...", "agentReader": true }
    ]
  }'
json
{
  "researchId": "7d2f8e10-4c3b-4a5d-9e8f-1a2b3c4d5e6f",
  "status": "QUEUED",
  "total": 5,
  "progress": 0
}

As três chaves de cada arquivo ​

CampoO que faz
typeOpcional. Sem ele, o agente identifica o arquivo. Com ele, o tipo é o que você disse.
agentReaderManda o OCR do tipo ler o arquivo e gravar os campos no metadata. Obrigatório quando não há type.
autoCreateManda a leitura deste arquivo montar o caso: envolvidos e relato saem dela. Exige agentReader.

Um arquivo sem type e sem agentReader é recusado com 400, e o corpo traz o index dele — ninguém pode adivinhar o que o arquivo é.

Limites ​

LimiteValor
Arquivos por envio40
Tamanho de um arquivo (decodificado)10 MB
Soma dos arquivos (decodificados)50 MB
Formatosapplication/pdf, image/jpeg, image/png, image/webp

Passar de qualquer um deles é 413. Há um envio por caso: mandar outro com um em andamento é 409 RESEARCH_DOCUMENTS_IN_PROGRESS.

3. O que o worker faz com cada arquivo ​

arquivo ──sem type?──▶ identificador ──▶ target
                                          │
                 FOTO_VEICULO ────────────┤──▶ OCR Veículo ──▶ posição ──▶ tipo
                                          │
                 APOLICE, BO, CNH… ───────┴──▶ tipo
                                          │
                                   agentReader? ──▶ OCR do tipo ──▶ metadata
                                          │
                                    autoCreate? ──▶ montagem do caso

1. O identificador olha o arquivo sem saber o que ele é e diz o target, com o motivo (basis): apólice, boletim de ocorrência, aviso de sinistro, termo de terceiro, CNH, CRLV, foto do local, foto do veículo — ou OUTRO. O OUTRO fica fora do caso, com o motivo no resultado.

2. A foto de veículo passa também pelo OCR Veículo, que diz de que posição ela é — e é a posição que dá o tipo:

PosiçãoTipo do documento
frenteVEHICLE_FRENTE_CAPO_FAROIS
traseiraVEHICLE_TRASEIRA
lateral_esquerdaVEHICLE_LATERAL_ESQUERDA
lateral_direitaVEHICLE_LATERAL_DIREITA
interiorVEHICLE_INTERIOR_AIRBAGS
cofre_motorVEHICLE_COFRE_MOTOR

Uma foto que o OCR Veículo lê como outro ou nao_e_veiculo fica de fora, pelo mesmo motivo do OUTRO.

3. O OCR do tipo lê o arquivo e grava o que extraiu no metadata do documento, na chave do agente:

DocumentoChave no metadata
Boletim de ocorrênciaocrBo
ApóliceocrApolice
Aviso de sinistroocrAvisoSinistro
Termo de terceiroocrTermoTerceiro
CNHocrCnh
CRLVocrCrlv
Foto de veículoocrVehicle

Toda leitura traz, além dos campos próprios do documento, o que ele cita: persons_cited (nome, CPF, papel no documento, placa) e vehicles_cited (placa, chassi, marca, modelo, ano, papel). É dessas citações que a montagem do caso tira os envolvidos. identifyDocument guarda o que o identificador decidiu, e autoCreate: true marca os arquivos que entraram na montagem.

4. Acompanhar o envio ​

O andamento sai no GET do caso, em documents:

sh
curl "https://services.zarv.com/api/v1/lens/$WORKSPACE_ID/research/$RESEARCH_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
json
{
  "documents": {
    "status": "PROCESSING",
    "total": 5,
    "progress": 60,
    "errorCode": "",
    "results": [
      {
        "index": 0,
        "fileName": "bo.pdf",
        "type": "BOLETIM_OCORRENCIA",
        "documentId": "b41c…",
        "target": "BOLETIM_OCORRENCIA",
        "outcome": "read",
        "reason": ""
      },
      {
        "index": 3,
        "fileName": "frente.jpg",
        "type": "VEHICLE_FRENTE_CAPO_FAROIS",
        "documentId": "c52d…",
        "target": "FOTO_VEICULO",
        "position": "frente",
        "outcome": "read",
        "reason": ""
      },
      {
        "index": 4,
        "fileName": "selfie.jpg",
        "type": "",
        "documentId": "",
        "target": "OUTRO",
        "outcome": "left_out",
        "reason": "o arquivo não é um documento do caso"
      }
    ]
  }
}

results cresce arquivo a arquivo: um arquivo pronto já aparece antes de o envio terminar. O outcome de cada um:

outcomeSignificado
savedGravado como documento, sem leitura (veio com type e sem agentReader)
readGravado com a leitura do agente
read_failedGravado, mas o agente não conseguiu ler — o reason diz por quê
left_outFicou fora do caso — o reason diz por quê

status: DONE fecha o envio e leva o caso para Pronto para análise. Um envio que falhou leva para Dados inconsistentes.

5. A montagem do caso ​

Terminada a leitura, se pelo menos um arquivo veio com autoCreate, o Lens chama o agente de reconciliação: ele recebe as leituras de todos os documentos do caso, resolve quem é quem — a mesma pessoa citada em três documentos é uma pessoa só — e devolve os envolvidos com a árvore e as citações de onde cada um veio.

O resultado fica em documents.assembly:

json
{
  "assembly": {
    "status": "DONE",
    "errorCode": "",
    "entities": [
      {
        "key": "VEHICLE:TST1A23",
        "type": "VEHICLE",
        "value": "TST1A23",
        "name": "FIAT ARGO DRIVE 1.0",
        "roles": ["PRINCIPAL"],
        "entityId": "5e9a…",
        "outcome": "created"
      },
      {
        "key": "PERSON:11144477735",
        "type": "PERSON",
        "value": "11144477735",
        "name": "JOÃO DA SILVA",
        "roles": ["SEGURADO", "MOTORISTA"],
        "entityId": "a1b2…",
        "outcome": "created"
      },
      {
        "key": "PERSON:",
        "type": "PERSON",
        "value": "",
        "name": "TESTEMUNHA CITADA NO BO",
        "roles": [],
        "entityId": "",
        "outcome": "left_out",
        "reason": "pessoa sem CPF"
      }
    ],
    "institutional": 2,
    "fields": ["incidentType", "reportAddress", "reportTime"],
    "notes": ["A data do fato veio do boletim de ocorrência."]
  }
}

O que a montagem faz com cada envolvido:

  • created — nasceu agora, com manual: false: foi descoberto, não declarado. Nasce com o nome e o chassi no profile e as fontes da reconciliação no metadata, sem a consulta paga de cadastro.
  • updated — já estava no caso e ganhou os papéis que lhe faltavam, ou o vínculo com o veículo.
  • unchanged — já estava, e não havia o que mudar.
  • left_out — não entrou, e o reason diz por quê: pessoa ou empresa sem CPF/CNPJ, veículo sem placa, ou veículo cuja placa está em outro caso aberto do workspace.

institutional conta as citações que eram da parte institucional do documento — o cabeçalho, o carimbo, o órgão emissor — e por isso não viraram envolvido.

Nos campos do caso, incidentType e objective da reconciliação substituem os do caso; o endereço, o relato e a data só preenchem o que estava vazio. fields lista o que mudou.

A montagem não falha o envio

Se o agente de reconciliação não responder, o envio termina normalmente e assembly traz errorCode: RECONCILIATION_FAILED (ou AGENT_UNAVAILABLE). Os documentos continuam gravados; só os envolvidos não foram montados.

O caso montado é um ponto de partida: revise-o e corrija pelas rotas de envolvido e documento antes de pedir a análise.

Declarar um envolvido à mão ​

Quando você já sabe quem está no caso — ou quando quer corrigir o que a montagem trouxe:

sh
curl -X POST "https://services.zarv.com/api/v1/lens/$WORKSPACE_ID/research/$RESEARCH_ID/entity" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "type": "VEHICLE", "value": "TST1A23", "roles": ["PRINCIPAL"] }'

A consulta do cadastro ​

Incluir um envolvido consulta um provedor pago e guarda o resultado em profile:

TipovalueConsultaChave em profile
PERSONCPFDataset do Zarv ID v3 (PF)dataset
COMPANYCNPJDataset do Zarv ID v3 (PJ)dataset
VEHICLEPlacaZarv Assetasset

O documento é conferido — tamanho e dígito verificador — antes da consulta: um erro de digitação é 400, não uma consulta cobrada. A consulta vem depois de todas as conferências e antes de gravar, então o que seria recusado não é cobrado, e uma consulta que falha (502) não grava nada.

A árvore do caso ​

  • O VEHICLE é sempre raiz — ele não tem parentId.
  • A COMPANY só fica sob um VEHICLE.
  • O parentId tem de ser um envolvido deste caso.

Duas regras que evitam caso duplicado ​

Dentro do caso: se já existe um envolvido com aquele value, a chamada devolve o que já está lá — sem gravar de novo e sem consultar.

Entre casos: uma placa que já está num caso em aberto do mesmo workspace é recusada com 409, e o corpo traz o caso:

json
{
  "error": "a placa TST1A23 já está na pesquisa 7d2f8e10-…, que ainda está em aberto",
  "code": "VEHICLE_IN_OPEN_RESEARCH",
  "researchId": "7d2f8e10-4c3b-4a5d-9e8f-1a2b3c4d5e6f",
  "licensePlate": "TST1A23"
}

Não abra um segundo caso: continue naquele. Dois casos para a mesma ocorrência dividem as evidências, e nenhuma das duas análises vê o quadro inteiro.

Papéis ​

Um envolvido tem um ou mais papéis — o segurado que dirigia é SEGURADO e MOTORISTA.

ParaPapéis
VEHICLEPRINCIPAL, TERCEIRO_ENVOLVIDO, CADASTRADO_CONTA, ALOCADO_PEDIDO, OBSERVADO_COLETA
PessoasSEGURADO, DONO, MOTORISTA, PASSAGEIRO, VITIMA, TESTEMUNHA, CRIMINOSO, MOTORISTA_ALOCADO, MOTORISTA_OBSERVADO, REDE_*
Só COMPANYFUNILARIA, MECANICA, LOCADORA

SEGURADO não é sinônimo de DONO: quem tem a apólice nem sempre é o titular do veículo — e essa diferença é exatamente o que a dimensão Documental procura.

Um papel só de empresa numa pessoa física é 400 RESEARCH_ENTITY_ROLE_TYPE_MISMATCH.

A identidade é imutável

A placa e o CPF/CNPJ são a chave pela qual o Asset, o Zarv ID e as dimensões consultaram tudo. O PUT recusa trocá-los com 400 IDENTITY_IS_IMMUTABLE: para corrigir, remova e inclua de novo — e a inclusão consulta o cadastro outra vez.

Corrigir um documento ​

O PUT do documento substitui tudo: type, fileName, contentType e base64 são obrigatórios, e o que não vier é apagado. É por aqui que se corrige um tipo que o agente errou ou se amarra o documento a um envolvido.

Para preservar o que os OCRs leram, releia o documento antes e reenvie o metadata inteiro com a sua chave a mais.

Na listagem, use ?content=false sempre que não precisar do arquivo: com 40 documentos de até 10 MB, a listagem leve é a diferença entre dezenas de kilobytes e centenas de megabytes.

Quando a Coleta termina ​

Quando o envio fecha em DONE, o caso vai sozinho para Pronto para análise, e é a hora de conferir o que a montagem trouxe:

  1. Os envolvidos estão certos, com os papéis certos? (GET .../entity)
  2. Os documentos têm o tipo certo? (GET .../document?content=false)
  3. O relato, o endereço, a data e o incidentType estão preenchidos? (GET .../research/{id})

Com isso em ordem, siga para a Análise.