> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dollarpe.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# KYC sharing

> Submit KYC data you already verified, then fix failures one check at a time.

Use KYC sharing if you already verify your users. You collect the documents and submit the verified data to Zapyd. Zapyd stores it and runs its own compliance checks.

<Note>
  KYC sharing accepts customers from India (`IND`). For US customers, use the [KYC SDK](/guides/customers/kyc-sdk).
</Note>

## Flow

```mermaid theme={null}
flowchart LR
    A[Create customer] --> B[Get KYC configuration]
    B --> C[POST add-kyc-data]
    C --> D{CUSTOMER webhook}
    D -->|VERIFIED| E[Add bank account]
    D -->|FAILED| F[Update the failed part]
    F --> D
```

## 1. Create the customer

Create a customer with [`POST /customer/create`](/api-reference-exchange/endpoint/customer/create) and save its `id`. See [the customer object](/guides/customers/overview#the-customer-object).

## 2. Get the KYC configuration

Your organization's configuration decides which documents are accepted and which extra fields you must send. Read it once per customer country.

<CodeGroup>
  ```http Request theme={null}
  GET /cms/api/v1/kyc/configuration/{customer_id}
  ```

  ```json Response theme={null}
  {
    "status": true,
    "message": "Success",
    "data": {
      "supported_document_types": ["AADHAAR", "PASSPORT", "VOTER_ID", "DRIVING_LICENSE"],
      "additional_info_required": {
        "options": ["income_range", "profession"],
        "rules": { "type": "allOf", "min_required": 2 },
        "income_range": { "type": "string", "required": true },
        "profession": { "type": "string", "required": true }
      }
    }
  }
  ```
</CodeGroup>

| Field | Meaning |
| - | - |
| `supported_document_types` | Allowed values for `document_type` |
| `additional_info_required.options` | Field names you can send inside `additional_info` |
| `additional_info_required.rules` | `allOf` or `anyOf`, and `min_required`: the minimum number of those fields to send |
| `additional_info_required.<field>` | The field's `type` (`string` or `url`) and whether it's `required` |

## 3. Submit the KYC data

Send the verified data with [`POST /kyc/add-kyc-data`](/api-reference-exchange/endpoint/kyc/add-kyc-data). The customer moves to `PROCESSING`.

<CodeGroup>
  ```json Request theme={null}
  {
    "customer_id": "075986f3-282b-4555-bfcd-fad973e32596",
    "full_name": "Priya Sharma",
    "phone": "9911002211",
    "full_address": "12 MG Road, Bengaluru, Karnataka 560001",
    "dob": "15-08-1992",
    "registered_date": "01-01-2025",
    "tax_number": "ABCDE1234F",
    "document_type": "PASSPORT",
    "document_front_image_url": "https://files.example.com/kyc/passport-front.jpg",
    "document_back_image_url": "https://files.example.com/kyc/passport-back.jpg",
    "document_details": { "document_number": "P1234567" },
    "selfie_url": "https://files.example.com/kyc/selfie.jpg",
    "ip_address": "203.0.113.10",
    "additional_info": { "income_range": "<10L", "profession": "Engineer" }
  }
  ```

  ```json Response theme={null}
  {
    "status": true,
    "message": "Success",
    "data": {
      "id": "075986f3-282b-4555-bfcd-fad973e32596",
      "status": "PROCESSING",
      "failure_reason": null
    }
  }
  ```
</CodeGroup>

<ResponseField name="customer_id, full_name, phone, full_address" type="string" required>
  The customer, their legal name, their phone number without country code (9–10 digits), and their full residential address.
</ResponseField>

<ResponseField name="dob, registered_date" type="string (DD-MM-YYYY)" required>
  Date of birth, and the date the user registered on your platform.
</ResponseField>

<ResponseField name="document_type" type="string" required>
  One of `supported_document_types` from step 2.
</ResponseField>

<ResponseField name="document_front_image_url, document_back_image_url" type="string (URL)">
  JPG, JPEG, PNG or PDF. Required for every document type except `AADHAAR`, which also accepts `aadhaar_json` or `aadhaar_xml` in `document_details.additional_data`.
</ResponseField>

<ResponseField name="document_details.document_number" type="string" required>
  The document's number (for a passport, the file number): 6–20 letters, digits or hyphens.
</ResponseField>

<ResponseField name="selfie_url" type="string (URL)" required>
  JPG, JPEG or PNG. The face must be clearly visible.
</ResponseField>

<ResponseField name="tax_number" type="string">
  Optional. The PAN in India.
</ResponseField>

<ResponseField name="additional_info" type="object">
  The fields your configuration requires.
</ResponseField>

<ResponseField name="ip_address" type="string">
  Optional. The end user's IP address.
</ResponseField>

<Warning>
  Send image URLs, not base64. Host the files somewhere Zapyd can download them, and make sure the images are sharp and every word on the document is readable.
</Warning>

## 4. Wait for the result

Zapyd runs these checks. The first one that fails sets the `failure_reason`:

| Check | What Zapyd verifies | `failure_reason` if it fails |
| - | - | - |
| Document | The number matches official records. The document isn't expired or forged | `DOCUMENT_VERIFICATION_FAILED` |
| Tax | The tax number exists, belongs to an individual, and matches the name and date of birth | `TAX_VERIFICATION_FAILED` |
| Selfie | Liveness, and a match with the document photo | `SELFIE_VERIFICATION_FAILED` |
| Additional info | Any checks your configuration defines | `ADDITIONAL_INFO_VERIFICATION_FAILED` |

Most results arrive within 60 seconds. Manual review can take up to 24 hours. Zapyd sends the result as a `CUSTOMER` webhook:

```json theme={null}
{
  "type": "CUSTOMER",
  "event": "FAILED",
  "id": "075986f3-282b-4555-bfcd-fad973e32596",
  "timestamp": "2026-09-30T10:00:00Z",
  "metadata": { "failure_reason": "TAX_VERIFICATION_FAILED" }
}
```

If you can't receive webhooks, poll [`GET /customer/{customer_id}`](/api-reference-exchange/endpoint/customer/\{customer_id}) no more than once a minute and read `status` and `failure_reason`.

## 5. Fix a failure

Resubmit only the part that failed. Each update moves the customer back to `PROCESSING` and uses one of the customer's three attempts.

| `failure_reason` | Endpoint | Body |
| - | - | - |
| `DOCUMENT_VERIFICATION_FAILED` | [`PATCH /kyc/update-document-info`](/api-reference-exchange/endpoint/kyc/update-document-info) | `customer_id`, `full_address`, `document_type`, `document_details`, and both image URLs (or Aadhaar data) |
| `TAX_VERIFICATION_FAILED` | [`PATCH /kyc/update-tax-info`](/api-reference-exchange/endpoint/kyc/update-tax-info) | `customer_id`, `tax_number` |
| `SELFIE_VERIFICATION_FAILED` | [`PATCH /kyc/update-selfie-info`](/api-reference-exchange/endpoint/kyc/update-selfie-info) | `customer_id`, `selfie_url` |
| `ADDITIONAL_INFO_VERIFICATION_FAILED` | [`POST /kyc/reset-kyc`](/api-reference-exchange/endpoint/kyc/reset-kyc), then [`POST /kyc/add-kyc-data`](/api-reference-exchange/endpoint/kyc/add-kyc-data) again | `customer_id`, then the full KYC body with corrected `additional_info` |

```json PATCH /cms/api/v1/kyc/update-tax-info theme={null}
{ "customer_id": "075986f3-282b-4555-bfcd-fad973e32596", "tax_number": "ABCDE1234G" }
```

`KYC_FAILED` means the customer can't be verified. Don't retry. Contact support with the `customer_id`.

Usual causes of a failure: blurry images, an expired document, a name that differs between documents, or a mistyped tax number. Show the user what to fix before they use another attempt.

## Test it in sandbox

1. Create a customer and submit KYC data with any well-formed values.
2. Set a result with [Mock KYC Status](/api-reference-exchange/endpoint/kyc/mock-kyc-status). `kyc_status` accepts `VERIFIED`, `UNVERIFIED`, `DOCUMENT_VERIFICATION_FAILED`, `TAX_VERIFICATION_FAILED` and `ADDITIONAL_INFO_VERIFICATION_FAILED`.
3. Check that your webhook handler and your update flow work, then set `VERIFIED`.

## Next

Add the customer's bank account: [Bank accounts and wallets](/guides/customers/bank-accounts-and-wallets).
