Inyo

Verificação Server-to-Server

Quando você já tem uma interface de captura — ou está verificando imagens coletadas anteriormente — envie-as diretamente e receba o resultado na própria resposta. Sem sessão, sem widget, sem link para o cliente.


Criar uma Verificação

Endpoint: POST /v1/verifications
Autenticação: token Bearer com o scope verifications
Content-Type: multipart/form-data

curl --request POST \
  --url https://{FQDN}/v1/verifications \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --header "Idempotency-Key: $(uuidgen)" \
  --form userRef=user-123 \
  --form [email protected] \
  --form [email protected] \
  --form [email protected]

Retorna 201 com o mesmo resultado normalizado que o widget produz.

Idempotency-Key é obrigatório

Toda chamada deve carregar um cabeçalho Idempotency-Key. Uma requisição sem ele é rejeitada com 422.

Este endpoint executa a extração do documento, a revisão de autenticidade, a triagem de sanções e as checagens faciais de forma síncrona, então uma única chamada pode levar vários segundos. Tempo suficiente para que um timeout do cliente seja um evento comum, não exótico — e uma nova tentativa cega executaria tudo isso de novo, e cobraria você por isso.

Use um valor que o seu próprio código consiga reproduzir para a mesma verificação lógica: um UUID que você gera e armazena, ou um identificador do seu sistema. Não o derive de algo que se repete, como apenas o userRef — duas verificações legítimas da mesma pessoa colidiriam, e a segunda retornaria o resultado da primeira.

SituaçãoResposta
Primeira chamada com uma chave201 com o resultado
Mesma chave, primeira chamada concluída201 com o resultado atual daquela verificação — não uma cópia congelada, então uma decisão de revisão posterior é refletida
Mesma chave, primeira chamada ainda em execução409 carregando o sessionId, para que você possa consultar GET /v1/sessions/{session_id} e obter o desfecho
Mesma chave, tenant diferenteSem relação — as chaves têm escopo do seu tenant

O 409 importa mais do que parece. Se a sua requisição sofreu timeout, você nunca recebeu um sessionId, então não tem como perguntar sobre o trabalho já em andamento. A resposta de conflito o devolve:

{
  "detail": {
    "code": "IDEMPOTENCY_KEY_IN_FLIGHT",
    "message": "A request with this Idempotency-Key is still being processed. Poll GET /v1/sessions/{sessionId} for the outcome.",
    "sessionId": "81e04c30-2620-42f1-a3e0-68aef1f84043"
  }
}

Portanto o comportamento correto em um timeout é: repita a mesma chamada com a mesma chave. Você receberá o resultado ou um 409 dizendo onde olhar. Nunca repita com uma chave nova — isso inicia uma segunda verificação cobrada da mesma pessoa.

POST /v1/sessions não aceita Idempotency-Key. Sua resposta contém um link de widget de uso único que não pode ser reemitido, então uma nova tentativa ali cria uma nova sessão; uma duplicata custa um link não utilizado, não uma verificação repetida.

Campos do Formulário

CampoTipoObrigatórioDescrição
userReftextoSimSeu identificador para a pessoa sendo verificada
frontImagearquivoSimFrente do documento — a página da foto de um passaporte, a frente de um cartão
backImagearquivoNãoVerso do documento. Para carteiras de motorista e identidades estaduais dos EUA, contém o código de barras
selfieImagearquivoNãoOmita para executar apenas as verificações de documento — veja Verificação apenas de documento
dataChecktextoNãotrue compara os dados extraídos com o prefill
prefilltextoNãoUma string JSON com o mesmo schema do prefill de sessão

Observe que aqui o prefill é uma string JSON dentro de um campo multipart, não um objeto aninhado:

  --form 'prefill={"firstName":"Ana","lastName":"Silva","dateOfBirth":"1988-03-04"}' \
  --form dataCheck=true

Envie o Verso do Cartão

Nas carteiras de motorista e identidades estaduais dos EUA, o verso contém um código de barras PDF417 que codifica os dados do titular. A Inyo o decodifica no recebimento e, como o código de barras é autoverificável — a simbologia carrega sua própria correção de erros — ele prevalece sobre o OCR da zona visual para os campos que contém. A decodificação é independente de rotação, portanto um verso de cabeça para baixo ainda é lido.

Um verso ausente, ilegível ou sem código de barras é um no-op silencioso: os valores do OCR permanecem e nenhuma verificação muda. Não há desvantagem em enviá-lo, e há um ganho mensurável de precisão quando ele é decodificado. Os passaportes trazem uma zona de leitura mecânica na página da foto, de modo que frontImage sozinho é suficiente para eles.


Verificação Apenas de Documento

Omita selfieImage para verificar o documento sem biometria. As verificações de documento são executadas — legibilidade, formato, validade, autenticidade, jurisdição — e nenhuma verificação facial aparece em checks[].

Uma consequência a considerar: uma verificação apenas de documento não possui pontuação biométrica. Se você tiver um limiar de revisão configurado, não há nada para ser comparado, e uma verificação não medida é tratada como não medida, não confiável — portanto é encaminhada para in_review em vez de ser aprovada automaticamente. Envie uma selfie, ou deixe o limiar de revisão sem configurar, se precisar que verificações apenas de documento sejam decididas de forma síncrona.


in_review Não É uma Resposta Final

POST /v1/verifications retorna o resultado de forma síncrona, mas uma resposta 201 não garante uma decisão terminal. O status pode ser in_review, o que significa que um analista ainda vai decidir.

Isso acontece quando você configurou um limiar de revisão, ou quando rejeições retidas estão habilitadas e as verificações rejeitaram o documento. Sem nenhuma das duas configurações, toda verificação retorna decidida.

Quando isso acontece:

CanalComportamento
WebhookCom um webhookUrl configurado, o resultado decidido é enviado via POST como qualquer outro resultado — veja Notificações de resultado
PollingGET /v1/sessions/{sessionId} retorna o status e o result atuais, atualizados no próprio recurso, com result.manualReview indicando quem decidiu e por quê

Use o sessionId do corpo da resposta como identificador para ambos. Nenhum webhook é enviado para a resposta síncrona original — o 201 já a entregou. Veja Revisão Manual para o quadro completo.


Respostas de Erro

StatusCausaComo tratar
401 / 403Token ausente ou inválido, ou token sem o scope verificationsVeja Autenticação
422prefill não é um JSON válido ou viola o schema de prefill (incluindo o formato do número de documento)Corrija o payload — o detail indica o problema
422dataCheck=true sem prefillForneça um payload de prefill para comparação
502O serviço de verificação estava indisponívelTransitório — tente novamente. Trata-se de falha de infraestrutura, não de uma recusa. Não trate como um resultado negativo para o cliente

Widget ou Server-to-Server?

Os dois pontos de entrada compartilham o mesmo pipeline e o mesmo formato de resultado, e seus limiares, roteamento de revisão, jurisdições aceitas e opções de enriquecimento se aplicam de forma idêntica. Duas configurações são, por natureza, de nível de sessão e não têm efeito aqui: os tipos de documento permitidos e o travamento de prefill.documentType restringem o que o widget oferece ao cliente, portanto, neste endpoint, o tipo de documento é simplesmente o que as imagens revelarem ser.

As diferenças que importam:

Widget hospedadoServer-to-server
Qualidade da capturaGuiada, com enquadramento ao vivo e feedback de reflexoSob seu controle
Captura com falhaO cliente é orientado e tenta novamenteRetorna um resultado; tentar novamente é decisão sua
Entrega do resultadoWebhook ou redirecionamento assinadoO corpo da resposta, mais alterações posteriores via webhook
Defesa contra ataques de apresentaçãoMesmas verificaçõesMesmas verificações, mas sem contexto de captura ao vivo para se apoiar
Evidência de conformidadeA Inyo retém a captura guiada e o vídeo opcional da selfieApenas as imagens que você envia

A diferença de retentativa diz respeito a orientar um cliente ao vivo — ela não muda o que sua configuração significa nem como a decisão é tomada.


Próximos Passos