KYC Forms API (Early access)
The KYC Forms API lets a partner submit or modify KYC details of their investors. Currently, Cybrilla POA supports only modification of existing KYC records. The modification of KYC record will be supported if the investors' KYC status at the KRA is one of the below -
validatedverifiedorregisteredonhold
Workflow to Modify a particular KYC Record
- As a good practice, first check the KYC status of the investor using the PAN number. If the KYC status is one of the above mentioned ones, only then intiate a KYC Form with
type = modify - Create a KYC Form with
type = modifyby givingpan,name,date_of_birth,proof_details_callback_urlandesign_callback_url. At this stage,kyc_formobject will be created withunder_reviewstate. Internally Cybrilla will decide if the particular KYC record linked against the given PAN is eligible for KYC Modification or not. If not eligible,kyc_formwill move intofailedstate withreason = ineligible_for_kyc_modificationproof_details_callback_urlwill take in the URL where you want the investor to redirect back after the Digilocker journeyesign_callback_urlwill take in the URL where you want the investor to redirect back after the esign journey- Please note that
pan,nameanddate_of_birthshould be as per ITD / PAN records
- If the KYC record is eligible to be modified, then
kyc_formwill move intocreatedstate. Now, you need to provide all the details needed to complete the form. You can refer torequirements.fields_neededarray to figure out the pending details. - You will also see a redirection URL present in the
proof_details.fetch_urlattribute. Use this URL to redirect your investor into the Digilocker page and the investor has to complete the journey to fetch Aadhaar details. Once Aadhaar details are fetched, the same will be used as both Identity and Address proofs.
4.1. In case the proof details fetch fails due to some reason, you can retry the same usingRetry proof details fetchAPI.
4.2. Note that you can use this Retry proof details fetch API only ifproof_details.status = failed. - You also need to collect a photocopy of the investor's wet signature to complete the workflow. Once you have the same, you need to use the
Upload Signature to KYC FormAPI to upload the signature file to Cybrilla. - Once you have provided all the details to Cybrilla,
requirements.fields_neededin thekyc_formobject will benull. Now,kyc_formwill move intoawaiting_esignstate. - Refer to
esign_details.esign_urlattribute to get the esign redirection link where the investor should complete the esign journey. Once this is completed successfully,kyc_formwill move intoawaiting_submissionstate.
7.1.kyc_formcan move intoawaiting_submissionstate only ifesign_details.statusis insuccessfulstate.
7.2. You can retry this URL as long as the investor can make a successful esign. - Internally Cybrilla will attempt to submit this KYC Form to the KRA and based on this,
kyc_formwill move into eithersubmittedorfailedstate. If it moves into afailedstate, you can refer to thereasonattribute for more details. - If suppose investor is not taking any action to complete the KYC Form within 7 days since its creation,
kyc_formwill move intoexpiredstate. You can refer toexpires_atattribute to get to know the expiry date and time. If the investor wants to modify the KYC record at a later date, a newkyc_formhas to be created and this same workflow has to be followed.
NOTE: You can create a
kyc_formobject only if there is no on-goingkyc_formfor the given PAN.
Note on KYC Form reviewing the investor's eligibility
- KYC Form once created, will be in
under_reviewstate. Here a bunch of checks are performed internally to check the eligibility of the investor trying to submit the form. - If the investor is trying to push a KYC Form with
type = modify, then Cybrilla will check below items and take necessary actions -
| Scenario | Type of KYC Form | Action taken |
|---|---|---|
| Investor's KYC is - validated - verified or registered - onhold | modify | Cybrilla will allow such investors to submit Modify KYC Form |
| Investor's KYC is other than - validated - verified or registered - onhold | modify | Cybrilla will not allow such investors to submit Modify KYC Form |
| Investor's PAN details do not match with ITD/PAN database | modify | Cybrilla will not allow such investors to submit Modify KYC Form |
KYC Form object
{
"object": "kyc_form",
"id": "kycf_2de2a1df94614d048000dd101a566925",
"type": "modify",
"status": "created",
"reason": null,
"pan": "AAAPA3751A",
"name": "John Doe",
"date_of_birth": "2000-01-02",
"email_address": "joyboy@myself.com",
"phone_number": "9876543210",
"residential_status": "resident",
"gender": "male",
"marital_status": "unmarried",
"father_name": "Davy Johns",
"spouse_name": null,
"occupation_type": "private_sector_service",
"aadhaar_number": "1210",
"country_of_birth": "in",
"place_of_birth": "in",
"income_slab": "above_10lakh_upto_25lakh",
"pep_details": "no_exposure",
"citizenship_countries": [
"in"
],
"nationality_country": "in",
"tax_residency_other_than_india": false,
"non_indian_tax_residency_1": null,
"non_indian_tax_residency_2": null,
"non_indian_tax_residency_3": null,
"signature_provided": false,
"proof_details": {
"fetch_url": "https://s.finprim.com/identity_documents/fetch_my_proof",
"status": "pending"
},
"proof_details_callback_url": "https://myapp.com/proof_details_callback",
"identity": {
"proof_type": null
},
"address": {
"proof_type": null
},
"geolocation": {
"latitude": 9.354,
"longitude": 77.453
},
"esign_details": {
"esign_url": null,
"status": null
},
"esign_callback_url": "https://myapp.com/esign_callback",
"requirements": {
"fields_needed": [
"identity_proof",
"address",
"signature"
]
},
"created_at": "2025-12-23T12:41:06.649Z",
"updated_at": null,
"review_completed_at": "2025-12-23T12:41:07.649Z",
"awaiting_esign_at" : null,
"awaiting_submission_at": null,
"submitted_at": null,
"failed_at": null,
"expires_at": "2025-12-30T12:41:06.649Z"
}
KYC Form Object parameters
| Attribute | Type | Remarks |
|---|---|---|
| object | string | Value will always be kyc_form. Objects of the same type share the same value |
| id | string | Unique identifier of the kyc_form object |
| type | enum | Type of the KYC Form. Possible values are - modify |
| status | string | Indicates the what status of pre verification - under_review - Cybrilla is internally checking the eligibility for the type of KYC form initiated- created - KYC form is created and the data can be provided as indicated in requirements.fields_needed array- awaiting_esign - The KYC form is completely filled up and the invesor has to esign the same in-order to submit it to the processing entity- awaiting_submission - Cybrilla is attempting to submit the esigned KYC form to the processing entity- submitted - The esigned KYC form is submitted to the processing entity- failed - KYC form failed to successfully reach an end state. Refer to reason for more details- expired - KYC form is expired since investor did not take any action on it |
| reason | string | The reason why kyc_form is in a failed state |
| pan | string | PAN number of the investor |
| name | string | Name of the investor |
| date_of_birth | String | Date of birth of the investor |
| email_address | string | Email address of the investor |
| phone_number | string | Phone number of the investor |
| residential_status | enum | Investor's residential status. Possible values are - resident |
| gender | enum | Investor's gender. Possible values are - male, female and transgender |
| marital_status | enum | Marital status of the investor. Possible values are married, unmarried and others |
| father_name | string | Investor's father's name. Needed only if marital_status is umarried or others |
| spouse_name | string | Investor's spouse's name. Needed only if marital_status is married |
| occupation_type | enum | Investor's occupation. Possible values are - business, professional, retired, housewife, student, public_sector_service, private_sector_service, government_service, agriculture, doctor, forex_dealer, service, others |
| aadhaar_number | string | Last 4 digits of investor's Aadhaar number |
| country_of_birth | string | Investor's country of birth. ISO country code will be present |
| place_of_birth | string | Investor's place of birth |
| income_slab | enum | Investor's income slab. Possible values are - upto_1lakh, above_1lakh_upto_5lakh, above_5lakh_upto_10lakh, above_10lakh_upto_25lakh, above_25lakh_upto_1cr, above_1cr |
| pep_details | string | Investor's political exposure details. Possible values are - pep - Politically exposed- related_pep - Related to a politically exposed person- no_exposure - No political exposure |
| citizenship_countries | array | List of countries where the investor has a citizenship |
| nationality_country | string | ANSI code of investor's country of nationality |
| tax_residency_other_than_india | boolean | If investor is a tax payer in any country other than India, such details will be indicated here. Possible values are true or false |
| non_indian_tax_residency_1 | hash | If investor is a tax payer in any country other than India, such details will be mentioned here |
| non_indian_tax_residency_2 | hash | If investor is a tax payer in any country other than India, such details will be mentioned here |
| non_indian_tax_residency_3 | hash | If investor is a tax payer in any country other than India, such details will be mentioned here |
| signature_provided | boolean | Indicates if the photocopy of the signature has been uploaded against this kyc_form or not. Possbile values are true or false |
| proof_details | hash | This will give the details on the status of fetching proof details that will be submitted against the kyc_form |
| proof_details_callback_url | string | The callback URL where the investor will be redirected to post proof fetch workflow |
| identity | hash | Identity proof details. This will have the proof_type that was captured. Possible values are aadhaar |
| address | hash | Address proof details. This will have the proof_type that was captured. Possible values are aadhaar |
| geo_location | hash | Geo-location of the investor from where this KYC form is being filled up and submitted |
| esign_details | hash | This will give the details on the status of the esign workflow |
| esign_callback_url | string | The callback URL where the investor will be redirected to post esign workflow |
| requirements | hash | Feedback on the data requirements. It contains fields_needed array which represent the list of fields that are required for procesing the KYC Form |
| created_at | string | The timestamp at which the kyc_form object was created with under_review state |
| updated_at | string | The timestamp at which the kyc_form object was updated with any value |
| review_completed_at | string | The timestamp at which the kyc_form object moved into created state from under_review state |
| awaiting_esign_at | string | The timestamp at which the kyc_form object moved into awaiting_esign state |
| awaiting_submission_at | string | The timestamp at which the kyc_form object moved into awaiting_submission state |
| submitted_at | string | The timestamp at which the kyc_form object moved into submitted state |
| failed_at | string | The timestamp at which the kyc_form object moved into failed state |
| expires_at | string | The timestamp at which the kyc_form object will move into expired state |
Non Indian Tax Residency hash
| Attribute | Type | Comments |
|---|---|---|
| country | string | ANSI code of investor's country of tax residency |
| taxid_number | string | Valid Tax Identification number issued in the above mentioned country |
Proof details hash
| Attribute | Type | Comments |
|---|---|---|
| fetch_url | string | URL to redirect your investor into the Digilocker page |
| status | string | Status of the proof fetch. Possible values are - pending, fetched and failed |
Geo-location hash
| Attribute | Type | Comments |
|---|---|---|
| latitude | float | Value of the Latitude |
| longitude | float | Value of the Longitude |
Esign details hash
| Attribute | Type | Comments |
|---|---|---|
| esign_url | string | URL to redirect your investor to complete esign workflow |
| status | string | Status of the proof fetch. Possible values are - pending, and successful |
Create KYC Form API
POST /poa/kyc_forms
This API lets you create a KYC form object.
curl --location --request POST '{{base_url}}/poa/kyc_forms' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"type": "modify",
"pan": "AAAPA3751A",
"name": "John Doe",
"date_of_birth": "2000-01-02",
"proof_details_callback_url": "https://myapp.com/proof_details_callback",
"esign_callback_url": "https://myapp.com/esign_callback"
}'
Request parameters
| Name | Mandatory to create kyc_form object | Mandatory to submit kyc_form details | Type | Comments |
|---|---|---|---|---|
| type | yes | yes | enum | Type of the KYC Form. Allowed values are - modify |
| pan | yes | yes | string | PAN number of the investor. This should be in the format AAAPANNNNA where A can be any alphabet and N can be any number |
| name | yes | yes | string | Name of the investor. This should not contain any special characters |
| date_of_birth | yes | yes | string | Date of birth of the investor in the format yyyy-mm-dd |
| proof_details_callback_url | yes | yes | string | The callback URL where the investor will be redirected to post proof fetch workflow |
| esign_callback_url | yes | yes | string | The callback URL where the investor will be redirected to post esign workflow |
| email_address | no | yes | string | Email address of the investor |
| phone_number | no | yes | string | Phone number of the investor |
| residential_status | no | yes | enum | Investor's residential status. Allowed values are - resident |
| gender | no | yes | enum | Investor's gender. Allowed values are - male, female and transgender |
| marital_status | no | yes | enum | Marital status of the investor. Allowed values are married, unmarried and others |
| father_name | no | conditional | string | Investor's father's name. Needed only if marital_status is umarried or others |
| spouse_name | no | conditional | string | Investor's spouse's name. Needed only if marital_status is married |
| occupation_type | no | yes | enum | Investor's occupation. Allowed values are - business, professional, retired, housewife, student, public_sector_service, private_sector_service, government_service, agriculture, doctor, forex_dealer, service, others |
| aadhaar_number | no | yes | string | Last 4 digits of investor's Aadhaar number |
| country_of_birth | no | yes | string | Investor's country of birth. ISO country code should be provided |
| place_of_birth | no | yes | string | Investor's place of birth. Length is allowed upto 60 characters |
| income_slab | no | yes | enum | Investor's income slab. Allowed values are - upto_1lakh, above_1lakh_upto_5lakh, above_5lakh_upto_10lakh, above_10lakh_upto_25lakh, above_25lakh_upto_1cr, above_1cr |
| pep_details | no | yes | string | Investor's political exposure details. Allowed values are - pep - Politically exposed- related_pep - Related to a politically exposed person- no_exposure - No political exposure |
| citizenship_countries | no | yes | array | List of countries where the investor has a citizenship. Currently only one value is supported. You need to pass the ANSI code of the citizenship country |
| nationality_country | no | yes | string | ANSI code of investor's country of nationality |
| tax_residency_other_than_india | no | yes | boolean | If investor is a tax payer in any country other than India, such details will be indicated here. Possible values are true or false |
| non_indian_tax_residency_1 | no | yes | hash | If investor is a tax payer in any country other than India, such details will be mentioned here. Mandatory if tax_residency_other_than_india is true |
| non_indian_tax_residency_2 | no | yes | hash | If investor is a tax payer in any country other than India, such details will be mentioned here |
| non_indian_tax_residency_3 | no | yes | hash | If investor is a tax payer in any country other than India, such details will be mentioned here |
| geo_location | no | yes | hash | Geo-location of the investor from where this KYC form is being filled up and submitted. Ensure that this in within India |
Non Indian Tax Residency hash
| Attribute | Mandatory | Type | Comments |
|---|---|---|---|
| country | yes | string | ANSI code of investor's country of tax residency |
| taxid_number | yes | string | Valid Tax Identification number issued in the above mentioned country |
Geo-location hash
| Attribute | Mandatory | Type | Comments |
|---|---|---|---|
| latitude | yes | float | Value of the Latitude |
| longitude | yes | float | Value of the Longitude |
NOTE: Even though some of the above parameters are marked as non-mandatory for the kyc_form object creation, all those are needed to submit the kyc_form to the KRA.
The
kyc_formobject will be returned as the response.
Note on KYC Form object events
- Events are triggered upon
statuschanges that happen onkyc_formobject. - Types of events -
kyc_form.under_reviewkyc_form.createdkyc_form.awaiting_esignkyc_form.awaiting_submissionkyc_form.submittedkyc_form.failedkyc_form.expiredkyc_form.updated
- For more details, check Webhook notifications page.
Update KYC Form API
PATCH /poa/kyc_forms
This API lets you update a KYC form object.
curl --location --request PATCH '{{base_url}}/poa/kyc_forms' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--data '{
"id": "{{kyc_form_id}}",
"gender": "male",
"marital_status": "unmarried"
}'
Request parameters
| Name | Mandatory | Type | Comments |
|---|---|---|---|
| id | yes | string | ID of the kyc_form object which has to be updated |
NOTE: Other parameters are same as Create KYC Form API request parameters. Ensure that all the listed fields in requirements.fields_needed array are updated.
The
kyc_formobject will be returned as the response.
Fetch KYC Form API
This API lets you fetch a KYC Form object.
curl --location --request GET '{{base_url}}/poa/kyc_forms/{{kyc_form_id}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
Query parameters
| Name | Mandatory | Type | Comments |
|---|---|---|---|
| id | yes | string | ID of the kyc_form object which has to be updated |
The
kyc_formobject will be returned as the response.
Upload Signature to KYC Form API
This API lets you update a signature file to the KYC Form object.
curl --location --request POST '{{base_url}}/poa/kyc_forms/{{kyc_form_id}}/signature' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <token>' \
--form 'file=@"/Users/guessmyname/Downloads/WhiteAndBlackSignature.jpg"'
NOTE:
- Once you have uploaded the signature to
kyc_formobject,signature_providedwill be marked astrue. - Supported file formats:
png,jpg,jpegandpdf - Supported file size: Upto 5 MB
The
kyc_formobject will be returned as the response.
Retry proof details fetch API
This API lets you get a new URL to fetch proof_details. You can use this API only if proof_details.status is in a failed state.
curl --location --request POST '{{base_url}}/poa/kyc_forms/{{kyc_form_id}}/retry_proof_details_fetch' \
--header 'Content-Type: application/json' \
--header 'x-tenant-id: cybrillarta' \
--header 'Authorization: Bearer <token>'
The
kyc_formobject will be returned as the response.
Testing
In sandbox, simulation facility can be used to test the submission of KYC Forms workflows. This facility is only available in sandbox.
| Scenario | PAN format | KYC Form Status | Description |
|---|---|---|---|
| KRA accepted the KYC Form | XXXPXNNNNX | submitted | This will simulate a successful submission of KYC Form to the KRA. Use this pattern of PAN where X denotes any alphabet and N denotes any number |
| KRA rejected the KYC Form | XXXPXNNNNR | failed | This will simulate a failed submission of KYC Form to the KRA. Use this pattern of PAN where X denotes any alphabet and N denotes any number |
NOTE:
- To simulate various KYC Statuses, you can use the same testing scenarios present in KYC Check section. Here is the link to that.
- While you use the KYC Check simulations, you can also use the above mentioned KYC Form submission simulation as a part of the same input, to test out multiple scenarios.