Face Validation
Este endpoint responde a uma única pergunta: a face da imagem enviada corresponde à biometria oficial registrada para o CPF informado na URL?
Você envia uma imagem e um CPF. A API localiza a face na imagem, recorta, e a confronta com a base oficial. A resposta é um veredito enxuto — sem comparação entre duas fotos suas, sem dados cadastrais e sem extração de documento.
Este endpoint não compara duas imagens entre si (para isso existe o Face Match), não faz liveness (use o Liveness), não extrai os dados escritos no documento e não devolve os dados cadastrais do CPF (use o Bureau PF).
Face Validation ou Face Match + Datavalid
Os dois endpoints validam uma face contra a base oficial a partir de um CPF. A diferença está no que mais eles fazem, e no formato do veredito.
| Face Validation | Face Match + Datavalid | |
|---|---|---|
| Rota | /face-validation/v1/natural-person/{CPF} | /face-match-and-datavalid/v2/natural-person/{CPF} |
| Arquivos por chamada | 1 imagem | 2 arquivos |
| Compara as suas imagens entre si | Não | Sim, devolve matched e confidence |
| Valida contra a base oficial | Sim | Sim |
| Formatos aceitos | image/png, image/jpeg | image/png, image/jpeg, application/pdf |
Envio por JSON (base64) | Aceita | Aceita |
Campo similarity | Não devolve | Devolve |
| Faixa de probabilidade | VeryHigh, High, Low, VeryLow, Unknown | VeryHigh, High, Low, VeryLow |
| Dados cadastrais do CPF | Não devolve | Devolve federalRevenueNumberStatus |
Formato de data | Objeto | Lista |
| Permissão | nextid.bureaus.faceValidation | nextid.bureaus.faceMatchAndDatavalid |
Use o Face Validation quando você tem só uma imagem — uma selfie, por exemplo — e precisa apenas saber se ela é do titular do CPF. Use o Face Match + Datavalid quando você também precisa confrontar duas imagens suas entre si, ou quando precisa da situação cadastral do CPF na mesma chamada.
Request
POST/face-validation/v1/natural-person/{CPF}Headers
Authorization: ApiKey <sua-chave-de-api>Este endpoint também aceita o token JWT, no formato Authorization: Bearer <accessToken>. Veja Token JWT.
A chamada exige a permissão nextid.bureaus.faceValidation. Ela é uma permissão própria: quem chama o Face Match + Datavalid normalmente não passa a ter acesso a este endpoint por isso.
Parâmetros
| Parâmetro | Descrição | Obrigatório |
|---|---|---|
| CPF | CPF cuja biometria será consultada. Vai no caminho da URL, com ou sem máscara. É validado pelo dígito verificador antes de qualquer consulta. | Sim |
| returnsFaceInfo | Quando true, o objeto face da resposta ganha boundingBox e croppedBase64. Query string. Padrão: false. | Não |
O CPF pode ser enviado com ou sem máscara (123.456.789-09 ou 12345678909), sempre com os 11 dígitos, incluindo os zeros à esquerda.
🚧 A query string deste endpoint é estrita
Diferente de outros endpoints, aqui a query string é validada:
returnsFaceInfoaceita apenastrueoufalse. Qualquer outra codificação —1,0,TRUE,sim— é recusada com422, e não silenciosamente ignorada.- Um parâmetro desconhecido derruba a requisição.
?returnsFaceInfoo=true, com o erro de digitação, devolve422em vez de processar a chamada sem a face info.
Isso é intencional: um parâmetro escrito errado falha alto, em vez de devolver 200 com uma resposta que não é a que você pediu.
Arquivos aceitos
| Item | Valor |
|---|---|
| Formatos | image/png, image/jpeg |
| Quantidade por chamada | 1 arquivo |
| Formas de envio | multipart/form-data ou base64 em JSON |
| Tamanho máximo (multipart) | 15 MB |
A imagem pode ser enviada como multipart/form-data ou em base64, no campo base64 do corpo JSON, como descrito em Envio de arquivos. As duas formas se comportam igual: os mesmos formatos, o mesmo limite de um arquivo por chamada e as mesmas recusas.
O nome do campo — o do formulário no multipart, ou a chave dentro de base64 no JSON — é livre, e volta na resposta em metadata.filesInfo. Enviar mais de um arquivo é recusado com 422, e não enviar nenhum também.
‼️ O campo urls não é aceito neste endpoint
O envio do arquivo por URL não é aceito aqui. Um corpo JSON com o campo urls é recusado com 422, antes de o arquivo ser buscado:
{
"id": "e2b0f3a7-5c41-4c2b-9d33-8a5f1c7e4b02",
"error": {
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "Sending files by URL is not supported. Use multipart/form-data or the \"base64\" field."
}
}Só PNG e JPEG, nas duas formas de envio. Qualquer outro mimetype — PDF incluído — devolve 422, e o mesmo vale para um envio com mais de um arquivo.
Se a imagem tiver mais de uma face, a de maior confiança é a usada na validação. Se nenhuma face for detectada, a requisição falha com 422 — a consulta à base oficial não chega a acontecer.
Exemplo Request
curl -i -X POST 'https://api-homolog.nxcd.app/face-validation/v1/natural-person/12345678909' \
--header 'Authorization: ApiKey SUA_CHAVE_AQUI' \
--form 'selfie=@./selfie.jpg'Pedindo também o recorte da face encontrada:
curl -i -X POST 'https://api-homolog.nxcd.app/face-validation/v1/natural-person/123.456.789-09?returnsFaceInfo=true' \
--header 'Authorization: ApiKey SUA_CHAVE_AQUI' \
--form 'selfie=@./selfie.jpg'A mesma chamada, com a imagem em base64:
curl -i -X POST 'https://api-homolog.nxcd.app/face-validation/v1/natural-person/12345678909' \
--header 'Authorization: ApiKey SUA_CHAVE_AQUI' \
--header 'Content-Type: application/json' \
--data '{ "base64": { "selfie": "BASE_64_AQUI" } }'Response
| Campo | Descrição | Tipo |
|---|---|---|
| id | Identificador único da requisição | String |
| version | Versão da API que atendeu a chamada | String |
| data | Objeto com o resultado da validação. Não é uma lista. | Object |
| data.federalRevenueNumber | O CPF consultado, sem máscara | String |
| data.face | O veredito da validação | Object |
| data.face.availability | true quando houve face suficiente para avaliar. false quando não houve veredito. | Boolean |
| data.face.probability | Faixa de probabilidade de a face enviada ser a do titular do CPF: VeryHigh, High, Low, VeryLow ou Unknown | String |
| data.face.boundingBox | Posição da face na imagem enviada, em proporções entre 0 e 1. Só aparece com returnsFaceInfo=true. | Object |
| data.face.croppedBase64 | Recorte da face em base64. Só aparece com returnsFaceInfo=true. | String |
| metadata | Objeto com os metadados da requisição | Object |
| metadata.filesInfo | Lista com uma entrada, referente ao arquivo enviado | Object[] |
| metadata.filesInfo[].fieldname | Nome do campo usado no envio | String |
| metadata.filesInfo[].name | Nome do arquivo enviado | String |
| metadata.filesInfo[].size | Tamanho do arquivo enviado, em bytes | Number |
| metadata.filesInfo[].pages | Número de páginas do arquivo. Como só imagens são aceitas, é sempre 1. | Number |
| metadata.filesInfo[].mimetype | Tipo do arquivo enviado | String |
| metadata.filesInfo[].encoding | Codificação do arquivo no envio | String |
| metadata.filesInfo[].sha256 | Hash SHA-256 do arquivo enviado | String |
| metadata.timeSpent | Tempo de processamento da requisição, em milissegundos | Number |
boundingBox traz top, left, width e height como proporções da imagem, entre 0 e 1 — não em pixels. A origem é o canto superior esquerdo: left e top são a distância da face até esse canto, dividida respectivamente pela largura e pela altura da imagem. Para obter pixels, multiplique left e width pela largura da imagem, e top e height pela altura.
Os valores de probability
availability | probability | O que significa |
|---|---|---|
true | VeryHigh | Avaliado. Probabilidade muito alta de ser o titular do CPF. |
true | High | Avaliado. Probabilidade alta. |
true | Low | Avaliado. Probabilidade baixa. |
true | VeryLow | Avaliado. Probabilidade muito baixa. |
false | Unknown | Não avaliado. Não havia face suficiente para produzir um veredito. |
‼️ Unknown não é um resultado ruim — é a ausência de resultado
Este é o ponto que mais gera interpretação errada. Unknown e VeryLow não são a mesma coisa, e a diferença muda a decisão que você toma:
VeryLow(comavailability: true) é um veredito negativo: a face foi comparada com a base oficial, e o resultado é que ela provavelmente não é do titular do CPF.Unknown(comavailability: false) não é veredito nenhum: não havia face suficiente para avaliar. A API não está dizendo que a pessoa não é o titular — está dizendo que não sabe.
Tratar Unknown como reprovação nega acesso a pessoas legítimas por um problema de imagem ou de base. Tratar Unknown como aprovação aceita qualquer um. O correto é tratá-lo como um terceiro caminho: pedir uma nova captura, ou encaminhar para conferência manual.
Na prática, teste availability antes de olhar probability.
🚧 Este endpoint não devolve similarity
Se você vem do Face Match + Datavalid, repare que aqui não existe o campo similarity, e ele não vai passar a existir.
A validação usada por este endpoint produz uma faixa de risco, não uma medida contínua. Não há um número de 0 a 1 por trás de probability que tenha sido medido. Expor um seria inventar precisão que o dado não tem.
Não construa regras de negócio esperando um score contínuo aqui: decida sobre as faixas de probability, que são o dado real.
Exemplos JSON
- Face validada com probabilidade muito alta
{
"id": "13cfec7c-b238-4820-a4d1-5173e4c1418e",
"version": "v1",
"data": {
"federalRevenueNumber": "12345678909",
"face": {
"availability": true,
"probability": "VeryHigh"
}
},
"metadata": {
"filesInfo": [
{
"fieldname": "selfie",
"name": "selfie.jpg",
"size": 890098,
"pages": 1,
"mimetype": "image/jpeg",
"encoding": "7bit",
"sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6c4"
}
],
"timeSpent": 4210
}
}- Sem veredito — não havia face suficiente para avaliar
{
"id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
"version": "v1",
"data": {
"federalRevenueNumber": "12345678909",
"face": {
"availability": false,
"probability": "Unknown"
}
},
"metadata": {
"filesInfo": [
{
"fieldname": "selfie",
"name": "selfie.jpg",
"size": 762310,
"pages": 1,
"mimetype": "image/jpeg",
"encoding": "7bit",
"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
}
],
"timeSpent": 3980
}
}TIP
Este é um 200, não um erro. A requisição foi processada; o que não houve foi veredito. Veja o bloco acima sobre como tratar Unknown.
- Com
returnsFaceInfo=true
{
"id": "a7f0c3d2-9e51-4b8a-8f31-2d4c6b9e0a77",
"version": "v1",
"data": {
"federalRevenueNumber": "12345678909",
"face": {
"availability": true,
"probability": "High",
"boundingBox": { "top": 0.11, "left": 0.26, "width": 0.42, "height": 0.69 },
"croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
}
},
"metadata": {
"filesInfo": [
{
"fieldname": "selfie",
"name": "selfie.png",
"size": 1204877,
"pages": 1,
"mimetype": "image/png",
"encoding": "7bit",
"sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
}
],
"timeSpent": 5120
}
}Headers de resposta
| Header | Quando aparece |
|---|---|
Nextid-ReqId | Em todas as respostas. Traz o identificador da requisição, o mesmo do campo id do corpo. |
Erros
| Código | Quando ocorre |
|---|---|
| 401 Unauthorized | Chave de API ou token JWT ausente, inválido, ou sem a permissão nextid.bureaus.faceValidation. |
| 404 Not Found | A versão informada na URL não existe. Só a v1 é aceita. |
| 406 Not Acceptable | O corpo foi enviado como JSON, mas sem o campo base64. |
| 413 Payload Too Large | O arquivo enviado passa de 15 MB. |
| 415 Unsupported Media Type | O header Content-Type está ausente, ou não é multipart/form-data nem application/json. |
| 422 Unprocessable Entity | CPF que não passa na validação do dígito verificador; campo urls no corpo; nenhum arquivo enviado; mais de um arquivo; formato de arquivo não aceito; parâmetro de query desconhecido ou com valor inválido; nenhuma face detectada na imagem; face recusada por baixa qualidade. |
| 500 Internal Server Error | Falha inesperada durante o processamento, incluindo indisponibilidade da base oficial. |
TIP
Este endpoint praticamente não usa 400. O 422 é o código de recusa para todo problema no que foi enviado — do CPF ao formato do arquivo, passando pela query string.
As recusas ligadas ao arquivo chegam com 422 e uma destas mensagens, iguais nas duas formas de envio:
message | Quando ocorre |
|---|---|
Sending files by URL is not supported. Use multipart/form-data or the "base64" field. | O corpo traz o campo urls. |
An image file is required. | Nenhum arquivo foi enviado. |
Exceed limit of files. Max allowed 1. | Mais de um arquivo na mesma chamada. |
Expected one of the following mimetypes: image/png, image/jpeg | O arquivo não é PNG nem JPEG. Vale também para PDF. |
Exemplo de resposta com CPF inválido:
Status Code: 422{
"id": "13cfec7c-b238-4820-a4d1-5173e4c1418e",
"error": {
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "Invalid Federal Revenue Number"
}
}Exemplo de resposta quando nenhuma face é detectada na imagem:
Status Code: 422{
"id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
"error": {
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "No face detected in the image"
}
}🚧 Nenhuma face na imagem é 422, não Unknown
São situações diferentes, e chegam por caminhos diferentes:
- Não achamos face na imagem que você enviou →
422, com a mensagem acima. A validação nem chega a ser feita. - Achamos a face, mas não houve como produzir um veredito →
200, comavailability: falseeprobability: "Unknown".
No primeiro caso o problema está na imagem enviada, e pedir uma nova captura costuma resolver.
O formato das respostas de erro está descrito em Códigos HTTP das respostas.
Versões
Este endpoint tem uma única versão, a v1. Ela é o padrão quando a versão é omitida na URL.
| Versão | Situação | O que muda |
|---|---|---|
| v1 | Recomendada | Única versão. Atende tanto /face-validation/natural-person/{CPF} quanto /face-validation/v1/natural-person/{CPF}. |
Qualquer outro valor na URL — /face-validation/v2/natural-person/{CPF}, por exemplo — devolve 404.