Finger Contactless: onboarding e autenticação
O fluxo de finger permite validar a identidade de uma pessoa e cadastrar sua biometria no onboarding, para depois realizar a autenticação com uma nova captura de impressão digital.
| Etapa | Requisição | Finalidade |
|---|---|---|
| Gerar o token da aplicação | POST /api/v1/app-credentials/token | Trocar a key e o secret pelo token de acesso. |
| Onboarding | POST /api/v1/services/biometric/onboarding | Validar a identidade pelo CPF e cadastrar a biometria, conforme a configuração do contrato da aplicação. |
| Autenticação | POST /api/v1/services/biometric/authenticate | Comparar uma nova captura com o cadastro do CPF (1:1) ou identificar na galeria biométrica (1:N). |
Teste local
Este roteiro reproduz as chamadas HTTP do app de exemplo: gerar o token, fazer o onboarding e autenticar com uma nova captura. O Postman roda no seu computador e chama o ambiente da API escolhido; ele não captura digitais nem executa o SDK de captura.
Preparação
Você precisa das credenciais de uma aplicação da API Online, de um contrato biométrico ativo vinculado a ela e das imagens de digitais de uma pessoa cujo CPF possa ser validado no provedor configurado. Para completar onboarding seguido de autenticação, o contrato também precisa habilitar o armazenamento e configurar o provedor de comparação.
Use a mesma aplicação, o mesmo ambiente e o mesmo contrato durante o teste. Um cadastro feito em outro ambiente ou aplicação não fica automaticamente disponível na comparação 1:1. As credenciais dos provedores são configuradas no contrato pela equipe responsável pelo ambiente.
Baixe e importe a coleção Postman — Finger. Ela contém geração de token, onboarding, autenticação 1:1 e identificação 1:N. Abra as variáveis da coleção e preencha os valores usados localmente:
| Variável | Valor |
|---|---|
base_url | URL fornecida para seu ambiente, sem barra final e sem /api/v1. O app de exemplo está configurado para https://api-staging.techtrue.com.br. Use esse endereço somente com credenciais e contrato habilitados nesse ambiente. |
key / secret | Credenciais da aplicação nesse ambiente. |
token | Preenchido automaticamente pela requisição de geração de token. |
cpf | CPF da pessoa capturada, com 11 dígitos. |
onboarding_collection_id / authentication_collection_id / identification_collection_id | Preencha com um identificador único por coleta (por exemplo, um UUID). Mantenha-o para reenvios da mesma coleta e substitua-o antes de uma nova coleta ou comparação. |
Os dados pessoais, as imagens e as credenciais devem ser preenchidos somente na sua cópia local da coleção e do ambiente. Os arquivos para download não contêm esses dados.
Em cada requisição biométrica, abra Body → raw → JSON. O array fingers já está no corpo, com a estrutura abaixo para um indicador esquerdo. O campo image referencia a variável de ambiente da respectiva captura; ajuste position conforme o dedo capturado. O campo nfiq2 começa em 55, como valor de exemplo; substitua-o pela qualidade real retornada pelo SDK quando disponível. Acrescente objetos ao array para enviar mais dedos. Este fragmento mostra apenas fingers; mantenha os demais campos que já estão no body:
{ "fingers": [ { "position": 7, "nfiq2": 55, "image": "{{finger_image_onboarding}}" } ]}Preencha as variáveis de ambiente com o Base64 real, sem aspas adicionais nem prefixo data:image/png;base64,, e mantenha as referências {{finger_image_onboarding}} e {{finger_image_authentication}} no body. Se usar mais dedos, acrescente um objeto por dedo e crie uma variável de imagem para cada dedo, preservando a posição e a qualidade correspondentes. Não use o nome de um arquivo nem uma foto da mão inteira no campo image.
Executar o fluxo
- Envie 01 — Gerar token. O script salva o campo
tokenda resposta na coleção. As outras chamadas usam esse valor em Authorization → Bearer Token. - Envie 02 — Onboarding com o CPF e a primeira captura. Confira
status: "APPROVED"etemplateStatus: "STORED"ou"ALREADY_EXISTS"antes de seguir. Se já existir cadastro, a nova captura não substitui automaticamente as digitais cadastradas. - Faça uma nova captura dos dedos cadastrados, atualize
finger_image_authenticationno ambiente selecionado e envie 03 — Autenticação 1:1. A coleção envia o mesmo CPF commode: "ONE_TO_ONE". ConfiraresultCode,statusedecision. - Opcionalmente, envie 04 — Identificação 1:N, que usa a imagem de
finger_image_authenticationdo ambiente selecionado. Essa chamada usamode: "ONE_TO_N"e omite o CPF, buscando na galeria configurada para o provedor de comparação.
Execute as etapas manualmente, conferindo cada resposta. Os testes da coleção verificam o formato do retorno e exibem status, resultCode e decision; passar nesses testes não significa aprovação biométrica.
Para repetir exatamente uma requisição, mantenha os dados e seu identificador. Para testar uma nova captura, outro CPF ou outra comparação, atualize os dados e substitua o identificador correspondente por um novo valor. O identificador é preenchido manualmente nas variáveis da coleção, permitindo testar também a duplicidade.
Se montar as chamadas manualmente, use Body → raw → JSON e os corpos das seções seguintes. Todos os valores entre {{ e }} devem estar definidos no Postman; ao executar cURL no terminal, substitua-os pelos valores reais.
Autenticação das rotas
As duas rotas da API Online exigem o token da aplicação gerado com a key e o secret, conforme explicado em Autenticação — Gerar um token.
curl --request POST '{{base_url}}/api/v1/app-credentials/token' \ --header 'Content-Type: application/json' \ --data '{"key": "{{key}}", "secret": "{{secret}}"}'Resposta esperada:
{ "token": "{{token}}"}Use o valor de token no cabeçalho de todas as chamadas de onboarding e autenticação:
Authorization: Bearer {{token}}Content-Type: application/jsonUse o token da aplicação Online desse ambiente; o token de login do dashboard e o token de uma aplicação on-premise não são intercambiáveis com ele. No app de exemplo, o token é informado nas configurações; o fluxo de captura não gera esse token automaticamente.
A rota /biometric/authenticate realiza a comparação biométrica; ela não gera o token de acesso. A key e o secret são enviados à rota de geração do token, e não no corpo das requisições biométricas.
A aplicação identificada pelo token precisa ter um contrato biométrico ativo configurado. O contrato define os provedores, o armazenamento e o limiar de comparação. Não envie contractId: a API resolve esse vínculo pela credencial autenticada e rejeita o envio de um valor para esse campo.
Dados da captura
O app configura o SDK AirSnap para retornar uma imagem PNG por dedo segmentado. Ele usa os bytes de primaryImage (com fallback para displayImage quando necessário), converte para Base64 sem quebras de linha e envia cada dedo em fingers. A captura padrão é dos quatro dedos da mão esquerda, posições 7 a 10; o usuário pode selecionar outros modos de captura.
Para reproduzir esse envio, utilize imagens individuais produzidas pela captura, com as posições corretas. Não envie a imagem da mão inteira, caminho de arquivo, URL, prefixo de Data URL ou Base64 de um template no campo image.
Envie o corpo em JSON, com pelo menos um dedo. Este fragmento mostra apenas fingers; os corpos completos estão nas seções de cada rota:
{ "fingers": [ { "position": 7, "nfiq2": 55, "image": "{{finger_image_onboarding}}" } ]}| Campo | Tipo | Obrigatório | O que enviar |
|---|---|---|---|
collectionId | string | Sim, nas duas rotas | Identificador da coleta, não vazio, com até 128 caracteres. Use um novo identificador para cada nova coleta. |
fingers | array de objetos | No fluxo com imagens | Pelo menos um objeto com position e image. Não envie uma lista vazia. |
fingers[].position | integer | Sim, em cada dedo | Posição do dedo na tabela NIST, de 1 a 10. |
fingers[].image | string | Sim, em cada dedo | Imagem individual da impressão digital codificada em Base64, não vazia. Para reproduzir o app, use o PNG retornado pelo SDK, sem prefixo e sem quebras de linha. |
fingers[].nfiq2 | integer | Não | O app envia a qualidade nist2Quality retornada pelo SDK. Esse campo adicional não é declarado nem validado pelo DTO atual da API; não é requisito para chamar as rotas nem garantia de aprovação. Se não tiver esse valor da captura, omita-o. |
template | string | Se fingers não for enviado | Template biométrico gerado pelo SDK, não vazio e compatível com o provedor configurado. |
templateFormat | string | Se fingers não for enviado | Identificador do formato/provedor do template, não vazio, com até 32 caracteres. Exemplo: TECH5. |
metadata | object | Não | Metadados opcionais da integração, como canal, dispositivo e versão do SDK. |
Posições dos dedos
position | Dedo | position | Dedo |
|---|---|---|---|
| 1 | Polegar direito | 6 | Polegar esquerdo |
| 2 | Indicador direito | 7 | Indicador esquerdo |
| 3 | Médio direito | 8 | Médio esquerdo |
| 4 | Anelar direito | 9 | Anelar esquerdo |
| 5 | Mínimo direito | 10 | Mínimo esquerdo |
O mínimo de um dedo é a validação estrutural da API. A aprovação também depende das imagens, da disponibilidade de referência no provedor e das regras do contrato. Para a autenticação 1:1, recapture dedos presentes no cadastro.
Qualidade e liveness no app
Além da imagem, o app envia nfiq2 por dedo. A configuração atual pede ao SDK o cálculo dessa qualidade. O campo não deve ser confundido com score da comparação ou threshold do contrato.
Quando o liveness está habilitado no app, ele avalia os scores retornados pelo SDK antes de liberar o envio. Scores ausentes ou abaixo do limiar configurado bloqueiam o botão de envio. O corpo HTTP não envia esses scores nem um campo de aprovação de liveness. Portanto, um teste no Postman valida a integração com a API e a resposta biométrica, mas não reproduz essa verificação local da captura.
Os exemplos usam marcadores para substituição. Envie a imagem ou o template completo produzido pela captura; os marcadores não são dados biométricos válidos.
Onboarding de finger
POST /api/v1/services/biometric/onboarding
O onboarding valida a identidade no provedor configurado usando o CPF e as digitais. Quando a validação é aprovada e o contrato habilita o armazenamento, o fluxo cadastra a biometria para comparações posteriores. Se já houver cadastro ativo, a resposta informa essa condição.
Além dos dados da captura, esta rota aceita:
| Campo | Tipo | Obrigatório | O que enviar |
|---|---|---|---|
cpf | string | Sim | CPF com 11 dígitos, com ou sem a máscara 000.000.000-00. |
personExternalId | string | Não | Identificador externo opcional da pessoa, com até 128 caracteres. O cadastro usado na comparação 1:1 é localizado pelo CPF. |
Exemplo de requisição
Exemplo com um indicador esquerdo. O app envia um objeto para cada dedo capturado e inclui também nfiq2 em cada objeto. metadata e personExternalId são opcionais da API e não são enviados pelo app nesse fluxo.
curl --request POST '{{base_url}}/api/v1/services/biometric/onboarding' \ --header 'Authorization: Bearer {{token}}' \ --header 'Content-Type: application/json' \ --data '{ "cpf": "{{cpf}}", "collectionId": "onboarding-coleta-001", "fingers": [ { "position": 7, "nfiq2": 55, "image": "{{finger_image_onboarding}}" } ] }'Exemplo de resposta aprovada — HTTP 200
Exemplo ilustrativo com validação de identidade e armazenamento concluídos. Os identificadores, provedores e códigos técnicos variam conforme a configuração e o resultado da operação.
{ "transactionId": "5c9faac7-706c-4de6-8af5-f5ec895ee42f", "collectionId": "onboarding-coleta-001", "flow": "ONBOARDING", "status": "APPROVED", "resultCode": "ONBOARDING_APPROVED", "message": "Onboarding approved.", "decision": "MATCH", "biometricAlreadyRegistered": false, "billingStatus": "REGISTERED", "templateStatus": "STORED", "provider": "VALID_ID_CHECK", "providerRawStatus": "VALID_ID_CHECK_MATCH", "matcherProvider": "TECH5_OMNIMATCH", "matcherRawStatus": "TECH5_ENROLL_OK", "createdAt": "2026-09-11T12:00:00.000Z"}Antes de seguir para a autenticação 1:1, confira templateStatus: STORED indica armazenamento e ALREADY_EXISTS indica cadastro existente. Uma identidade aprovada com templateStatus: "NOT_STORED" não confirma que houve cadastro para autenticação. Se o cadastro falhar, o retorno será PENDING com TEMPLATE_REGISTRATION_FAILED, mesmo que decision seja MATCH.
Autenticação de finger
POST /api/v1/services/biometric/authenticate
Envie uma nova captura e um novo collectionId. O modo padrão é ONE_TO_ONE: a API busca o cadastro ativo do CPF no contexto da aplicação e do contrato e compara a captura com esse cadastro.
Além dos dados da captura, esta rota aceita:
| Campo | Tipo | Obrigatório | O que enviar |
|---|---|---|---|
mode | string | Não | ONE_TO_ONE (padrão) ou ONE_TO_N. |
cpf | string | Em ONE_TO_ONE, inclusive quando mode é omitido | CPF do cadastro, com 11 dígitos, com ou sem máscara. Em ONE_TO_N, pode ser omitido. |
transactionContext | string | Não | Contexto opcional da transação, com até 128 caracteres. |
operationType | string | Não | Tipo opcional de operação, com até 64 caracteres. |
Exemplo de requisição 1:1
curl --request POST '{{base_url}}/api/v1/services/biometric/authenticate' \ --header 'Authorization: Bearer {{token}}' \ --header 'Content-Type: application/json' \ --data '{ "cpf": "{{cpf}}", "mode": "ONE_TO_ONE", "collectionId": "autenticacao-coleta-002", "fingers": [ { "position": 7, "nfiq2": 55, "image": "{{finger_image_authentication}}" } ] }'Alternativa por template
O app deste roteiro envia imagens em fingers, não template. Use a alternativa abaixo somente se sua integração já produzir um template compatível e o provedor configurado suportar esse envio. templateFormat: "TECH5" é um identificador, não converte PNG, WSQ ou outro arquivo em template. Para testar o mesmo fluxo do app, mantenha os exemplos com imagens.
Exemplo de corpo para a mesma rota:
{ "cpf": "{{cpf}}", "mode": "ONE_TO_ONE", "collectionId": "autenticacao-coleta-003", "template": "{{template_gerado_pelo_sdk}}", "templateFormat": "TECH5"}Exemplo de resposta aprovada — HTTP 200
Os valores de score e threshold abaixo são ilustrativos; o limiar vem do contrato, e a escala do score depende do provedor.
{ "transactionId": "c5a95adc-8e34-4eaf-85ee-a27c01b276d1", "collectionId": "autenticacao-coleta-002", "flow": "AUTHENTICATION", "authenticationMode": "ONE_TO_ONE", "status": "APPROVED", "resultCode": "AUTHENTICATION_APPROVED", "message": "Authentication approved.", "decision": "MATCH", "score": 0.92, "threshold": 0.85, "billingStatus": "REGISTERED", "provider": "TECH5_OMNIMATCH", "providerRawStatus": "TECH5_MATCH_OK", "createdAt": "2026-09-11T12:05:00.000Z"}Identificação 1:N
Para buscar uma correspondência na galeria do provedor de comparação configurado, envie mode: "ONE_TO_N". Esse modo dispensa o CPF e requer suporte à identificação no contrato.
curl --request POST '{{base_url}}/api/v1/services/biometric/authenticate' \ --header 'Authorization: Bearer {{token}}' \ --header 'Content-Type: application/json' \ --data '{ "mode": "ONE_TO_N", "collectionId": "identificacao-coleta-004", "fingers": [ { "position": 7, "nfiq2": 55, "image": "{{finger_image_authentication}}" } ] }'A busca usa a galeria do provedor configurado no contrato; ela não consulta a base de validação de CPF do onboarding.
Uma identificação aprovada retorna authenticationMode: "ONE_TO_N", status: "APPROVED", resultCode: "IDENTIFICATION_APPROVED" e decision: "MATCH". Quando disponível, providerExternalId contém o identificador do candidato selecionado no provedor; ele não é o CPF. A resposta pública não inclui uma lista de candidatos.
Como interpretar as respostas
HTTP 200 não significa, por si só, aprovação biométrica. O app considera sucesso HTTP 2xx acompanhado de status: "APPROVED". Confira status, resultCode e decision no JSON. Use resultCode para tratar o resultado na integração; message é uma descrição legível.
resultCode | status esperado | Significado |
|---|---|---|
ONBOARDING_APPROVED | APPROVED | Identidade aprovada; consulte templateStatus para saber se houve armazenamento. |
BIOMETRIC_ALREADY_REGISTERED | APPROVED | Identidade aprovada e cadastro biométrico já existente. |
AUTHENTICATION_APPROVED | APPROVED | Comparação 1:1 aprovada. |
IDENTIFICATION_APPROVED | APPROVED | Identificação 1:N aprovada. |
BIOMETRIC_NO_MATCH | REJECTED | Biometria sem correspondência (NO_MATCH). |
BIOMETRIC_NOT_FOUND | REJECTED | Biometria não encontrada pelo provedor (NOT_FOUND). |
BIOMETRIC_NOT_ENROLLED | REJECTED | Nenhum cadastro ativo encontrado para o CPF na autenticação 1:1 (NOT_FOUND). |
PROVIDER_UNAVAILABLE | PENDING | Provedor indisponível ou com erro; consulte os campos de erro. |
TEMPLATE_REGISTRATION_FAILED | PENDING | Validação de identidade aprovada, mas cadastro biométrico pendente ou com falha. |
DUPLICATE_COLLECTION | Conforme a decisão armazenada, ou PENDING | Coleta já recebida; nenhuma nova validação ou comparação é executada. |
Campos de retorno
Campos opcionais podem não aparecer no JSON, conforme o fluxo e as informações disponíveis.
| Campo | Tipo | Descrição |
|---|---|---|
transactionId | string | Identificador da transação para rastreamento. |
collectionId | string | Identificador de coleta enviado na requisição. |
flow | string | ONBOARDING ou AUTHENTICATION. |
authenticationMode | string | Modo usado na autenticação: ONE_TO_ONE ou ONE_TO_N. |
status | string | Resultado do fluxo: APPROVED, REJECTED ou PENDING. |
resultCode / message | string | Código do resultado e sua descrição. |
decision | string | Decisão biométrica, como MATCH, NO_MATCH, NOT_FOUND ou UNAVAILABLE. |
score / threshold | number | Score retornado pela comparação, quando disponível, e limiar configurado. |
biometricAlreadyRegistered | boolean | No onboarding, indica se o cadastro já existia. |
templateStatus | string | No onboarding: STORED, ALREADY_EXISTS, NOT_STORED ou FAILED. |
billingStatus | string | Estado do registro de cobrança: REGISTERED ou SKIPPED_DUPLICATE nos retornos usuais. Não indica aprovação biométrica. |
provider / providerRawStatus | string | Provedor e código técnico da validação de identidade ou comparação. |
providerExternalId | string | Identificador externo retornado pelo provedor, quando disponível. |
matcherProvider / matcherRawStatus / matcherExternalId | string | Dados do provedor de cadastro biométrico, quando disponíveis no onboarding. |
errorSource | string | Origem do erro: IDENTITY_PROVIDER, TECH5 ou FIDUCIA_API. |
errorCode / errorMessage | string | Código técnico e descrição do erro, quando aplicável. |
createdAt | string | Data/hora da transação no formato ISO 8601. |
Exemplo de autenticação sem cadastro — HTTP 200
{ "transactionId": "b231bf42-003b-4d1b-9a1a-c7569ed38ce8", "collectionId": "autenticacao-coleta-005", "flow": "AUTHENTICATION", "authenticationMode": "ONE_TO_ONE", "status": "REJECTED", "resultCode": "BIOMETRIC_NOT_ENROLLED", "message": "No active biometric enrollment was found for this person.", "decision": "NOT_FOUND", "threshold": 0.85, "billingStatus": "REGISTERED", "provider": "TECH5_OMNIMATCH", "providerRawStatus": "BIOMETRIC_ENROLLMENT_NOT_FOUND", "createdAt": "2026-09-11T12:10:00.000Z"}Reenvios e duplicidade
A API identifica duplicidade pela combinação de collectionId, aplicação e fluxo (ONBOARDING ou AUTHENTICATION). Ao reenviar a mesma coleta, mantenha seu identificador. Para uma nova captura ou uma nova comparação, inclusive ao mudar o modo de autenticação, gere outro collectionId.
Uma duplicata retorna resultCode: "DUPLICATE_COLLECTION" e billingStatus: "SKIPPED_DUPLICATE", com os dados armazenados da coleta. Esse retorno não reproduz necessariamente todos os campos da primeira resposta: por exemplo, pode não incluir score, threshold ou templateStatus. O status é calculado a partir da decisão armazenada; não interprete a duplicidade como uma nova aprovação ou confirmação de armazenamento.
Erros HTTP
| HTTP | O que esperar |
|---|---|
200 | Fluxo processado, inclusive recusa, indisponibilidade do provedor ou duplicidade. Leia o resultado no corpo. |
400 | Corpo inválido, campo obrigatório ausente ou configuração inválida/ausente do contrato ou provedor. |
401 | Token ausente, inválido ou expirado. Gere um token válido com a key e o secret e envie Authorization: Bearer {{token}}. |
500 | Erro interno da API. |
Na geração de token, credenciais inválidas podem retornar HTTP 400 com Invalid credential. Isso é diferente do HTTP 401 ao chamar as rotas biométricas com token ausente ou inválido.
Erros capturados durante a execução do fluxo usam resultCode: "API_ERROR". Exemplo de HTTP 400 para uma aplicação sem contrato biométrico:
{ "statusCode": 400, "resultCode": "API_ERROR", "errorSource": "FIDUCIA_API", "errorCode": "FIDUCIA_API_REQUEST_ERROR", "errorMessage": "Biometric contract not configured for app", "message": "Biometric contract not configured for app"}Erros de autenticação e de validação do corpo ocorrem antes da execução do fluxo e podem usar o formato padrão abaixo, sem resultCode. Em erros de validação, message pode ser uma lista de mensagens.
{ "statusCode": 401, "message": "Unauthorized", "error": "Unauthorized"}