Guide

Submit KYC you've already collected

If your app has already done KYC for a user, send it to us in one call instead of making them repeat it. We check it, our team reviews it, and you get a webhook when it is approved or rejected.

This is off by default. Ask your OroPocket contact to switch on Accept partner KYC via raw API for your account. Until then the endpoint answers 403 PARTNER_KYC_NOT_ENABLED. On the hosted embed, use the kyc field on /partner/users/init instead.

This is the shortcut alternative to the step-by-step KYC endpoints (email, PAN, Aadhaar OTP). Use it when you already hold the user's verified PAN and Aadhaar record, for example from DigiLocker or an Aadhaar OKYC provider. Register the user first with POST /partner/users/init (flow: "api") to get their user_code.

1. Send the KYC

POST/partner/users/:user_code/kyc/submitkyc

Send the fields at the top level of the body, or wrapped as { "kyc": { … } } (the same object as the embed's kyc).

FieldTypeDescription
panstringrequiredIndividual PAN, e.g. ABCPK1234Z (the 4th character must be P). Case doesn't matter.
aadhaarstringrequiredThe full 12-digit Aadhaar number, or masked as "XXXXXXXX1234" (X, x or *; spaces and dashes are ignored).
aadhaar_dataobjectrequiredThe Aadhaar record your OKYC / DigiLocker provider returned, as JSON (keys below). Leave out the photo and the XML (64 KB limit).
dobstringrequiredDate of birth as YYYY-MM-DD. Must match the record; the user must be 18 or older.
emailstringrequiredThe user's email.
pan_namestringoptionalThe name on the PAN, if you have it. It must share a word with the Aadhaar name.
documentsobjectoptionalOptional images for our reviewer: pan_image, aadhaar_front, aadhaar_back. Each is base64, bare or as a data: URI, of a JPEG, PNG or PDF, up to 4 MB. Send any, all or none.

Keys we read from aadhaar_data:

KeyUse
name (required)The legal name. It becomes the user's name on OroPocket, their invoices and their holding certificate.
dob · date_of_birth · dateOfBirthDD-MM-YYYY, DD/MM/YYYY or YYYY-MM-DD. Must equal dob.
year_of_birthIf the record has only a year, it must match the year of dob.
masked_aadhaar · aadhaar_last4 · uidIf present, the last 4 digits must match aadhaar.
address (object) · split_addresshouse, street, landmark, vtc, district, state, pincode.
full_address · address (string)Kept as the full address.
gender · care_of · reference_idShown to our reviewer with the record.
curl -X POST https://api.oropocket.com/partner/users/usr_xxx/kyc/submit \
  -H "Authorization: Bearer oro_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "pan": "ABCPK1234Z",
    "aadhaar": "XXXXXXXX4321",
    "dob": "1990-08-15",
    "email": "asha@example.com",
    "pan_name": "ASHA KUMARI",
    "aadhaar_data": {
      "name": "Asha Kumari",
      "dob": "15-08-1990",
      "gender": "F",
      "care_of": "D/O Ram Kumar",
      "masked_aadhaar": "xxxxxxxx4321",
      "reference_id": "your-okyc-reference",
      "address": { "house": "12", "street": "MG Road", "vtc": "Pune", "state": "Maharashtra", "pincode": "411001" }
    },
    "documents": {
      "pan_image": "data:image/jpeg;base64,/9j/4AAQSk...",
      "aadhaar_front": "data:image/png;base64,iVBORw0KG..."
    }
  }'

The image type is read from the file itself, so a mislabelled data URI still works, and anything that isn't really a JPEG, PNG or PDF is refused. Keep the whole request under 10 MB.

2. The result

A KYC problem is a normal 200 response with status and a list of errors, so you can show the user what to fix.

Response
{
  "success": true,
  "request_id": "req_xxx",
  "mode": "live",
  "data": {
    "user_code": "usr_xxx",
    "status": "pending_review",
    "errors": [],
    "persisted": true,
    "documents_received": ["pan_image", "aadhaar_front"]
  }
}
statusMeaning
pending_reviewChecks passed and the KYC is saved for our team to review. persisted is true. Sending again while it is pending replaces it (replaced: true).
rejectedSomething didn't pass. errors lists every problem; nothing was saved.
already_verifiedThe user's OroPocket KYC is already approved. Nothing was changed.
already_under_reviewThe user already has KYC waiting for review that you didn't send (their own, or from another app). Nothing was changed.
validated_sandboxSandbox key: the data and documents passed the format checks. Nothing is saved, and no duplicate check runs.
Error codeMeaning
INVALID_PANNot a PAN, or not an individual's PAN.
INVALID_AADHAARNot 12 digits, fails the Aadhaar checksum, or not in the masked form.
AADHAAR_LAST4_MISMATCHThe last 4 digits differ from the ones in aadhaar_data.
INVALID_AADHAAR_DATAaadhaar_data is missing, has no name or date of birth, or is over 64 KB.
INVALID_DOB · DOB_MISMATCH · UNDER_18dob isn't a real date, differs from the record, or the user is under 18.
INVALID_EMAIL · EMAIL_IN_USENo valid email, or it belongs to a different OroPocket account.
NAME_MISMATCHpan_name and the Aadhaar name share no word.
PAN_IN_USE · AADHAAR_IN_USEAlready on a different OroPocket account.
INVALID_DOCUMENTA document isn't base64 of a JPEG, PNG or PDF, or has an unknown name.
DOCUMENT_TOO_LARGEA document is over 4 MB.

Error messages never repeat the values you sent. These refuse the request itself:

CodeMeaning
403 PARTNER_KYC_NOT_ENABLEDAccept partner KYC via raw API isn't on for your account.
403 API_NOT_ALLOWEDYour key doesn't have the kyc capability.
404 USER_CODE_NOT_FOUNDThe user_code isn't one of your users.

3. Review and webhooks

Our team reviews each submission against the Aadhaar record and any images, usually within a working day. While it is pending, GET /partner/users/:user_code/kyc/status returns status: "under_review" and source: "partner", and anything that needs approved KYC (such as INR withdrawals) stays blocked. When it has been reviewed we send a webhook:

  • kyc.approved: the user's KYC is approved.
  • kyc.rejected, with the reason. The PAN and Aadhaar are released and the images deleted, so you can submit corrected details, or the user can complete KYC in the app.
kyc.rejected
{
  "event": "kyc.rejected",
  "event_id": "evt_xxx",
  "created_at": "2026-10-14T10:12:00.000Z",
  "data": {
    "user_code": "usr_xxx",
    "status": "rejected",
    "reason": "The name on the PAN does not match the Aadhaar record."
  }
}

4. How we handle the data

  • The KYC is recorded as submitted by you, with your account against it, and is only approved by our team.
  • We keep the PAN, the Aadhaar number (only the last 4 digits when you send it masked), the name, date of birth, gender, address and email. Photos, XML, signatures and share codes inside aadhaar_data are dropped.
  • Document images are stored privately and seen only by our reviewers. They are never at a public URL, and are deleted if the KYC is rejected.
  • Request bodies are never written to your request logs, and our own logs carry masked values only.
  • Send only KYC you have actually verified, with the user's consent to share it with OroPocket.