CKYC Verification
3 endpoints · Core API
CKYC (Central Know Your Customer) Verification is a centralized KYC process managed by the Central Registry of Securitisation Asset Reconstruction and Security Interest (CERSAI). It allows financial institutions to verify a customer's identity using a unique CKYC number (CKYC ID) without requiring the customer to submit KYC documents repeatedly.
Benefits
- 1. Centralized KYC repository: CKYC stores customer KYC records in a single, secure registry accessible by authorized institutions.
- 2. Reduced duplication: Eliminates the need for customers to submit KYC documents multiple times across different financial entities.
- 3. Faster onboarding: Speeds up customer verification and account opening processes.
- 4. Regulatory compliance: Ensures adherence to KYC norms defined by regulatory authorities.
- 5. Secure and reliable: Maintains standardized and verified customer data, reducing fraud risk.
What you can do
This API allows you to fetch and verify customer KYC details using a CKYC number or input data such as PAN or Aadhaar (as permitted). It helps in retrieving identity details, address information, and KYC status, enabling seamless onboarding and compliance for financial applications.
Search for an individual's CKYC record by identifier type and value (e.g., PAN, Voter ID, CKYC number).
This API is used to search the CKYC registry for individual records using a specific identifier. It returns a client_id, a list of matched records, and the total record count.
The API automatically normalizes the id_type, validates the identifier, and returns results in an array-based structure.
Request Body Parameters:
→ id_type (required): Identifier type used for CKYC search. Send one of the lowercase values listed below exactly as shown; any other value, including a different letter case, is rejected with 400.
→ id_number (required): The identifier value for the selected id_type. Its format is checked against the id_type (see the format listed against each value below); a mismatch is rejected with 400.
Supported id_type Values:
→ passport: Passport number, 1 letter followed by 7 digits (A1234567)
→ voter_id: Voter ID (EPIC), 3 letters followed by 7 digits
→ pan: PAN, 10 characters in the format AAAAA9999A (e.g., ABCDE1234F)
→ driving_license: Driving licence number, 2-letter state code followed by 13 digits (15 characters)
→ aadhaar_proof: Aadhaar number, exactly 12 digits
→ nrega_job_card: NREGA job card number, 5 to 30 characters (letters, digits, hyphen, slash)
→ npr_letter: NPR letter number, 5 to 20 letters or digits
→ ckyc_number: CKYC number, exactly 14 digits
→ ckyc_reference_id: CKYC reference ID, exactly 14 letters or digits (usually starts with IN)
→ mobile_number: Registered mobile number, exactly 10 digits
Important Notes:
→ id_type is case-sensitive. Values such as "PAN" or "Driving License" are not accepted; use "pan" or "driving_license".
→ consent and consent_text are also required (send "Y" and the standard consent text); request_id is optional.
Flow:
-
Call this API with id_type and id_number.
-
Review the returned records array.
-
Select the correct record.
-
Use its ckyc_identifier to initiate the download API.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- consentstringrequiredRequired. The end user's consent to this verification. Send `Y`.minLength 1default Y
- consent_textstringrequiredRequired. The consent statement shown to the end user. Send the default text from the sample.minLength 1default I hear by declare my consent agreeme…
- request_idstringoptionalOptional. Your own id to correlate this call in your logs. A unique id is generated if you leave it out.nullable
- id_typestringrequiredRequired. Identifier type. Lowercase only; one of "pan", "passport", "voter_id", "driving_license", "aadhaar_proof", "nrega_job_card", "npr_letter", "ckyc_number", "ckyc_reference_id", "mobile_number".minLength 1pattern ^(pan|passport|voter_id|driving_license|…default pan
- id_numberstringrequiredRequired. Identifier value to search for. Its format must match id_type (for example 10-character PAN AAAAA9999A, 12-digit Aadhaar, 14-digit CKYC number, 10-digit mobile number).minLength 1default ABCDE1234F
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalData payload returned from a successful CKYC individual search.
3 fields
- client_idstringoptionalNo description.nullable
- recordsarray<object>optionalNo description.nullable
Each item: 15 fields
- ckyc_identifierstringoptionalNo description.nullable
- ckyc_nostringoptionalNo description.nullable
- ckyc_reference_idstringoptionalNo description.nullable
- namestringoptionalNo description.nullable
- fathers_namestringoptionalNo description.nullable
- constitution_typestringoptionalNo description.nullable
- agestringoptionalNo description.nullable
- mob_codeinteger (int32)optionalNo description.nullable
- mob_numstringoptionalNo description.nullable
- image_typestringoptionalNo description.nullable
- photostringoptionalNo description.nullable
- kyc_datestringoptionalNo description.nullable
- updated_datestringoptionalNo description.nullable
- id_listarray<object>optionalNo description.nullable
Each item: 5 fields
- typestringoptionalNo description.nullable
- type_codestringoptionalNo description.nullable
- type_valuestringoptionalNo description.nullable
- statusstringoptionalNo description.nullable
- status_valuestringoptionalNo description.nullable
- remarksstringoptionalNo description.nullable
- record_countinteger (int32)optionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
429Too Many Requests
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataanyoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Initiate individual CKYC download.
Initiate an individual CKYC download. This endpoint validates the selected ckyc_identifier and registered mobile_number, then asks CKYC to send an OTP to the registered mobile number.
Use this endpoint after POST api/v1/ckyc/search/individual. The search response gives you records[].ckyc_identifier; pass that value here.
The important continuation value is data.request_id. Store it and use it with POST api/v1/ckyc/download/individual to submit the OTP or request an OTP resend. The client_id is a transaction identifier.
Request Body Parameters:
→ ckyc_identifier (required): CKYC identifier from search. Exactly 14 letters or digits: a CKYC reference ID such as INRMFE49270123 or a 14-digit CKYC number, depending on what search returned.
→ mobile_number (required): 10-digit mobile number registered with the individual CKYC record.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- consentstringrequiredRequired. The end user's consent to this verification. Send `Y`.minLength 1default Y
- consent_textstringrequiredRequired. The consent statement shown to the end user. Send the default text from the sample.minLength 1default I hear by declare my consent agreeme…
- request_idstringoptionalOptional. Your own id to correlate this call in your logs. A unique id is generated if you leave it out.nullable
- ckyc_identifierstringrequiredRequired. CKYC identifier from search: exactly 14 letters or digits (a CKYC reference ID or a 14-digit CKYC number).minLength 1pattern ^[A-Za-z0-9]{14}$default 12345678901234
- mobile_numberstringrequiredRequired. 10-digit mobile number registered with the CKYC record. The OTP is sent to this number.minLength 1pattern ^\d{10}$default 9876543210
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalData returned after a successful CKYC download initiate.
4 fields
- client_idstringoptionalTransaction ID for this initiate call.nullable
- request_idstringoptionalCKYC request ID. Pass this in the OTP submit/resend endpoint.nullable
- statusstringoptionalWorkflow status: "otp_sent", "otp_resent", or "downloaded".nullable
- ckyc_download_dataobjectoptionalA single CKYC record returned from search or download.
15 fields
- ckyc_identifierstringoptionalNo description.nullable
- ckyc_nostringoptionalNo description.nullable
- ckyc_reference_idstringoptionalNo description.nullable
- namestringoptionalNo description.nullable
- fathers_namestringoptionalNo description.nullable
- constitution_typestringoptionalNo description.nullable
- agestringoptionalNo description.nullable
- mob_codeinteger (int32)optionalNo description.nullable
- mob_numstringoptionalNo description.nullable
- image_typestringoptionalNo description.nullable
- photostringoptionalNo description.nullable
- kyc_datestringoptionalNo description.nullable
- updated_datestringoptionalNo description.nullable
- id_listarray<object>optionalNo description.nullable
Each item: 5 fields
- typestringoptionalNo description.nullable
- type_codestringoptionalNo description.nullable
- type_valuestringoptionalNo description.nullable
- statusstringoptionalNo description.nullable
- status_valuestringoptionalNo description.nullable
- remarksstringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
429Too Many Requests
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataanyoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500
Code samplescurl · Node.js · Python
Complete individual CKYC download.
Complete an individual CKYC download after OTP initiation. Use this endpoint in one of two modes:
→ Submit the OTP with request_id and otp.
→ Request another OTP with request_id and resend: true.
The request_id comes from POST api/v1/ckyc/download/individual/initiate. Do not use client_id for OTP submission.
When OTP validation succeeds, the response status is downloaded and data.ckyc_download_data contains the CKYC record.
Request Body Parameters:
→ request_id (required): CKYC request ID returned by the initiate endpoint (data.request_id). Digits only.
→ otp (conditional): Required when you are submitting an OTP (omit when resend is true). Exactly 6 digits, received on the registered mobile number.
→ resend (conditional): Required (as true) when you are requesting another OTP instead of submitting one. Boolean.
Provide either otp or resend: true, not both. A request with neither value is rejected.
Headers
- X-API-KEYstringrequiredYour secret API key for the environment you are calling (Stage and Live use different keys).
- X-API-APP-IDstringrequiredThe App ID issued together with the key.
- Content-Typestringrequiredapplication/json
Body parameters
application/json- otpstringconditionalConditional: required when submitting an OTP (omit when resend is true). Exactly 6 digits, received on the registered mobile number.nullablepattern ^\d{6}$default 968284
- resendbooleanconditionalConditional: required (as true) when requesting a fresh OTP instead of submitting one. Do not send otp together with resend.nullable
- request_idstringrequiredRequired. CKYC request ID returned by the initiate endpoint (data.request_id). Digits only.minLength 1pattern ^\d+$
Sample request body
Responses
200OK
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataobjectoptionalTop-level data returned from the CKYC individual download endpoint.
4 fields
- client_idstringoptionalNo description.nullable
- request_idstringoptionalNo description.nullable
- statusstringoptionalotp_resent or downloaded.nullable
- ckyc_download_dataobjectoptionalNo description.
2 fields
- record_count_detailsobjectoptionalNo description.
2 fields
- download_countstringoptionalNo description.nullable
- update_countstringoptionalNo description.nullable
- personal_identifiable_dataobjectoptionalNo description.
4 fields
- personal_detailsobjectoptionalNo description.
54 fields
- constitution_typestringoptionalNo description.nullable
- account_typestringoptionalNo description.nullable
- prefixstringoptionalNo description.nullable
- first_namestringoptionalNo description.nullable
- mnamestringoptionalNo description.nullable
- last_namestringoptionalNo description.nullable
- full_namestringoptionalNo description.nullable
- father_or_spousestringoptionalNo description.nullable
- father_fullnamestringoptionalNo description.nullable
- mother_fullnamestringoptionalNo description.nullable
- genderstringoptionalNo description.nullable
- dobstringoptionalNo description.nullable
- panstringoptionalNo description.nullable
- perm_line1stringoptionalNo description.nullable
- perm_line2stringoptionalNo description.nullable
- perm_line3stringoptionalNo description.nullable
- perm_citystringoptionalNo description.nullable
- perm_diststringoptionalNo description.nullable
- perm_statestringoptionalNo description.nullable
- perm_pinstringoptionalNo description.nullable
- perm_countrystringoptionalNo description.nullable
- corres_line1stringoptionalNo description.nullable
- corres_line2stringoptionalNo description.nullable
- corres_line3stringoptionalNo description.nullable
- corres_citystringoptionalNo description.nullable
- corres_diststringoptionalNo description.nullable
- corres_statestringoptionalNo description.nullable
- corres_pinstringoptionalNo description.nullable
- corres_countrystringoptionalNo description.nullable
- perm_corres_sameflagstringoptionalNo description.nullable
- perm_poastringoptionalNo description.nullable
- corres_poastringoptionalNo description.nullable
- mob_codestringoptionalNo description.nullable
- mob_numstringoptionalNo description.nullable
- emailstringoptionalNo description.nullable
- dec_datestringoptionalNo description.nullable
- dec_placestringoptionalNo description.nullable
- kyc_datestringoptionalNo description.nullable
- kyc_namestringoptionalNo description.nullable
- kyc_designationstringoptionalNo description.nullable
- kyc_branchstringoptionalNo description.nullable
- kyc_empcodestringoptionalNo description.nullable
- num_identityinteger (int32)optionalNo description.
- num_relatedinteger (int32)optionalNo description.
- num_imagesinteger (int32)optionalNo description.
- ckyc_nostringoptionalNo description.nullable
- ckyc_reference_idstringoptionalNo description.nullable
- doc_substringoptionalNo description.nullable
- doc_sub_valuestringoptionalNo description.nullable
- resi_statusstringoptionalNo description.nullable
- resi_status_valuestringoptionalNo description.nullable
- dis_flagstringoptionalNo description.nullable
- dis_typestringoptionalNo description.nullable
- dis_type_valuestringoptionalNo description.nullable
- identity_detailsobjectoptionalNo description.
1 field
- identityarray<object>optionalNo description.nullable
Each item: 5 fields
- identity_numberstringoptionalNo description.nullable
- identity_typestringoptionalApp-facing enum value, e.g. PAN, AADHAAR, PASSPORT.nullable
- identity_type_codestringoptionalRaw CERSAI type code, e.g. C for PAN, E for Aadhaar proof.nullable
- identity_type_valuestringoptionalHuman-readable document label. Use for display.nullable
- id_verification_statusstringoptionalYES when CKYC status code is 01, otherwise NO.nullable
- related_person_detailsobjectoptionalNo description.
1 field
- related_personarray<object>optionalNo description.nullable
Each item: 12 fields
- rel_typestringoptionalNo description.nullable
- rel_type_valuestringoptionalNo description.nullable
- genderstringoptionalNo description.nullable
- gender_valuestringoptionalNo description.nullable
- perm_poi_typestringoptionalNo description.nullable
- perm_poi_type_valuestringoptionalNo description.nullable
- corres_poi_typestringoptionalNo description.nullable
- corres_poi_type_valuestringoptionalNo description.nullable
- resi_statusstringoptionalNo description.nullable
- resi_status_valuestringoptionalNo description.nullable
- dis_typestringoptionalNo description.nullable
- dis_type_valuestringoptionalNo description.nullable
- image_detailsobjectoptionalNo description.
1 field
- imagearray<object>optionalNo description.nullable
Each item: 5 fields
- image_codestringoptionalDisplay label, e.g. Photograph, PAN, NREGA Job Card.nullable
- image_typestringoptionalFile type, e.g. jpg or pdf.nullable
- image_datastringoptionalBase64-encoded image or document data.nullable
- global_flagstringoptionalNo description.nullable
- global_flag_valuestringoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
400Bad Request
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 400
401Unauthorized
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 401
429Too Many Requests
- successbooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 200
- messagestringoptionalNo description.nullabledefault XXXXX
- dataanyoptionalNo description.nullable
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- isBillablebooleanoptionalWhether this request was charged: true if it was, false if not. Errors always show false. Flows that finish later (ITR Fetch, SHCIL eStamp, DigiLocker, eSign) show false here, because the charge is made when the result is ready. eSign charges each signer when they complete signing. DigiLocker deducts the credit when the link is created and refunds it automatically if the link expires before the user completes it.
500Internal Server Error
- dataobjectoptionalNo description.
- messagesarray<string>optionalNo description.nullable
- request_idstringoptionalNo description.nullable
- successbooleanoptionalNo description.default false
- messagestringoptionalNo description.nullabledefault XXXXX
- isBillablebooleanoptionalNo description.
- statusCodeinteger (int32)optionalNo description.default 500