OCR by Face Beta
🚧 Beta feature
This endpoint is in beta. The response contract may change without a version bump. Let our team know before you put it in production, so that we can follow your integration.
The OCR by Face API is an identity verification service that lets customers validate and retrieve identity documents from a CPF (the Brazilian individual taxpayer number) and a selfie photo, making the KYC process smoother and more efficient.
It solves the inverse path of the other document endpoints: here the customer does not send the document. They send the CPF and the selfie, and we look for the matching document. If you already have the document image at hand, the right endpoint is Full OCR.
Request
POST/ocr-by-face/v1/tax-id/{CPF}Parameters
| Parameter | Description | Required | Sent as |
|---|---|---|---|
| CPF | The person's CPF, with or without formatting | Yes | URL parameter |
document_types | Filters the document types searched for. Without it, the search covers only the Brazilian ID card (RG) and the driver's license (CNH). | No | Query parameter |
| selfie | The person's selfie image. The field name is up to you. | Yes | File in the body |
The CPF can be sent with or without formatting (123.456.789-09 or 12345678909), always with all 11 digits, including leading zeros. A CPF that fails check-digit validation returns 422 with the message Invalid taxId (CPF), before any processing takes place.
TIP
document_types is a list repeated in the query string. It can be sent like this (e.g. RG, CNH and passport): /ocr-by-face/v1/tax-id/12345678909?document_types[]=federal-id&document_types[]=drivers-license&document_types[]=passport.
Headers
Authorization: ApiKey <your-api-key>This endpoint also accepts the JWT token, in the format Authorization: Bearer <accessToken>. See JWT Token.
Accepted files
| Item | Value |
|---|---|
| Formats | image/png, image/jpeg |
| Files per call | 1 file |
| Maximum size (multipart) | 15 MB |
The form field name is up to you. If more than one file is sent, the request is rejected with 422.
Besides multipart/form-data, the selfie can be sent as JSON, in the base64 field, as described in Sending files.
Example request
curl -i -X POST 'https://api-homolog.nxcd.app/ocr-by-face/v1/tax-id/12345678909' \
--header 'Authorization: ApiKey YOUR_API_KEY' \
--form 'selfie=@./selfie.jpg'Filtering the document types searched for:
curl -i -X POST 'https://api-homolog.nxcd.app/ocr-by-face/v1/tax-id/12345678909?document_types[]=federal-id&document_types[]=passport' \
--header 'Authorization: ApiKey YOUR_API_KEY' \
--form 'selfie=@./selfie.jpg'Response
The envelope of this endpoint is a reduced one: it carries id and data, with no version and no metadata.
| Field | Description | Type |
|---|---|---|
| id | ID of the request | String |
| data | Object with the result of the analysis | Object |
| data.match | Whether the selfie matches the CPF | Boolean |
| data.similarity | Similarity percentage | Number |
| data.idCards | List of the identity documents found | Object[] |
| data.idCards[].base64 | Base64 of the identity document | String |
| data.ocr | Object with the text extracted from the document | Object |
| data.ocr.taxId | CPF of the applicant | String |
| data.ocr.name | Name of the applicant | String |
| data.ocr.birthdate | Date of birth of the applicant | String |
| data.ocr.mothersName | Mother's name of the applicant | String |
| data.ocr.fathersName | Father's name of the applicant | String |
| data.ocr.issuedAt | Issue date of the document | String |
🚧 idCards and ocr only exist when the selfie matches
When match is false, data carries only match and similarity. Test match before reading data.ocr or data.idCards.
JSON examples
Here are some examples of the response in JSON.
TIP
The CPF "12345678909" is a test CPF — it passes check-digit validation, but does not belong to a real person. If you have any questions, get in touch with our support team.
- Example when a document is found from the CPF and the selfie
{
"id": "e83b9a9b-0547-4d52-84b4-68a156f6116a",
"data": {
"idCards": [
{
"base64": "iVBORw0KG...K5CYII="
},
{
"base64": "iVBORw0K...SuQmCC"
}
],
"match": true,
"ocr": {
"birthdate": "1990-06-21",
"fathersName": "Joe Doe",
"issuedAt": "2010-10-01",
"mothersName": "Jane Doe",
"name": "John Doe",
"taxId": "12345678909"
},
"similarity": 0.9982403814792633
}
}- Example when the selfie does not match the CPF
{
"id": "943fb612-838e-46c3-92e7-4c92dc18b370",
"data": {
"match": false,
"similarity": 0.5110294818878174
}
}- Example when no document is found
{
"id": "7c86a49b-c392-4f6e-bd32-74f359d736bc",
"error": {
"statusCode": 404,
"error": "Not Found",
"message": "not found identity document for the provided person tax id and filters"
}
}- Example when the payload is invalid (invalid CPF or image)
{
"id": "795ada3c-5b6f-42de-8878-c5e59f98133d",
"error": {
"statusCode": 422,
"error": "Unprocessable Entity",
"message": "Invalid taxId (CPF)"
}
}Response headers
| Header | When it appears |
|---|---|
Nextid-ReqId | On every response. Carries the request identifier, the same one as the id field in the body. |
Errors
| Code | When it happens |
|---|---|
| 401 Unauthorized | API key or JWT token missing, invalid, or without the nextid.ocrByFace.ocrByFace permission. |
| 404 Not Found | No identity document was found for the CPF given and the filters applied. |
| 406 Not Acceptable | The body was sent as JSON, but without the base64 field. |
| 413 Payload Too Large | The selfie sent as multipart/form-data is larger than 15 MB. |
| 415 Unsupported Media Type | The Content-Type header is missing or is not supported. |
| 422 Unprocessable Entity | A CPF that fails check-digit validation (Invalid taxId (CPF)), a file format that is not accepted, or more than one file. |
| 500 Internal Server Error | Unexpected failure during processing. |
The invalid CPF message is different here
This endpoint answers Invalid taxId (CPF). The other endpoints that validate a CPF answer Invalid Federal Revenue Number. If your code compares the message, handle both.
The 404 is the expected response when there is no document for that CPF — it is not an integration failure. A selfie that does not match the CPF does not raise an error: it returns 200 with match: false.
The error response format is described in HTTP response codes.
Versions
This endpoint has a single version, v1, and it is mandatory in the path: /ocr-by-face/v1/tax-id/{CPF}. There is no version-less form, and no other version is live.
| Version | Status | What changes |
|---|---|---|
| v1 | Recommended | The only version. Reduced envelope, with id and data only. |
🚧 The contract may change without a version bump
While the endpoint is in beta, data fields may be added, renamed or removed without the v1 in the URL changing. Read the fields defensively and let our team know before going to production.
Security and best practices
- Always validate the CPF format before sending requests
- Make sure selfie images are sharp and well lit
- Implement proper error handling for every response code
- Every request must be made over HTTPS
For support or questions, see the contact channels.