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