Skip to content

Face Match + Datavalid

Este endpoint faz duas coisas em uma chamada:

  1. Face Match — recebe duas imagens, localiza uma face em cada uma e compara as duas entre si, exatamente como o Face Match.
  2. Datavalid — envia uma dessas faces ao serviço Datavalid da SERPRO e pergunta se ela corresponde à biometria oficial registrada para o CPF informado na URL.

A diferença para o Face Match puro é a segunda etapa: aqui a face não é confrontada apenas com a outra imagem que você enviou, mas também com a base oficial do governo. É isso que permite responder "esta pessoa é mesmo o titular deste CPF", e não só "estas duas fotos são da mesma pessoa".

Este endpoint não faz liveness (use o Liveness) e não extrai os dados escritos no documento (para isso existe o OCR).

Request

POST /face-match-and-datavalid/v2/natural-person/{CPF}

Headers

http
Authorization: ApiKey <sua-chave-de-api>

Este endpoint também aceita o token JWT, no formato Authorization: Bearer <accessToken>. Veja Token JWT.

Chaves da SERPRO

A consulta ao Datavalid feita por este endpoint usa o nosso acesso à SERPRO. Você não precisa ter contrato próprio com a SERPRO para usá-lo, e ele não lê chaves de cliente da requisição: os headers x-customer-key e x-customer-secret, se enviados aqui, são ignorados.

TIP

O envio das próprias chaves da SERPRO é suportado no endpoint /full-ocr-and-datavalid, não neste. Se o seu contrato prevê o uso das suas chaves, fale com o nosso suporte antes de montar a integração por aqui.

Parâmetros

ParâmetroDescriçãoObrigatório
CPFCPF cuja biometria será consultada no Datavalid. Vai no caminho da URL, com ou sem máscara. É validado pelo dígito verificador.Sim
faceToDatavalidQual das faces enviar ao Datavalid: IdCard ou Selfie. Query string. Padrão: IdCard.Não
returnsFaceInfoQuando presente, cada item de resources passa a trazer o objeto face, e metadata.filesInfo[].data vem vazio. Query string. Padrão: desligado.Não

🚧 faceToDatavalid continua existindo, e é uma preferência, não uma garantia

A API classifica cada face encontrada em dois tipos, pelo tamanho que ela ocupa na imagem: faces grandes viram SELFIE, faces pequenas — típicas de foto impressa em documento — viram ID.

  • faceToDatavalid=IdCard (padrão): envia ao Datavalid a primeira face do tipo ID. Se não houver nenhuma, envia a face do tipo SELFIE.
  • faceToDatavalid=Selfie: envia a primeira face do tipo SELFIE. Se não houver nenhuma, envia a face do tipo ID.

Ou seja, a chamada ao Datavalid acontece de qualquer jeito, com a face disponível. Um valor fora de IdCard e Selfie faz a requisição falhar com 422.

‼️ returnsFaceInfo=false liga o parâmetro

Diferente do Face Match, aqui o valor do returnsFaceInfo não é interpretado: a simples presença do parâmetro na query string já o ativa, inclusive returnsFaceInfo=false. Para deixá-lo desligado, não envie o parâmetro.

Arquivos aceitos

ItemValor
Formatosimage/png, image/jpeg, application/pdf
Quantidade por chamada2 arquivos
Tamanho máximo (multipart)15 MB por arquivo

Os nomes dos campos do formulário são livres — eles voltam na resposta, em resources e em metadata.filesInfo. Enviar mais de dois arquivos é recusado com 422.

Em PDFs de várias páginas, cada página é analisada em ordem e a primeira com alguma face detectada é a que entra na análise.

Além do multipart/form-data, os arquivos podem ser enviados em JSON, no campo base64, como descrito em Envio de arquivos.

Exemplo Request

bash
curl -i -X POST 'https://api-homolog.nxcd.app/face-match-and-datavalid/v2/natural-person/12345678909' \
  --header 'Authorization: ApiKey SUA_CHAVE_AQUI' \
  --form 'documento=@./cnh.jpg' \
  --form 'selfie=@./selfie.jpg'

Escolhendo a selfie como face a validar no Datavalid:

bash
curl -i -X POST 'https://api-homolog.nxcd.app/face-match-and-datavalid/v2/natural-person/123.456.789-09?faceToDatavalid=Selfie' \
  --header 'Authorization: ApiKey SUA_CHAVE_AQUI' \
  --form 'documento=@./cnh.jpg' \
  --form 'selfie=@./selfie.jpg'

Response

CampoDescriçãoTipo
idIdentificador único da requisiçãoString
versionVersão da API que atendeu a chamadaString
dataLista com o resultado da análise. Traz uma entrada quando a comparação aconteceu, e vem vazia quando não.Object[]
data[].matchedtrue quando as duas faces enviadas são da mesma pessoa. É o resultado do face match, não do Datavalid.Boolean
data[].confidenceGrau de confiança da comparação entre as duas faces, de 0 a 100Number
data[].datavalidResultado da consulta ao Datavalid. Vem como {} quando não houve consulta.Object
data[].datavalid.federalRevenueNumberAvailabilityIndica se o CPF informado existe na base oficialBoolean
data[].datavalid.federalRevenueNumberStatusIndica se a situação cadastral do CPF na base oficial é regularBoolean
data[].datavalid.faceResultado da comparação da face enviada com a biometria oficial. Vem como {} quando não há biometria a comparar.Object
data[].datavalid.face.availabilityIndica se existe biometria facial registrada para aquele CPF na base oficialBoolean
data[].datavalid.face.similaritySimilaridade entre a face enviada e a biometria oficial, em uma escala de 0 a 1Number
data[].datavalid.face.probabilityFaixa de probabilidade de a face enviada ser a mesma da base oficial: VeryHigh, High, Low ou VeryLowString
data[].resourcesAs duas faces usadas na comparação, na ordem em que foram confrontadasObject[]
data[].resources[].fieldnameNome do campo em que aquele arquivo foi enviadoString
data[].resources[].pagePágina do arquivo em que a face foi encontrada. Começa em 0; para imagens é sempre 0.Number
data[].resources[].faceDados da face. Só aparece quando returnsFaceInfo é enviado.Object
data[].resources[].face.typeSELFIE ou ID, conforme a classificação descrita acimaString
data[].resources[].face.confidenceConfiança com que o detector localizou a faceNumber
data[].resources[].face.ageIdade aparente estimadaNumber
data[].resources[].face.genderObjeto com value (Male ou Female) e confidenceObject
data[].resources[].face.boundingBoxPosição da face na imagem, em proporções entre 0 e 1Object
data[].resources[].face.croppedBase64Recorte da face em base64String
metadataObjeto com os metadados da requisiçãoObject
metadata.filesInfoLista com uma entrada por arquivo enviado, mesmo os em que nenhuma face foi encontradaObject[]
metadata.filesInfo[].fieldnameNome do campo usado no envioString
metadata.filesInfo[].nameNome do arquivo enviadoString
metadata.filesInfo[].sizeTamanho do arquivo, em bytesNumber
metadata.filesInfo[].pagesNúmero de páginas do arquivo. Para imagens, 1.Number
metadata.filesInfo[].mimetypeTipo do arquivo enviadoString
metadata.filesInfo[].encodingCodificação do arquivo no envioString
metadata.filesInfo[].sha256Hash SHA-256 do arquivo enviadoString
metadata.filesInfo[].dataFaces encontradas naquele arquivo, cada uma com page e face (boundingBox e croppedBase64). Vem vazia quando returnsFaceInfo é enviado.Object[]
metadata.timeSpentTempo de processamento da requisição, em milissegundosNumber

🚧 matched e datavalid são respostas a perguntas diferentes

matched diz se as duas imagens que você enviou são da mesma pessoa. datavalid.face diz se a face escolhida bate com a biometria oficial do CPF.

Os dois podem discordar, e a consulta ao Datavalid é feita mesmo quando matched é false — a etapa não é condicionada ao resultado da comparação. Trate os dois campos como sinais independentes na sua decisão.

‼️ Sem duas faces, não há Datavalid

A análise só acontece quando dois arquivos têm alguma face detectada. Se um deles não tiver, a resposta é 200 com "data": [] — sem matched, sem confidence e sem nenhuma consulta ao Datavalid.

Verifique o tamanho de data antes de ler data[0].

Exemplos JSON

  1. Faces correspondentes e biometria confirmada no Datavalid
Status Code: 200
json
{
  "id": "13cfec7c-b238-4820-a4d1-5173e4c1418e",
  "version": "v2",
  "data": [
    {
      "matched": true,
      "confidence": 97.81,
      "datavalid": {
        "federalRevenueNumberAvailability": true,
        "federalRevenueNumberStatus": true,
        "face": {
          "availability": true,
          "similarity": 0.96,
          "probability": "VeryHigh"
        }
      },
      "resources": [
        { "fieldname": "documento", "page": 0 },
        { "fieldname": "selfie", "page": 0 }
      ]
    }
  ],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "documento",
        "name": "cnh.jpg",
        "size": 567098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6b0",
        "data": [
          {
            "page": 0,
            "face": {
              "boundingBox": { "top": 0.22, "left": 0.28, "width": 0.15, "height": 0.16 },
              "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
            }
          }
        ]
      },
      {
        "fieldname": "selfie",
        "name": "selfie.jpg",
        "size": 890098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6c4",
        "data": [
          {
            "page": 0,
            "face": {
              "boundingBox": { "top": 0.11, "left": 0.26, "width": 0.42, "height": 0.69 },
              "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...SuQmCC"
            }
          }
        ]
      }
    ],
    "timeSpent": 7340
  }
}
  1. Faces correspondentes, mas o CPF não tem biometria na base oficial
Status Code: 200
json
{
  "id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
  "version": "v2",
  "data": [
    {
      "matched": true,
      "confidence": 95.12,
      "datavalid": {
        "federalRevenueNumberAvailability": true,
        "federalRevenueNumberStatus": true,
        "face": {
          "availability": false
        }
      },
      "resources": [
        { "fieldname": "documento", "page": 0 },
        { "fieldname": "selfie", "page": 0 }
      ]
    }
  ],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "documento",
        "name": "cnh.jpg",
        "size": 567098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6b0",
        "data": [
          {
            "page": 0,
            "face": {
              "boundingBox": { "top": 0.22, "left": 0.28, "width": 0.15, "height": 0.16 },
              "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
            }
          }
        ]
      },
      {
        "fieldname": "selfie",
        "name": "selfie.jpg",
        "size": 890098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6c4",
        "data": [
          {
            "page": 0,
            "face": {
              "boundingBox": { "top": 0.11, "left": 0.26, "width": 0.42, "height": 0.69 },
              "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...SuQmCC"
            }
          }
        ]
      }
    ],
    "timeSpent": 6980
  }
}
  1. Nenhuma face encontrada em um dos arquivos
Status Code: 200
json
{
  "id": "a7f0c3d2-9e51-4b8a-8f31-2d4c6b9e0a77",
  "version": "v2",
  "data": [],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "documento",
        "name": "cnh.jpg",
        "size": 567098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6b0",
        "data": [
          {
            "page": 0,
            "face": {
              "boundingBox": { "top": 0.22, "left": 0.28, "width": 0.15, "height": 0.16 },
              "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
            }
          }
        ]
      },
      {
        "fieldname": "selfie",
        "name": "borrada.jpg",
        "size": 152064,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
        "data": []
      }
    ],
    "timeSpent": 3120
  }
}

Headers de resposta

HeaderQuando aparece
Nextid-ReqIdEm todas as respostas. Traz o identificador da requisição, o mesmo do campo id do corpo.

Erros

CódigoQuando ocorre
401 UnauthorizedChave de API ou token JWT ausente, inválido, ou sem permissão para este endpoint.
404 Not FoundA versão informada na URL não existe. Só a v2 é aceita.
406 Not AcceptableO corpo foi enviado como JSON, mas sem o campo base64.
413 Payload Too LargeUm dos arquivos enviados em multipart/form-data passa de 15 MB.
415 Unsupported Media TypeO header Content-Type está ausente ou não é suportado.
422 Unprocessable EntityCPF que não passa na validação do dígito verificador, faceToDatavalid fora do enum, formato de arquivo não aceito, ou mais de dois arquivos. Também é o código devolvido quando o Datavalid recusa a face por baixa qualidade da imagem.
500 Internal Server ErrorFalha inesperada durante o processamento, incluindo indisponibilidade do Datavalid.

Exemplo de resposta com CPF inválido:

Status Code: 422
json
{
  "id": "13cfec7c-b238-4820-a4d1-5173e4c1418e",
  "error": {
    "statusCode": 422,
    "error": "Unprocessable Entity",
    "message": "Invalid Federal Revenue Number"
  }
}

Exemplo de resposta quando o Datavalid recusa a face por qualidade:

Status Code: 422
json
{
  "id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
  "error": {
    "statusCode": 422,
    "error": "Unprocessable Entity",
    "message": "The face is of poor quality to be processed in the datavalid"
  }
}

TIP

Uma face recusada por qualidade derruba a requisição inteira com 422 — você não recebe o resultado do face match junto. Se precisa do face match mesmo quando o Datavalid não consegue avaliar a imagem, faça as duas chamadas separadamente, pelo Face Match.

O formato das respostas de erro está descrito em Códigos HTTP das respostas.

Versões

Este endpoint tem uma única versão, a v2. Ela é o padrão quando a versão é omitida na URL.

VersãoSituaçãoO que muda
v2RecomendadaÚnica versão. Atende tanto /face-match-and-datavalid/natural-person/{CPF} quanto /face-match-and-datavalid/v2/natural-person/{CPF}.

Qualquer outro valor na URL — /face-match-and-datavalid/v3/natural-person/{CPF}, por exemplo — devolve 404.

Nextcode | Soluções em Verificação de Identidade