Skip to content

Full OCR + Datavalid

This endpoint does two things in one call:

  1. Full OCR — classifies the document sent and extracts its fields, like Full OCR and with the differences described below, including the cross-check against the Brazilian Federal Revenue Service.
  2. Datavalid — sends the extracted data to Datavalid, the validation service run by SERPRO (the Brazilian federal data processing agency), and asks, field by field, whether it checks out against the government's official record.

The difference from plain Full OCR is the second step. Full OCR answers "what is written on this document, and does it match the Federal Revenue Service". Here you also get "and does it match Datavalid" — name, parents' names, date of birth, driver's license status, ID card number, and the facial biometrics.

This endpoint does not perform liveness (use Liveness) and does not compare the face on the document with a selfie you send. If your case is checking a selfie against the official biometrics, use Face Match + Datavalid.

Request

POST /full-ocr-and-datavalid/v3

Headers

http
Authorization: ApiKey <your-api-key>

This endpoint also accepts the JWT token, in the format Authorization: Bearer <accessToken>. See JWT Token.

SERPRO keys

The Datavalid query can be made with our SERPRO access or with your own credentials. What enables the second mode is the scope of your API key:

Scope of your keyCredential headers
nextid.bureaus.fullOcrAndDatavalidOptional
nextid.bureaus.fullOcrAndDatavalid.customerKeysRequired

Send the credentials in two headers:

http
x-customer-key: <your-serpro-key>
x-customer-secret: <your-serpro-secret>

🚧 Send the raw value, with no prefix

The two headers are read exactly as you send them. Do not put Key or Secret before the value: the prefix would become part of the credential sent to SERPRO, and the query would fail with 401.

‼️ With one of the two headers missing, the request never starts

With the customerKeys scope, both headers are mandatory. If either one is missing or empty, the request is rejected immediately with 401 and the message Datavalid customer keys are required — before any file is read. Sending only one of the two is the same as sending neither.

🚧 If you send the headers, they get used

The two headers are read and forwarded to SERPRO whenever they are present, under either scope. The customerKeys scope determines that they are required, not that they start being used.

In other words: an API key with the ordinary scope that sends x-customer-key and x-customer-secret starts querying with your credentials. If the intent was to use Nextcode's access, do not send the headers.

TIP

This is the only endpoint that accepts your own SERPRO keys. Face Match + Datavalid always uses Nextcode's access and ignores those two headers.

Parameters

ParameterDescriptionRequired
federalRevenueNumberA CPF (the Brazilian individual taxpayer number) you already know for the person, to guide the search at the Federal Revenue Service. Accepts formatting. Can be repeated for more than one CPF.No

🚧 With no CPF resolved, there is no Datavalid query

The Datavalid query is made by CPF. That CPF can come from the document itself, read by OCR, or from the federalRevenueNumber parameter — but it has to exist.

When no CPF is resolved for the document, the Datavalid step is skipped silently: the response is 200, with the whole extraction as normal and "datavalid": {}. Passing federalRevenueNumber when you already know it is the safest way to guarantee the query.

🚧 federalRevenueNumber is validated by its check digits

A CPF that fails validation brings the whole request down with 422, before any processing.

Accepted files

ItemValue
Formatsapplication/pdf, image/png, image/jpeg
Files per callup to 7 files
Maximum size (multipart)15 MB per file

The form field names are up to you — they come back in the response. Sending more than seven files is rejected with 422.

The front and back of the same document, sent in different files or pages, are merged into a single data entry. That holds on both versions of this endpoint.

Besides multipart/form-data, the files can be sent as JSON, in the base64 field, as described in Sending files.

Example request

With Nextcode's access:

bash
curl -i -X POST 'https://api-homolog.nxcd.app/full-ocr-and-datavalid/v3?federalRevenueNumber=123.456.789-09' \
  --header 'Authorization: ApiKey YOUR_API_KEY' \
  --form 'frente=@./cnh-frente.jpg' \
  --form 'verso=@./cnh-verso.jpg'

With your own SERPRO credentials:

bash
curl -i -X POST 'https://api-homolog.nxcd.app/full-ocr-and-datavalid/v3?federalRevenueNumber=123.456.789-09' \
  --header 'Authorization: ApiKey YOUR_API_KEY' \
  --header 'x-customer-key: YOUR_SERPRO_KEY' \
  --header 'x-customer-secret: YOUR_SERPRO_SECRET' \
  --form 'documento=@./cnh.jpg'

Response

This section describes v3, the recommended version. v2 returns a data in a different format — see Versions.

The envelope is the API standard:

FieldDescriptionType
idUnique identifier of the requestString
versionAPI version that served the callString
dataList with one entry per document recognized. Comes back empty when none was recognized.Object[]
metadataMetadata of the requestObject

Each item of data carries the blocks below:

BlockWhat it is
datavalidWhat SERPRO answered about the extracted data
extractionThe fields read from the document
federalRevenueDataThe cross-check against the Federal Revenue Service
classificationWhich document it is, from which country, which sides
faceThe face found on the document
metadataFiles sent and processing time. Lives at the root, outside data[].

data[].datavalid

The result of the validation at SERPRO. Every field named after a piece of data is a check boolean, not the value of that data: name: true means "the name read from the document checks out against the official record", and does not return the official name.

FieldDescriptionType
datavalid.federalRevenueNumberAvailabilityIndicates whether the CPF exists in the official databaseBoolean
datavalid.federalRevenueNumberStatusIndicates whether the CPF's registration status in the official database is regularBoolean
datavalid.nameIndicates whether the name read matches the one in the official databaseBoolean
datavalid.nameSimilaritySimilarity between the name read and the one in the official database, from 0 to 1Number
datavalid.mothersNameIndicates whether the mother's name matchesBoolean
datavalid.mothersNameSimilaritySimilarity of the mother's name, from 0 to 1Number
datavalid.fathersNameIndicates whether the father's name matchesBoolean
datavalid.fathersNameSimilaritySimilarity of the father's name, from 0 to 1Number
datavalid.birthdateIndicates whether the date of birth matchesBoolean
datavalid.genderIndicates whether the gender matchesBoolean
datavalid.isBrazilianIndicates whether the person is recorded as Brazilian in the official databaseBoolean
datavalid.croppedFaceBase64Result of comparing the face on the document with the official biometrics. It carries no base64.Object
datavalid.croppedFaceBase64.availabilityIndicates whether facial biometrics are on record for that CPFBoolean
datavalid.croppedFaceBase64.similaritySimilarity between the face on the document and the official biometrics, from 0 to 1Number
datavalid.croppedFaceBase64.probabilityProbability band: VeryHigh, High, Low or VeryLowString
datavalid.documentCheck of the identity document citedObject
datavalid.document.typeIndicates whether the document carries the Brazilian ID card (RG) numberBoolean
datavalid.document.numberIndicates whether the RG number matches the one in the official databaseBoolean
datavalid.document.numberConfidenceSimilarity of the RG number, from 0 to 1Number
datavalid.driversLicenseCheck of the driver's license (CNH) dataObject
datavalid.driversLicense.statusIndicates whether the driver's license is confirmed in the SERPRO databaseBoolean
datavalid.driversLicense.issuedAtIndicates whether the issue date matchesBoolean
datavalid.driversLicense.expireAtIndicates whether the expiry date matchesBoolean
datavalid.driversLicense.firstIssuedAtIndicates whether the first licensing date matchesBoolean
datavalid.driversLicense.registerNumberIndicates whether the register number matchesBoolean
datavalid.driversLicense.driversLicenseCategoryIndicates whether the category matchesBoolean

‼️ datavalid comes back as {} when the query did not happen

The empty object is not a failure of the document: it is the absence of a query. It happens whenever no CPF was resolved for that document.

Code that reads data[0].datavalid.name gets an error in that case. Check that the object is not empty before reading any field of it.

🚧 croppedFaceBase64 carries no face crop at all

Despite the name, datavalid.croppedFaceBase64 is the object holding the biometric comparison resultavailability, similarity and probability. None of the three is base64, and the Datavalid response returns no image.

The name comes from the Datavalid API and does not change. The crop of the face on the document, which really is base64, is in data[].face.croppedBase64.

The document and driversLicense blocks depend on the document sent

driversLicense only has content when the document analyzed is a CNH; document carries the check of the RG. For a document that does not feed those fields, they come back with the values missing.

json
{
  "datavalid": {
    "federalRevenueNumberAvailability": true,
    "federalRevenueNumberStatus": true,
    "name": true,
    "nameSimilarity": 1,
    "gender": true,
    "birthdate": true,
    "mothersName": true,
    "mothersNameSimilarity": 0.97,
    "fathersName": false,
    "fathersNameSimilarity": 0.62,
    "isBrazilian": true,
    "croppedFaceBase64": {
      "availability": true,
      "similarity": 0.96,
      "probability": "VeryHigh"
    },
    "document": {
      "type": true,
      "number": true,
      "numberConfidence": 1
    },
    "driversLicense": {
      "status": true,
      "issuedAt": true,
      "expireAt": true,
      "firstIssuedAt": true,
      "registerNumber": true,
      "driversLicenseCategory": true
    }
  }
}

data[].extraction

The fields read from the document, in a flat object. The set of keys depends on the type and the model of the document: a CNH carries registerNumber, driversLicenseCategory, expireAt and company; an RG carries documentId, issuer, origin and naturalness. The four person fields — name, federalRevenueNumber, mothersName and birthdate — appear on most models.

This is the text as it came out of the OCR, untreated. This endpoint does not have the enhanced object with the cleaned-up version that v4 of Full OCR offers.

json
{
  "extraction": {
    "name": "JOAO DA SILVA SANTOS",
    "federalRevenueNumber": "12345678909",
    "mothersName": "MARIA DA SILVA SANTOS",
    "birthdate": "01/02/1990",
    "fathersName": "ANTONIO SANTOS",
    "registerNumber": "01234567890",
    "driversLicenseCategory": "AB",
    "firstIssuedAt": "15/04/2010",
    "issuedAt": "10/03/2019",
    "expireAt": "10/03/2029",
    "locale": "SAO PAULO",
    "originDocumentId": "12.345.678-9",
    "originDocumentIssuer": "SSP SP"
  }
}

data[].federalRevenueData

The cross-check against the Federal Revenue Service, made before and independently of Datavalid. Here, unlike in the datavalid block, the fields carry the values the Federal Revenue Service has on record.

FieldDescriptionType
federalRevenueData.nameName on record at the Federal Revenue ServiceString
federalRevenueData.federalRevenueNumberCPF found at the Federal Revenue ServiceString
federalRevenueData.mothersNameMother's name on record at the Federal Revenue ServiceString
federalRevenueData.birthdateDate of birth on record at the Federal Revenue ServiceString
federalRevenueData.matches.name.matchedtrue when the name read matches the Federal Revenue Service'sBoolean
federalRevenueData.matches.federalRevenueNumber.matchedtrue when the CPF matchesBoolean
federalRevenueData.matches.mothersName.matchedtrue when the mother's name matchesBoolean
federalRevenueData.matches.birthdate.matchedtrue when the date of birth matchesBoolean

The Federal Revenue Service and Datavalid are two different checks

federalRevenueData compares the document with the Federal Revenue Service database. datavalid compares it with the record in SERPRO's Datavalid. They are distinct sources and they can disagree — treat the two as independent signals.

json
{
  "federalRevenueData": {
    "name": "JOAO DA SILVA SANTOS",
    "federalRevenueNumber": "12345678909",
    "mothersName": "MARIA DA SILVA SANTOS",
    "birthdate": "01/02/1990",
    "matches": {
      "name": { "matched": true },
      "federalRevenueNumber": { "matched": true },
      "mothersName": { "matched": true },
      "birthdate": { "matched": true }
    }
  }
}

data[].classification

FieldDescriptionType
classification.typeType of the document: DriversLicense, FederalIDString
classification.subtypeModel within the type: Printed, Digital, Decree2018PaperString
classification.countryIssuing country, in three lettersString
classification.sidesOne entry per side recognizedObject[]
classification.sides[].sideOnlyFront, OnlyBack or FrontAndBackString
classification.sides[].pagePage where the side was recognized. Starts at 0.Number
classification.sides[].fieldnameName of the field the file was sent inString
classification.sides[].confidenceConfidence of the classification of that sideNumber
json
{
  "classification": {
    "type": "DriversLicense",
    "subtype": "Printed",
    "country": "BRA",
    "sides": [
      { "side": "OnlyFront", "page": 0, "fieldname": "frente", "confidence": 0.99 },
      { "side": "OnlyBack", "page": 0, "fieldname": "verso", "confidence": 0.97 }
    ]
  }
}

data[].face

The face found on the document — the same one that is sent to Datavalid for the biometric comparison.

FieldDescriptionType
face.ageEstimated apparent ageNumber
face.gender.valueMale or FemaleString
face.boundingBoxPosition of the face in the image, in proportions between 0 and 1 (top, left, width, height)Object
face.croppedBase64Crop of the face in base64String

When no face is found on the document, this block does not appear and the Datavalid query is made without the biometric step. datavalid.croppedFaceBase64 does not disappear from the response: the key is still there and comes back empty ({}), because availability, similarity and probability are only filled in when Datavalid returns the biometric block. The name, parents' names and date fields are still checked.

metadata

FieldDescriptionType
metadata.filesInfoList with one entry per file sentObject[]
metadata.filesInfo[].fieldnameName of the field used to send the fileString
metadata.filesInfo[].nameName of the file sentString
metadata.filesInfo[].sizeSize of the file, in bytesNumber
metadata.filesInfo[].pagesNumber of pages of the file. For images, 1.Number
metadata.filesInfo[].mimetypeType of the file sentString
metadata.filesInfo[].encodingEncoding of the file as sentString
metadata.filesInfo[].sha256SHA-256 hash of the file sentString
metadata.timeSpentProcessing time of the request, in millisecondsNumber

Full example

Status Code: 200
json
{
  "id": "12cfec3c-b456-7890-a4d1-5173e4c1418e",
  "version": "v3",
  "data": [
    {
      "datavalid": {
        "federalRevenueNumberAvailability": true,
        "federalRevenueNumberStatus": true,
        "name": true,
        "nameSimilarity": 1,
        "gender": true,
        "birthdate": true,
        "mothersName": true,
        "mothersNameSimilarity": 0.97,
        "fathersName": false,
        "fathersNameSimilarity": 0.62,
        "isBrazilian": true,
        "croppedFaceBase64": {
          "availability": true,
          "similarity": 0.96,
          "probability": "VeryHigh"
        },
        "document": {
          "type": true,
          "number": true,
          "numberConfidence": 1
        },
        "driversLicense": {
          "status": true,
          "issuedAt": true,
          "expireAt": true,
          "firstIssuedAt": true,
          "registerNumber": true,
          "driversLicenseCategory": true
        }
      },
      "extraction": {
        "name": "JOAO DA SILVA SANTOS",
        "federalRevenueNumber": "12345678909",
        "mothersName": "MARIA DA SILVA SANTOS",
        "birthdate": "01/02/1990",
        "fathersName": "ANTONIO SANTOS",
        "registerNumber": "01234567890",
        "driversLicenseCategory": "AB",
        "firstIssuedAt": "15/04/2010",
        "issuedAt": "10/03/2019",
        "expireAt": "10/03/2029",
        "locale": "SAO PAULO",
        "originDocumentId": "12.345.678-9",
        "originDocumentIssuer": "SSP SP"
      },
      "federalRevenueData": {
        "name": "JOAO DA SILVA SANTOS",
        "federalRevenueNumber": "12345678909",
        "mothersName": "MARIA DA SILVA SANTOS",
        "birthdate": "01/02/1990",
        "matches": {
          "name": { "matched": true },
          "federalRevenueNumber": { "matched": true },
          "mothersName": { "matched": true },
          "birthdate": { "matched": true }
        }
      },
      "classification": {
        "type": "DriversLicense",
        "subtype": "Printed",
        "country": "BRA",
        "sides": [
          { "side": "OnlyFront", "page": 0, "fieldname": "frente", "confidence": 0.99 },
          { "side": "OnlyBack", "page": 0, "fieldname": "verso", "confidence": 0.97 }
        ]
      },
      "face": {
        "age": 34,
        "gender": { "value": "Male" },
        "boundingBox": {
          "top": 0.2237228155136108,
          "left": 0.2856607735157013,
          "width": 0.1555942893028259,
          "height": 0.1687679588794708
        },
        "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
      }
    }
  ],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "frente",
        "name": "cnh-frente.jpg",
        "size": 567098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6b0"
      },
      {
        "fieldname": "verso",
        "name": "cnh-verso.jpg",
        "size": 512044,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
      }
    ],
    "timeSpent": 12480
  }
}

Document read, with no Datavalid query

Status Code: 200

No CPF was resolved for the document — neither read from it, nor given in federalRevenueNumber. The extraction happens as normal; the Datavalid step is skipped.

json
{
  "id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
  "version": "v3",
  "data": [
    {
      "datavalid": {},
      "extraction": {
        "name": "JOAO DA SILVA SANTOS",
        "birthdate": "01/02/1990",
        "documentId": "12.345.678-9",
        "issuer": "SSP SP"
      },
      "classification": {
        "type": "FederalID",
        "subtype": "MainModel",
        "country": "BRA",
        "sides": [
          { "side": "OnlyFront", "page": 0, "fieldname": "documento", "confidence": 0.98 }
        ]
      },
      "face": {
        "age": 34,
        "gender": { "value": "Male" },
        "boundingBox": { "top": 0.22, "left": 0.28, "width": 0.15, "height": 0.16 },
        "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
      }
    }
  ],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "documento",
        "name": "rg-frente.jpg",
        "size": 384210,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
      }
    ],
    "timeSpent": 7320
  }
}

Response headers

HeaderWhen it appears
Nextid-ReqIdOn every response. Carries the request identifier, the same one as the id field in the body.

Errors

CodeWhen it happens
401 UnauthorizedAPI key or JWT token missing, invalid, or without permission for this endpoint. Also when the scope is customerKeys and one of the credential headers is missing, and when SERPRO rejects your credentials.
404 Not FoundThe version given in the URL does not exist. Only v2 and v3 are accepted.
406 Not AcceptableThe body was sent as JSON, but without the base64 field.
413 Payload Too LargeOne of the files sent as multipart/form-data is larger than 15 MB.
415 Unsupported Media TypeThe Content-Type header is missing or is not supported.
422 Unprocessable EntityA federalRevenueNumber that fails check-digit validation, a file format that is not accepted, or more than seven files. It is also the code returned when Datavalid rejects the face for poor image quality.
500 Internal Server ErrorUnexpected failure during processing, including Datavalid being unavailable.

The two 401s of the key setup

They are different errors, with different messages, and the message is how you tell them apart.

Credential headers missing. The request is rejected before any processing:

Status Code: 401
json
{
  "id": "13cfec7c-b238-4820-a4d1-5173e4c1418e",
  "error": {
    "statusCode": 401,
    "error": "Unauthorized",
    "message": "Datavalid customer keys are required"
  }
}

Credentials rejected by SERPRO. The headers were there, but SERPRO answered 401 to them. Here the file has already been processed — the error happens at the query step and brings the whole request down:

Status Code: 401
json
{
  "id": "6a1d1e8c-4a7d-4a5e-9f2c-1b0f2a9c7e11",
  "error": {
    "statusCode": 401,
    "error": "Unauthorized",
    "message": "Invalid customer datavalid credentials"
  }
}

This is the most common error when setting up your own keys

Invalid customer datavalid credentials means the key and the secret reached SERPRO and were rejected. By far the most frequent causes are the Key /Secret prefix stuck to the header value and the two values being swapped. Also check that your contract with SERPRO covers the service being queried.

This error does not come with a partial result: you do not get the document extraction along with it. If you need the extraction even when Datavalid is unavailable, use Full OCR.

Example response when Datavalid rejects the face for quality:

Status Code: 422
json
{
  "id": "a7f0c3d2-9e51-4b8a-8f31-2d4c6b9e0a77",
  "error": {
    "statusCode": 422,
    "error": "Unprocessable Entity",
    "message": "The face is of poor quality to be processed in the datavalid"
  }
}

The error response format is described in HTTP response codes.

Versions

The recommended version is v3, called at /full-ocr-and-datavalid/v3.

‼️ Omitting the version hands the call to v2

POST /full-ocr-and-datavalid, with no version in the path, is served by v2, which has a different response format. Always state the version in the URL.

VersionStatusWhat changes
v3Recommendedclassification in the API's standard format, with type, subtype, country and sides.
v2Legacyclassifications in the plural, with the old vocabulary of types, and a more detailed federalRevenueData. This is what answers when the version is omitted from the URL.

There is no v4 here

Full OCR has a v4, with extraction and enhanced separated. This endpoint does not: /full-ocr-and-datavalid/v4 answers 404.

What changes in v2

The datavalid block is identical. The differences are in the other three:

  • classification becomes classifications, in the plural, and it is a list with one entry per side recognized. Each entry has page, fieldname and a classification with confidence, a type in the old vocabulary (CNH, RG, CPF, PROOF-OF-RESIDENCE, SELFIE, IMPRESSOS, CARTAOCREDITO or OTHERS) and a face (front, back or front-back). There is no subtype and no country.
  • federalRevenueData is more detailed. The matches live in federalRevenueData.matched — in the singular, different from v3 — and each field carries matched, confidence (0 to 1) and strategy (char-to-char or by-tokens).
  • face also carries the gender confidence, in face.gender.confidence.
Status Code: 200
json
{
  "id": "12cfec3c-b456-7890-a4d1-5173e4c1418e",
  "version": "v2",
  "data": [
    {
      "datavalid": {
        "federalRevenueNumberAvailability": true,
        "federalRevenueNumberStatus": true,
        "name": true,
        "nameSimilarity": 1,
        "gender": true,
        "birthdate": true,
        "mothersName": true,
        "mothersNameSimilarity": 0.97,
        "fathersName": false,
        "fathersNameSimilarity": 0.62,
        "isBrazilian": true,
        "croppedFaceBase64": {
          "availability": true,
          "similarity": 0.96,
          "probability": "VeryHigh"
        },
        "document": { "type": true, "number": true, "numberConfidence": 1 },
        "driversLicense": {
          "status": true,
          "issuedAt": true,
          "expireAt": true,
          "firstIssuedAt": true,
          "registerNumber": true,
          "driversLicenseCategory": true
        }
      },
      "extraction": {
        "name": "JOAO DA SILVA SANTOS",
        "federalRevenueNumber": "12345678909",
        "mothersName": "MARIA DA SILVA SANTOS",
        "birthdate": "01/02/1990",
        "registerNumber": "01234567890",
        "driversLicenseCategory": "AB"
      },
      "federalRevenueData": {
        "name": "JOAO DA SILVA SANTOS",
        "federalRevenueNumber": "12345678909",
        "mothersName": "MARIA DA SILVA SANTOS",
        "birthdate": "01/02/1990",
        "matched": {
          "name": { "matched": true, "confidence": 1, "strategy": "char-to-char" },
          "federalRevenueNumber": { "matched": true, "confidence": 1, "strategy": "char-to-char" },
          "mothersName": { "matched": true, "confidence": 0.97, "strategy": "by-tokens" },
          "birthdate": { "matched": true, "confidence": 1, "strategy": "char-to-char" }
        }
      },
      "classifications": [
        {
          "page": 0,
          "fieldname": "frente",
          "classification": { "confidence": 0.99, "type": "CNH", "face": "front" }
        },
        {
          "page": 0,
          "fieldname": "verso",
          "classification": { "confidence": 0.97, "type": "CNH", "face": "back" }
        }
      ],
      "face": {
        "age": 34,
        "gender": { "value": "Male", "confidence": 99.72 },
        "boundingBox": { "top": 0.22, "left": 0.28, "width": 0.15, "height": 0.16 },
        "croppedBase64": "iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAA...K5CYII="
      }
    }
  ],
  "metadata": {
    "filesInfo": [
      {
        "fieldname": "frente",
        "name": "cnh-frente.jpg",
        "size": 567098,
        "pages": 1,
        "mimetype": "image/jpeg",
        "encoding": "7bit",
        "sha256": "41c2ece339abfcf9ba1e7d5a60666162a24ef34ba95adeb41ed1d9721c91c6b0"
      }
    ],
    "timeSpent": 11940
  }
}

‼️ Switching versions breaks whoever reads the response

The result of the name check against the Federal Revenue Service is in data[].federalRevenueData.matched.name.matched on v2 and in data[].federalRevenueData.matches.name.matched on v3. And the classification moves from data[].classifications[] to data[].classification.

The datavalid block is the only one that crosses the two versions unchanged.

Nextcode | Identity Verification Solutions