Pular para o conteúdo principal

SDKs

A Veridia publica quatro SDKs. Três são clientes de servidor/API (JavaScript, Python, PHP). Um é uma UI de captura mobile (Flutter).

Todos os quatro estão na 0.1.0. A superfície da API é estável, mas trate a versão pelo que ela diz ser: pré-1.0.

Os quatro

SDKPacoteRegistroRequerO que é
JavaScript / TypeScript@veridia/sdknpmNode 18.17+ (ou um navegador)Cliente da API + verificação de webhook
PythonveridiaPyPIPython 3.11+Cliente da API (sync + async) + verificação de webhook
PHPveridia/veridia-phpComposerPHP 8.2+Cliente da API + verificação de webhook
Flutterveridia_sdkgit privadoDart 3.10.3+ / Flutter 3.38.4+UI de captura por câmera como um único widget

O nome do pacote para JavaScript é @veridia/sdk. Não @veridia/sdk-js.

Não existe SDK de React Native

Nunca existiu. Se você encontrou uma referência a @veridia/react-native ou uma entrada "React Native" em uma versão antiga desta barra lateral, ela apontava para um pacote que não existe em nenhum registro.

Para React Native hoje, suas opções são a API HTTP diretamente mais suas próprias telas de captura, ou uma WebView hospedando o widget web.

Qual deles eu preciso?

A etapa de captura e a etapa de resultado são trabalhos diferentes, e precisam de chaves diferentes.

Capturar imagens — acesso à câmera, checagens de qualidade, envio dos bytes. Isso roda onde o usuário está: o widget web em um navegador, ou o SDK Flutter em um app. Ambos usam uma chave publicável.

Ler o desfecho — isso roda no seu servidor, com uma chave secreta. Qualquer um dos três SDKs de servidor faz isso, e uma simples requisição HTTP também.

Os três SDKs de servidor também conseguem executar init e submit, que é o que você quer se captura as imagens com seu próprio código e só precisa de um cliente tipado para a API.

Tipos de chave, e qual SDK consegue ler um veredicto

PrefixoTipoOnde viveinit + submitLer veredictos
qv_pub_, qv_pubt_publicávelnavegador, app mobilesimnão
qv_sec_, qv_sect_secretasomente no seu servidorsimsim

As variantes com t são modo de teste. O prefixo de teste é qv_pubt_ / qv_sect_ — não qv_pub_test_.

GET /v1/verify/{id} recusa uma chave publicável com 401 secret_key_required. Isso é deliberado: uma chave publicável fica no código-fonte da página, onde qualquer pessoa pode lê-la, e um resultado de verificação carrega os campos de identidade extraídos. Uma chave publicável que pudesse ler resultados publicaria os desfechos de KYC de todos os seus clientes para todo visitante.

É por isso que o SDK Flutter aceita apenas uma publishableKey e não consegue buscar um veredicto. Embarcar uma chave secreta dentro do binário de um app não é uma alternativa — um APK é desempacotado em minutos, e a chave que ele entrega lê os veredictos de todos os clientes do seu tenant, não apenas o do dono do telefone.

SDKCaptura imagensFaz init / submitLê um veredicto
JavaScriptnãosimsim, com secretKey
Pythonnãosimsim, com uma chave qv_sec_*
PHPnãosimsim, com uma chave qv_sec_*
Fluttersimsimnão, por design

O fluxo que todo SDK encapsula

init → PUT de cada imagem → submit → webhook (ou polling)
  1. POST /v1/verify/init retorna um slot de upload por imagem (docFront, docBack, selfie), mais um expiresAt em segundos unix.
  2. PUT dos bytes para a URL de cada slot. Envie os headers do slot literalmente — veja abaixo.
  3. POST /v1/verify/submit com as keys da resposta do init. keys é obrigatório.
  4. O pipeline leva cerca de 15 segundos. O desfecho chega por webhook, ou você consulta GET /v1/verify/{id} com uma chave secreta.

Todo SDK expõe um helper que junta as keys para você — keysFrom (JS), keys_from (Python), VerifySubmitKeys::fromInit (PHP) — porque esquecê-las é a forma mais comum de tomar um 400 do submit.

Os uploads não vão para o R2

As URLs dos slots apontam para um endpoint da Veridia, não para armazenamento de objetos pré-assinado. Elas se autenticam com X-Veridia-Upload-Token, uma credencial de vida curta por verificação carregada dentro dos próprios headers do slot. Sua chave de API não autentica esse endpoint de forma alguma.

Duas consequências que vale conhecer antes de escrever qualquer código de upload à mão:

  • Repasse slot.headers literalmente. Reconstruir os headers você mesmo — ou enviar apenas Content-Type — descarta o token, e todo upload falha. Os quatro SDKs fazem isso corretamente.
  • Libere o host da API, não um host de armazenamento. Se você está escrevendo uma CSP ou uma regra de firewall de saída, os bytes vão para api.xxuxe.online.

O corpo precisa ser um JPEG de verdade (o endpoint checa o número mágico FF D8 FF) e ter no máximo 8 MB.

Você ainda pode ver "presigned R2 upload" no README de algum SDK ou em um comentário de código. Esse texto está desatualizado; o código nos quatro SDKs repassa os headers do slot e está correto.

status não é verdict

Dois eixos independentes, e confundi-los é o erro mais caro que esta API oferece.

CampoPergunta que respondeValores
statusO pipeline rodou?queued processing completed failed
verdictA pessoa passou?approved review rejected — ausente até completar

completed significa que o pipeline chegou a uma conclusão. Uma verificação aprovada, uma que exige revisão e uma rejeitada são todas completed. Ramificar por status para admitir um usuário admite todo candidato rejeitado.

Faça polling no status. Decida pelo verdict.

Duas armadilhas relacionadas: um veredicto nulo não é uma rejeição (significa que nenhuma decisão foi alcançada, seja porque ainda está rodando ou porque failed), e review é final — significa que um humano precisa olhar, não que o resultado ainda está se assentando. Fazer polling em um review esperando que ele se resolva espera para sempre.

metadata não sobrevive

POST /v1/verify/submit aceita um objeto metadata, mas ele é descartado na borda: não chega ao pipeline e não está presente no payload do webhook. Não o use para rotear nem reconciliar nada.

userRef, definido no init, é o campo que liga um evento de volta a um usuário no seu sistema. Ele é ecoado no webhook. Se você também precisa correlacionar no caminho de polling, guarde você mesmo o mapeamento verificationId → usuário: GET /v1/verify/{id} não retorna userRef.

Webhooks

Os quatro SDKs trazem verificação de assinatura HMAC-SHA256. Use-a — o desfecho de uma revisão humana pode chegar muito depois de o submit ter retornado, e o webhook é o único canal que o carrega.

Fatos que valem independentemente da linguagem:

  • O cabeçalho é Veridia-Signature: t=<unix>,v1=<hex>. Não existe X-Veridia-Signature nem um cabeçalho de timestamp separado — o timestamp fica dentro do valor da assinatura.
  • O MAC cobre os bytes "<t>." + rawBody. Verifique contra o corpo bruto. Reserializar o JSON muda o digest e a checagem falha.
  • O payload é planoverdict, verificationId, userRef no nível superior. Não existe envelope data.
  • O discriminador é type, não event.
  • Exatamente três tipos de evento: verification.approved, verification.review_required, verification.rejected. Não existe evento created nem expired para esperar.
  • A entrega é ao menos uma vez. Deduplique por id (evt_<hex>), que é estável entre retentativas.
  • A tolerância padrão de replay de 300 segundos está correta. Não a amplie — o dispatcher reassina a cada retentativa, então até a última retentativa chega com um t fresco.
  • fieldsExtracted carrega PII de identidade: nome completo, número do documento, data de nascimento. É por isso que o endpoint precisa ser https, e por que o payload não deve ser escrito literalmente nos logs da aplicação.

Detalhes completos na seção de webhooks.

Verificar um webhook é trabalho de servidor. O SDK Flutter expõe um WebhookVerifier, mas um app mobile não é destino de webhook — ele não tem URL estável e não pode guardar o segredo de assinatura.

Para onde ir agora