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

# KYC via Sumsub share token

> Reuse existing Sumsub KYC verification when creating a cardholder

If your platform already uses Sumsub for identity verification, you can pass a share token to Contro instead of re-collecting KYC data. This avoids duplicate verification and provides a faster onboarding experience.

## Prerequisites

* Your platform is a Sumsub client (the "donor")
* Your user has completed KYC verification on your Sumsub-integrated platform
* You can generate share tokens from your Sumsub account targeting Contro's client ID

## Flow

1. Your user completes KYC on your platform via Sumsub
2. You generate a Sumsub share token targeting Contro's client ID
3. Call `POST /partner/cardholders` with `kycSource: "sumsub"` and the share token
4. Contro imports the applicant data immediately — the token is not stored

## Create a cardholder with Sumsub KYC

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.contro.me/v1/partner/cardholders \
    -H "x-contro-api-key: $CONTRO_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "externalUserId": "user_42",
      "kycSource": "sumsub",
      "sumsubShareToken": "eyJhbGciOiJub25lIn0...",
      "email": "jane@example.com",
      "phoneNumber": "+14155552671"
    }'
  ```

  ```typescript SDK (Node) theme={null}
  const cardholder = await contro.cardholders.create({
    externalUserId: "user_42",
    kycSource: "sumsub",
    sumsubShareToken: "eyJhbGciOiJub25lIn0...",
    email: "jane@example.com",
    phoneNumber: "+14155552671",
  });
  ```

  ```python SDK (Python) theme={null}
  cardholder = contro.cardholders.create(
      external_user_id="user_42",
      kyc_source="sumsub",
      sumsub_share_token="eyJhbGciOiJub25lIn0...",
      email="jane@example.com",
      phone_number="+14155552671",
  )
  ```

  ```typescript TypeScript (fetch) theme={null}
  const cardholder = await fetch(`${BASE_URL}/partner/cardholders`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      externalUserId: "user_42",
      kycSource: "sumsub",
      sumsubShareToken: "eyJhbGciOiJub25lIn0...",
      email: "jane@example.com",
      phoneNumber: "+14155552671",
    }),
  }).then((r) => r.json());
  ```
</CodeGroup>

## Key details

* **`firstName` and `lastName` are extracted automatically** from the imported Sumsub applicant data. You do not need to provide them.
* The share token is imported **immediately** at cardholder creation time. It is not stored.
* If the imported applicant is already approved, `kycStatus` is set to `"approved"` right away.
* If the applicant is still pending review in Sumsub, `kycStatus` starts as `"pending"` and updates via webhook when Sumsub completes the review.

## Required fields

| Field | Type | Description |
| - | - | - |
| `externalUserId` | string | Your unique identifier for this user |
| `kycSource` | string | Must be `"sumsub"` |
| `sumsubShareToken` | string | Sumsub share token from your platform |
| `email` | string | Valid email address |
| `phoneNumber` | string | E.164 formatted phone number |

## Sandbox behavior

In sandbox mode, the share token import is skipped. A dummy applicant ID is stored and KYC is auto-approved.
