OCR API - India
The following document highlights the details of the OCR API.
API Description
Objective
The OCR API performs optical character recognition(OCR) to extract information from officially valid documents such as PAN, Aadhaar, Voter's ID and passport.
| Input | Output |
|---|---|
| An image of any of the officially valid documents supported by HyperVerge | The data extracted from the document |
API URL
For any of the supported officially valid documents:
https://ind-docs.hyperverge.co/v2.0/readKYC
Exclusively for PAN:
https://ind-docs.hyperverge.co/v2.0/readPAN
Exclusively for Indian passports:
https://ind-docs.hyperverge.co/v2.0/readPassport
Exclusively for Aadhaar:
https://ind-docs.hyperverge.co/v2.0/readAadhaar
Exclusively for Voter ID:
https://ind-docs.hyperverge.co/v2.0/readVoterID
Overview
The API is RESTful and uses standard HTTP verbs and status codes. The responses are in JSON format and you should upload all images and files as form-data through a POST request.
Method - POST
Authentication
You need a unique pair of application ID ( appId ) and application key ( appKey ) from HyperVerge to verify your identity for accessing the API.
Headers
| Header | Mandatory / Optional | Description | Input Format |
|---|---|---|---|
| Content-type | Mandatory | The media type for the request payload | multipart/form-data |
| appId | Mandatory | The application identifier shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
| appKey | Mandatory | The application key shared by HyperVerge. You can find the details in the dashboard's credentials tab | This should be a unique value |
| transactionId | Mandatory | A unique identifier for tracking a user journey | This should be both unique and easily associated with the user's journey in your application(s) |
Inputs
The following table provides the details of the parameters required for the OCR API's request body:
Each of the following parameters are alternate options that you can use in the request. Kindly use any one of them in the request.
| Parameter | Mandatory / Optional | Type | Description | Input Format | Default Value |
|---|---|---|---|---|---|
image | Selectively mandatory - The request must have any one of the image, pdf or url parameters. | string | The image file on which the API will perform the OCR extraction. Note The API supports JPEG, PNG and TIFF images. | Not Applicable | Not Applicable |
pdf | Selectively mandatory - The request must have any one of the image, pdf or url parameters. | string | The PDF file on which the API will perform the OCR extraction. | Not Applicable | Not Applicable |
url | Selectively mandatory - The request must have any one of the image, pdf or url parameters. | string | The public URL of the file on which the API will perform the OCR extraction. For example, "url=https://public_URL_of_the_document" | Not Applicable | Not Applicable |
shouldSupportNewVoterId | Optional | string | If set to 'yes', the API supports the inclusion of the new voter ID. If set to 'no' or not enabled, a message that says "No supported KYC document detected" is displayed | Not Applicable | 'no' |
- For the deep learning servers to extract text out of an image, the rule of thumb that needs to be followed is that the text in the image should be legible.
- Higher size of image will lead to higher upload and processing time. Hence the size of image should be reduced as much as possible while ensuring that above condition is met.
- A general guideline that can be followed is to keep the width of the ID card image at least 800 pixels and to keep JPEG compression quality factor above 80%.
- The aspect ratio of the input image should be same as the aspect ratio of the original document. Kindly take care of the aspect ratio when resizing the image. If integrating into an Android or iOS app, please use the HyperSnap SDK for Android and iOS.
- This SDK provides camera functionality for capturing images of ID cards while taking care of all the above requirements.
Inputs for Aadhaar Masking
The OCR API also supports Aadhaar masking while extracting the OVD details in the response.
The following table lists all the input parameters to enable it.
| Parameter | Mandatory / Optional | Type | Description | Input Format | Default Value |
|---|---|---|---|---|---|
maskAadhaar | Optional | string | If set to "yes", it masks the first eight digits of the user's Aadhaar while revealing only the last four digits. | Not Applicable | "no" |
maskAadhaarComplete | Optional | string | If set to "yes", it masks all the digits of the user's Aadhaar. | Not Applicable | "no" |
maskAadhaarText | Optional | string | If set to "yes", it masks the aadhaar number in response body. It has to be used with maskAadhaar or maskAadhaarComplete to mask first 8 or all digits respectively. | Not Applicable | "no" |
maskQR | Optional | string | If set to "yes", it masks the QR code associated with the user's Aadhaar. | Not Applicable | "no" |
returnQRMaskingInfo | Optional | string | If set to "yes", it verifies if the Aadhaar QR is masked in the response. It should be used with the aforementioned maskQR parameter. | Not Applicable | "no" |
outputImageUrl | Optional | string | If set to "yes", the image of the user's masked Aadhaar is returned against the url field. | Not Applicable | "no" |
returnMaskingInfo | Optional | string | If set to "yes", it verifies whether the image has been masked by our service in the response. | Not Applicable | "no" |
We do not apply masking if the Aadhaar number is not detected in the ID card or is already pre-masked.
Request
The following code snippet demonstrates standard curl requests for the OCR API. You can send an image file, a PDF file or the public URL of the document in the request.
- Send Image File
- Send PDF
- Send Public URL
curl --location --request POST 'https://ind-docs.hyperverge.co/v2.0/readKYC' \
--header 'Content-Type: multipart/form-data' \
--header 'appId: <Enter_the_HyperVerge_appId>' \
--header 'appKey: <Enter_the_HyperVerge_appKey>' \
--header 'transactionId: <Enter_the_HyperVerge_transactionID>' \
--form 'image=@"<Enter_image_path_with_extension>"'
curl --location --request POST 'https://ind-docs.hyperverge.co/v2.0/readKYC' \
--header 'Content-Type: multipart/form-data' \
--header 'appId: <Enter_the_HyperVerge_appId>' \
--header 'appKey: <Enter_the_HyperVerge_appKey>' \
--header 'transactionId: <Enter_the_HyperVerge_transactionID>' \
--form 'pdf=@"<Enter_file_path_with_.pdf_extension>"'
curl --location --request POST 'https://ind-docs.hyperverge.co/v2.0/readKYC' \
--header 'Content-Type: multipart/form-data' \
--header 'appId: <Enter_the_HyperVerge_appId>' \
--header 'appKey: <Enter_the_HyperVerge_appKey>' \
--header 'transactionId: <Enter_the_HyperVerge_transactionID>' \
--form 'url="<Enter_the_public_URL>"'
Success Response
The following code snippet demonstrates a success response from the OCR API:
{
"status": "success",
"statusCode": 200,
"result": {
"details": {
// Response fields will vary based on the document type
}
}
}
Success Response Details
The following table outlines the details of the success response from the OCR API:
| Parameter | Type | Description |
|---|---|---|
status | string | The status of the request |
statusCode | integer | The HTTP status code returned for the request |
result | object | Contains the extracted details from the document |
details | object | Contains the extracted fields with their values and confidence scores |
Each of the details object in the JSON response for a supported document type will have the following schemas. They are ordered by document type and sub-type.
- New PAN ID
- Old PAN ID
"date": {
"value": "<type: String, description: Date of birth of the holder>",
"conf": "<type: Number, description: Confidence For extracted Date of Birth>"
},
"father": {
"value": "<type: String, description: Fathers name of the holder>",
"conf": "<type: Number, description: Confidence For extracted Fathers name>"
},
"name": {
"value": "<type: String, description: Name of the Holder>",
"conf": "<type: Number, description: Confidence For extracted Name>"
},
"pan_no": {
"value": "<type: String, description: PAN Number of the Holder>",
"conf": "<type: Number, description: Confidence For extracted PAN Number>"
},
"date_of_issue": {
"value": "<type:String description: Date of Issue of PAN card>",
"conf": "<type: Number, description: Confidence For extracted Date of Issue>"
}
"tag": "<type: String, description: Unique identifier For extracted document sub-type>"
"date": {
"value": "<type: String, description: Date of birth of the holder>",
"conf": "<type: Number, description: Confidence For extracted Date of Birth>"
},
"father": {
"value": "<type: String, description: Fathers name of the holder>",
"conf": "<type: Number, description: Confidence For extracted Fathers name>"
},
"name": {
"value": "<type: String, description: Name of the Holder>",
"conf": "<type: Number, description: Confidence For extracted Name>"
},
"pan_no": {
"value": "<type: String, description: PAN Number of the Holder>",
"conf": "<type: Number, description: Confidence For extracted PAN Number>"
},
"tag": "<type: String, description: Unique identifier For extracted document sub-type>"
- Aadhaar Front Bottom
- Aadhaar Front Top
- Aadhaar Back
"aadhaar": {
"value": <type: String, description: Aadhaar Number of the holder>,
"ismasked": <type: String, values: [yes or no], description: yes If the Aadhaar number extracted is of masked type and no If it is not of masked type>,
"conf": <type: Number, description: Confidence For extracted Aadhaar Number>
},
"dob": {
"value": <type: String, description: Date of Birth of the Holder>,
"conf": <type: Number, description: Confidence For extracted Date of Birth>
},
"father": {
"value": <type: String, description: Fathers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Fathers name>
},
"gender": {
"value": <type: String, description: Gender of the holder>,
"conf": <type: Number, description: Confidence For extracted Gender>
},
"mother": {
"value": <type: String, description: Mothers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Mothers name>
},
"name": {
"value": <type: String, description: Name of the holder>,
"conf": <type: Number, description: Confidence For extracted Name>
},
"yob": {
"value": <type: String, description: Year of Birth of the holder>,
"conf": <type: Number, description: Confidence For extracted Year of Birth>
},
"qr": {
"value": <type: String, description: QR code XML extracted from the Input Aadhaar Image>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
"aadhaar": {
"value": <type: String, description: Aadhaar Number of the holder>,
"ismasked": <type: String, values: [yes or no], description: yes If the Aadhaar number extracted is of masked type and no If it is not of masked type>,
"conf": <type: Number, description: Confidence For extracted Aadhaar Number>
},
"address": {
"care_of": <type: String, description: Care Of section of the address of the holder>,
"district": <type: String, description: District of the address of the holder>,
"city": <type: String, description: City of the address of the holder>,
"locality": <type: String, description: Locality of the address of the holder>,
"landmark": <type: String, description: Landmark of the address of the holder>,
"street": <type: String, description: Street of the address of the holder>,
"line1": <type: String, description: Line1 of the address of the holder>,
"line2": <type: String, description: Line2 of the address of the holder>,
"house_number": <type: String, description: House Number of the address of the holder>,
"pin": <type: String, description: Pincode of the address of the holder>,
"state": <type: String, description: State of the address of the holder>,
"value": <type: String, description: Address of the holder>
"conf": <type: Number, description: Confidence For extracted Address>
},
"father": {
"value": <type: String, description: Fathers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Fathers name>
},
"husband": {
"value": <type: String, description: Husbands name of the holder>,
"conf": <type: Number, description: Confidence For extracted Husbands name>
},
"name": {
"value": <type: String, description: Name of the holder>,
"conf": <type: Number, description: Confidence For extracted Name>
},
"phone": {
"value": <type: String, description: Phone number of the holder>,
"conf": <type: Number, description: Confidence For extracted Phone number>
},
"pin": {
"value": <type: String, description: Pincode of the holders Address>,
"conf": <type: Number, description: Confidence For extracted Pincode>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
"aadhaar": {
"value": <type: String, description: Aadhaar Number of the holder>,
"ismasked": <type: String, values: [yes or no], description: yes If the Aadhaar number extracted is of masked type and no If it is not of masked type>,
"conf": <type: Number, description: Confidence For extracted Aadhaar Number>
},
"address": {
"care_of": <type: String, description: Care Of section of the address of the holder>,
"district": <type: String, description: District of the address of the holder>,
"city": <type: String, description: City of the address of the holder>,
"locality": <type: String, description: Locality of the address of the holder>,
"landmark": <type: String, description: Landmark of the address of the holder>,
"street": <type: String, description: Street of the address of the holder>,
"line1": <type: String, description: Line1 of the address of the holder>,
"line2": <type: String, description: Line2 of the address of the holder>,
"house_number": <type: String, description: House Number of the address of the holder>,
"pin": <type: String, description: Pincode of the address of the holder>,
"state": <type: String, description: State of the address of the holder>,
"value": <type: String, description: Address of the holder>
"conf": <type: Number, description: Confidence For extracted Address>
},
"father": {
"value": <type: String, description: Fathers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Fathers name>
},
"husband": {
"value": <type: String, description: Husbands name of the holder>,
"conf": <type: Number, description: Confidence For extracted Husbands name>
},
"name": {
"value": <type: String, description: Name of the holder>,
"conf": <type: Number, description: Confidence For extracted Name>
},
"phone": {
"value": <type: String, description: Phone number of the holder>,
"conf": <type: Number, description: Confidence For extracted Phone number>
},
"pin": {
"value": <type: String, description: Pincode of the holders Address>,
"conf": <type: Number, description: Confidence For extracted Pincode>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
- Passport Front
- Passport Back
"country_code": {
"value": <type: String, description: Country Code of the holders Passport>,
"conf": <type: Number, description: Confidence For extracted Country Code>
},
"dob": {
"value": <type: String, description: Date of Birth of the holder>,
"conf": <type: Number, description: Confidence For extracted Date of Birth>
},
"doe": {
"value": <type: String, description: Date of Expiry of the Passport>,
"conf": <type: Number, description: Confidence For extracted Date of Expiry>
},
"doi": {
"value": <type: String, description: Date of Issue of the Passport>,
"conf": <type: Number, description: Confidence For extracted Date of Issue>
},
"gender": {
"value": <type: String, description: Gender of the holder>,
"conf": <type: Number, description: Confidence For extracted Gender>
},
"given_name": {
"value": <type: String, description: Given Name of the holder>,
"conf": <type: Number, description: Confidence For extracted Given Name>
},
"nationality": {
"value": <type: String, description: Nationality of the holder>,
"conf": <type: Number, description: Confidence For extracted Nationality>
},
"passport_num": {
"value": <type: String, description: Passport Number of the holder>,
"conf": <type: Number, description: Confidence For extracted Passport Number>
},
"place_of_birth": {
"value": <type: String, description: Place of birth of the holder>,
"conf": <type: Number, description: Confidence For extracted Place of Birth>
},
"place_of_issue": {
"value": <type: String, description: Place of issue of the Passport>,
"conf": <type: Number, description: Confidence For extracted Place of Issue>
},
"surname": {
"value": <type: String, description: Surname of the holder>,
"conf": <type: Number, description: Confidence For extracted Surname>
},
"mrz": {
"line1": <type: String, description: Line1 of MRZ In the Passport>,
"line2": <type: String, description: Line2 of MRZ In the Passport>
"conf": <type: Number, description: Confidence For extracted MRZ>
},
"type": {
"value": <type: String, description: Type of Passport>
"conf": <type: Number, description: Confidence For extracted Type of Passport>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
"address": {
"district": <type: String, description: District of the address of the holder>,
"city": <type: String, description: City of the address of the holder>,
"locality": <type: String, description: Locality of the address of the holder>,
"landmark": <type: String, description: Landmark of the address of the holder>,
"street": <type: String, description: Street of the address of the holder>,
"line1": <type: String, description: Line1 of the address of the holder>,
"line2": <type: String, description: Line2 of the address of the holder>,
"house_number": <type: String, description: House Number of the address of the holder>,
"pin": <type: String, description: Pincode of the address of the holder>,
"state": <type: String, description: State of the address of the holder>,
"value": <type: String, description: Address of the holder>
"conf": <type: Number, description: Confidence For extracted Address>
},
"father": {
"value": <type: String, description: Fathers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Fathers name>
},
"mother": {
"value": <type: String, description: Mothers name of the holder>,
"conf": <type: Number, description: Confidence For extracted Mothers name>
},
"file_num": {
"value": <type: String, description: File number of the Passport>,
"conf": <type: Number, description: Confidence For extracted File number>
},
"old_doi": {
"value": <type: String, description: Date of Issue of the Old Passport>,
"conf": <type: Number, description: Confidence For extracted Old Date of Issue>
},
"old_passport_num": {
"value": <type: String, description: Old Passport Number of the holder>,
"conf": <type: Number, description: Confidence For extracted Old Passport Number>
},
"old_place_of_issue": {
"value": <type: String, description: Old Place of issue of the Passport>,
"conf": <type: Number, description: Confidence For extracted Old Place of Issue>
},
"passport_num": {
"value": <type: String, description: Passport Number of the holder>,
"conf": <type: Number, description: Confidence For extracted Passport Number>
},
"pin": {
"value": <type: String, description: Pincode of the Address of the holder>,
"conf": <type: Number, description: Confidence For extracted Pincode>
},
"spouse": {
"value": <type: String, description: Spouse name of the holder>
"conf": <type: Number, description: Confidence For extracted Spouses name>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
- New Voter ID Front
- Old Voter ID Front
- Voter ID Back
"voterid": {
"value": <type:String, description: VoterID of Holder>,
"conf": <type: Number, description: Confidence for extracted VoterID>
},
"name": {
"value": <type:String, description: Name of Holder>,
"conf": <type: Number, description: Confidence for extracted Name>
},
"relation": {
"value": <type:String, description: Name of relative's Holder>,
"conf": <type: Number, description: Confidence for extracted Relative's Name>
},
"tag": <type: String, description: Unique identifier for extracted document sub-type>
"voterid": {
"value": <type:String, description: VoterID of Holder>,
"conf": <type: Number, description: Confidence For extracted VoterID>
},
"name": {
"value": <type:String, description: Name of Holder>,
"conf": <type: Number, description: Confidence For extracted Name>
},
"gender": {
"value": <type:String, description:Gender of Holder>,
"conf": <type: Number, description: Confidence For extracted Gender>
},
"relation": {
"value": <type:String, description: Name of relatives Holder>,
"conf": <type: Number, description: Confidence For extracted Relatives Name>
},
"dob": {
"value": <type:String, description: Date of Birth of Holder >,
"conf": <type: Number, description: Confidence For extracted Date of Birth>
},
"doc": {
"value": <type:String, description: Date For Calculation of Age>,
"conf": <type: Number, description: Confidence For extracted Date For Calculation of Age>
},
"age": {
"value": <type:String, description: Age of the Holder>
"conf": <type: Number, description: Confidence For extracted Age>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
"voterid": {
"value": <type:String, description: VoterID of Holder>,
"conf": <type: Number, description: Confidence For extracted VoterID>
},
"gender": {
"value": <type:String, description:Gender of Holder>,
"conf": <type: Number, description: Confidence For extracted Gender>
},
"pin": {
"value": <type: String, description: Pincode of the Address of the holder>,
"conf": <type: Number, description: Confidence For extracted Pincode>
},
"dob": {
"value": <type:String, description: Date of Birth of Holder >,
"conf": <type: Number, description: Confidence For extracted Date of Birth>
},
"age": {
"value": <type:String, description: Age of the Holder>
"conf": <type: Number, description: Confidence For extracted Age>
},
"date": {
"value": <type:String, description: Date of Issue of VoterID>,
"conf": <type: Number, description: Confidence For extracted Date of Issue>
},
"type": {
"value": <type:String, description: Type of VoterID: Old/New>,
"conf": <type: Number, description: Confidence For extracted Type of VoterId>
},
"address": {
"district": <type: String, description: District of the address of the holder>,
"city": <type: String, description: City of the address of the holder>,
"locality": <type: String, description: Locality of the address of the holder>,
"landmark": <type: String, description: Landmark of the address of the holder>,
"street": <type: String, description: Street of the address of the holder>,
"line1": <type: String, description: Line1 of the address of the holder>,
"line2": <type: String, description: Line2 of the address of the holder>,
"house_number": <type: String, description: House Number of the address of the holder>,
"pin": <type: String, description: Pincode of the address of the holder>,
"state": <type: String, description: State of the address of the holder>,
"value": <type: String, description: Address of the holder>
"conf": <type: Number, description: Confidence For extracted Address>
},
"tag": <type: String, description: Unique identifier For extracted document sub-type>
Error Responses
The following are some error responses from the OCR API:
- Missing Document Input
- Multiple Documents Input
- Invalid File Size - 1
- Invalid File Size - 2
- Invalid PDF
{
"status": "failure",
"statusCode": "400",
"error": "API call requires one input image"
}
{
"status": "failure",
"statusCode": "400",
"error": "API call handles only one input image"
}
{
"status": "failure",
"statusCode": "400",
"error": "image size cannot be greater than 6MB"
}
{
"status": "failure",
"statusCode": "413",
"error": "File too large"
}
{
"status": "failure",
"statusCode": "400",
"error": "Invalid PDF"
}
The following snippets are response samples for a no document detected error across all the endpoints.
- Any Document (readKYC)
- Any Document (readPAN)
- Any Document (readAadhaar)
- Any Document (readPassport)
- Any Document (readVoterID)
- Any Document (readVoterID)
- Missing KYC Document
{
"status": "failure",
"statusCode": "422",
"error": "No supported KYC document detected"
}
{
"status": "failure",
"statusCode": "422",
"error": "No Pancard detected"
}
{
"status": "failure",
"statusCode": "422",
"error": "No Aadhaar detected"
}
{
"status": "failure",
"statusCode": "422",
"error": "No Passport detected"
}
{
"status": "failure",
"statusCode": "422",
"error": "No VoterID detected"
}
{
"status": "failure",
"statusCode": "422",
"error": "No VoterID detected"
}
If a new voter ID card is used for the request, the following error response is returned when the parameter shouldSupportNewVoterId is set to 'no' or not enabled.
{
"status": "failure",
"statusCode": "422",
"error": "No supported KYC document detected"
}
- Download Failed
- Time Out
- Size Issue
- Rate Limit
- Network Tampering
- Document Orientation
This following error response is returned only when the request contains the URL input is provided. It is returned when,
- URL contains an invalid domain.
- Invalid url is provided.
- Remote end is unreachable.
- Remote end resets connection.
{
"status": "failure",
"statusCode": "424",
"error": "Download from URL Failed"
}
This error response is returned only when the request contains a URL input. The timeout is set to 5 seconds.
{
"status": "failure",
"statusCode": "424",
"error": "Download from URL timed out"
}
{
"status": "failure",
"statusCode": "424",
"error": "Url contains an image of size larger than 12582912 bytes"
}
{
"status": "failure",
"statusCode": "429",
"error": "Requests rate limit exceeded"
}
{
"status": "failure",
"statusCode": "425",
"error": "Network tampering detected"
}
{
"status": "failure",
"statusCode": "433",
"error": "Document Not Horizontal"
}
Error Response Details
A failure or error response contains a failure status with a relevant status code and error message.
The following table lists all error responses:
| Status Code | Error Message | Error Description | Error Resolution |
|---|---|---|---|
| 400 | API call requires one input image / API call handles only one input image / image size cannot be greater than 6MB / Invalid PDF | The request is missing required input parameters, has multiple inputs, contains an invalid file size, or has an invalid PDF format | Provide exactly one input parameter (image, pdf, or url), ensure file size is within limits, and verify PDF format is valid |
| 413 | File too large | The uploaded file exceeds the maximum allowed size | Reduce the file size and try again |
| 422 | No supported KYC document detected / No Pancard detected / No Aadhaar detected / No Passport detected / No VoterID detected | The API could not detect a supported document type in the provided input | Ensure the input contains a valid, legible document image and that the document type is supported. For new voter ID cards, set shouldSupportNewVoterId to 'yes' |
| 424 | Download from URL Failed / Download from URL timed out / Url contains an image of size larger than 12582912 bytes | The URL provided could not be accessed, timed out, or contains a file that is too large | Verify the URL is publicly accessible, check network connectivity, ensure the file size is within limits, and try again |
| 425 | Network tampering detected | Network security issues were detected during the request | Check network security settings and try again |
| 429 | Requests rate limit exceeded | The API rate limit has been exceeded | Wait before making additional requests or contact HyperVerge to increase your rate limit |
| 433 | Document Not Horizontal | The document image is not in horizontal orientation, which is required for OCR processing | Rotate the document image to horizontal orientation and try again |