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

# Onboard individual users via the KYC Connector

> Use the Uphold KYC Connector to ingest verifications from Sumsub or Veriff, mapping provider payloads to KYC processes without bespoke integration work.

The [KYC Connector](/rest-apis/kyc-connector-api/introduction) is an ingestion layer between third-party KYC providers and Uphold's platform. Instead of manually mapping provider-specific payloads to Uphold's KYC model, you create an **ingestion** and the KYC Connector handles extraction and submission on your behalf.

The KYC Connector covers four processes: `profile`, `address`, `identity`, and `proofOfAddress`. Any remaining required processes (e.g. `customerDueDiligence`, `taxDetails`) must still be completed via the [REST API](/developer-guides/user-onboarding/individual/via-api).

<Tabs>
  <Tab title="Sumsub">
    ## Prerequisites

    * API client credentials with permission to create users and create ingestions.
    * Your Sumsub account [must be configured](/rest-apis/kyc-connector-api/sumsub/overview#setup-requirements) for KYC data sharing.

    ## Walkthrough

    ```mermaid theme={null}
    sequenceDiagram
      autonumber
      participant U as Client App
      participant B as Your Backend
      participant A as Core API
      participant K as KYC Connector API
      participant S as KYC Provider
      participant W as Webhooks

      U->>B: User provides personal, address, and contact details
      B->>A: GET /core/terms-of-service?type=general&country={country}
      A-->>B: { termsOfService[] }
      B-->>U: Display Terms of Service
      U->>B: User accepts Terms of Service
      B->>A: POST /core/users (with ToS + X-Uphold-User-Ip)
      A-->>B: { user }
      B-->>U: User completes verification (existing provider flow)
      U->>S: User completes KYC (identity, proof-of-address)
      S-->>B: Applicant approved (webhook or callback)
      B->>S: Generate share token for applicant
      S-->>B: { shareToken }
      B->>K: POST /kyc-connector/sumsub/ingestions (shareToken + processes)
      K-->>B: { ingestion }
      A-->>W: kyc-connector.sumsub.ingestion.status-changed (running → finished)
      B->>A: GET /core/kyc (verify process statuses)
      B->>A: PATCH /core/kyc/* (complete remaining processes via API)
      B->>A: GET /core/capabilities
      A-->>B: { capabilities[] }
      B-->>U: User is ready to transact
    ```

    ## Create the user

    The user creation step is identical to the [REST API approach](/developer-guides/user-onboarding/individual/via-api#create-the-user): fetch the applicable Terms of Service, display them to the user, and call [Create User](/rest-apis/core-api/users/create-user):

    ```http theme={null}
    GET /core/terms-of-service?type=general&country={country}
    POST /core/users
    ```

    <Tip>The `X-Uphold-User-Ip` [user context](/rest-apis/headers#user-context) header is **mandatory** when creating a user.</Tip>

    ## Collect KYC data

    Your existing KYC provider flow requires no changes. Once the user completes verification and the applicant is approved, generate a **share token** from your backend. This token authorizes Uphold to copy the applicant's KYC data from your provider account.

    ## Create an ingestion

    Call [Create ingestion](/rest-apis/kyc-connector-api/sumsub/create-ingestion) with the share token and the list of KYC processes you want to ingest.

    ```json theme={null}
    POST /kyc-connector/sumsub/ingestions
    {
      "shareToken": "_act-sbx-jwt-eyJhbGciOiJub25lIn0.eyJqdGkiOiJ0ZXN0IiwidXJsIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9.",
      "processes": [
        "identity",
        "proof-of-address"
      ]
    }
    ```

    A successful response returns an `ingestion` object with details about the ingestion and its initial status:

    ```json Response theme={null}
    {
      "ingestion": {
        "id": "019b2184-1ca9-7dd6-b7a5-ec242def68b0",
        "userId": "123e4567-e89b-12d3-a456-426614174000",
        "status": "queued",
        "processes": [
          "identity",
          "proof-of-address"
        ],
        "provider": "sumsub",
        "parameters": {
          "shareToken": "_act-sbx-jwt-eyJhbGciOiJub25lIn0.eyJqdGkiOiJ0ZXN0IiwidXJsIjoiaHR0cHM6Ly9leGFtcGxlLmNvbSJ9."
        },
        "createdAt": "2026-01-15T14:23:01.819Z",
        "updatedAt": "2026-01-15T14:23:01.819Z"
      }
    }
    ```

    ## Monitor the ingestion

    Prefer **webhooks** for real-time updates, or fall back to **polling** if webhooks are not feasible.

    * Webhook events (recommended):
      * [kyc-connector.sumsub.ingestion.created](/rest-apis/kyc-connector-api/sumsub/webhooks/ingestion-created)
      * [kyc-connector.sumsub.ingestion.status-changed](/rest-apis/kyc-connector-api/sumsub/webhooks/ingestion-status-changed)
        * `status: queued` → ingestion created, waiting to be picked up
        * `status: running` → fetching and submitting provider data to Uphold
        * `status: finished` → processing complete
    * Polling (fallback): [Get ingestion](/rest-apis/kyc-connector-api/sumsub/get-ingestion)

    <Warning>
      When the ingestion reaches `finished`, inspect the `result` field for each process. A `completed` result means the data was successfully extracted and submitted to Uphold — it does **not** mean the KYC process itself has been verified. Always confirm KYC process statuses using [Get KYC Overview](/rest-apis/core-api/kyc/get-overview).
    </Warning>

    ## Complete onboarding process

    Once the ingestion finishes, the KYC Connector has submitted only the processes it supports (`profile`, `address`, `identity`, `proof-of-address`). Use [Get KYC Overview](/rest-apis/core-api/kyc/get-overview) to confirm which processes are now `ok` and identify what still needs to be collected.

    Any remaining required processes (e.g. `customerDueDiligence`, `taxDetails`) must still be completed.

    <CardGroup cols={2}>
      <Card title="Via REST API" icon="code" href="/developer-guides/user-onboarding/individual/via-api#complete-kyc-processes">
        Check required processes and prompt the user to submit any outstanding ones. Call the relevant endpoints to submit the data and update process statuses until all are `ok`.
      </Card>

      <Card title="Via KYC Widget" icon="puzzle-piece" href="/developer-guides/user-onboarding/individual/via-kyc-widget">
        Embed the KYC Widget to let the user complete the remaining processes through a pre-built UI.
      </Card>
    </CardGroup>

    ## Check capabilities

    Always check if the required capabilities for the user's intended activities are unlocked before allowing them to transact. Call [List capabilities](/rest-apis/core-api/capabilities/list-user-capabilities) to check restrictions and requirements for each capability.

    ```http theme={null}
    GET /core/capabilities
    ```

    The response includes the list of capabilities with any outstanding `requirements` or `restrictions`.

    ```json Response theme={null}
    {
      "capabilities": [
        {
          "key": "crypto-deposits",
          "enabled": true,
          "requirements": [],
          "restrictions": []
        },
        {
          "key": "crypto-withdrawals",
          "enabled": true,
          "requirements": [
            "user-must-submit-identity"
          ],
          "restrictions": []
        }
      ]
    }
    ```

    <Check>The user is now onboarded and ready to transact.</Check>
  </Tab>

  <Tab title="Veriff">
    ## Prerequisites

    * API client credentials with permission to create users, manage Veriff config, and create ingestions.
    * One or more Veriff integrations configured with the appropriate verification flows (IDV, PoA).

    ## Walkthrough

    ```mermaid theme={null}
    sequenceDiagram
      autonumber
      participant U as Client App
      participant B as Your Backend
      participant A as Core API
      participant K as KYC Connector API
      participant V as Veriff
      participant W as Webhooks

      B->>K: PUT /kyc-connector/veriff/config (one-time setup)
      K-->>B: { config }
      U->>B: User provides country of residence
      B->>A: GET /core/terms-of-service?type=general&country={country}
      A-->>B: { termsOfService[] }
      B-->>U: Display Terms of Service
      U->>B: User accepts Terms of Service
      B->>A: POST /core/users (with ToS + X-Uphold-User-Ip)
      A-->>B: { user }
      B-->>U: User completes verification (existing provider flow)
      U->>V: User completes KYC (identity, proof-of-address)
      V-->>B: Session approved (webhook or callback)
      B->>K: POST /kyc-connector/veriff/ingestions (sessions + processes)
      K-->>B: { ingestion }
      A-->>W: kyc-connector.veriff.ingestion.status-changed (running → finished)
      B->>A: GET /core/kyc (verify process statuses)
      B->>A: PATCH /core/kyc/* (complete remaining processes via API)
      B->>A: GET /core/capabilities
      A-->>B: { capabilities[] }
      B-->>U: User is ready to transact
    ```

    ## Configure the provider

    Before creating any ingestions, you must register your Veriff integration credentials with Uphold. This is a **one-time setup** (or whenever you need to update credentials or integrations).

    Call [Set Veriff config](/rest-apis/kyc-connector-api/veriff/set-config) with your integration details:

    ```json theme={null}
    PUT /kyc-connector/veriff/config
    {
      "integrations": [
        {
          "name": "my-idv-integration",
          "apiKey": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "sharedSecretKey": "f0e1d2c3-b4a5-6789-0fed-cba987654321",
          "processes": [
            "profile",
            "identity"
          ]
        },
        {
          "name": "my-poa-integration",
          "apiKey": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "sharedSecretKey": "e1d2c3b4-a596-7890-fedc-ba9876543210",
          "processes": [
            "address",
            "proof-of-address"
          ]
        }
      ]
    }
    ```

    <Tip>You can configure multiple integrations if you use separate Veriff integrations for different processes (e.g. one for IDV, another for PoA).</Tip>

    ## Create the user

    The user creation step is identical to the [REST API approach](/developer-guides/user-onboarding/individual/via-api#create-the-user): fetch the applicable Terms of Service, display them to the user, and call [Create User](/rest-apis/core-api/users/create-user):

    ```http theme={null}
    GET /core/terms-of-service?type=general&country={country}
    POST /core/users
    ```

    <Tip>The `X-Uphold-User-Ip` [user context](/rest-apis/headers#user-context) header is **mandatory** when creating a user.</Tip>

    ## Collect KYC data

    Your existing Veriff verification flow requires no changes. Once the user completes verification and the session is approved, you will have the **session ID** ready to use.

    ## Create an ingestion

    Call [Create ingestion](/rest-apis/kyc-connector-api/veriff/create-ingestion) with the session details and the list of KYC processes you want to ingest. Each session references an **integration name** from your provider configuration and the **session ID** from Veriff.

    ```json theme={null}
    POST /kyc-connector/veriff/ingestions
    {
      "processes": [
        "profile",
        "address",
        "identity",
        "proof-of-address"
      ],
      "sessions": [
        {
          "sessionId": "550e8400-e29b-41d4-a716-446655440000",
          "integrationName": "my-idv-integration",
          "processes": [
            "profile",
            "identity"
          ]
        },
        {
          "sessionId": "661f9511-f30c-52e5-b827-557766551111",
          "integrationName": "my-poa-integration",
          "processes": [
            "address",
            "proof-of-address"
          ]
        }
      ]
    }
    ```

    A successful response returns an `ingestion` object with details about the ingestion and its initial status:

    ```json Response theme={null}
    {
      "ingestion": {
        "id": "019b2184-1ca9-7dd6-b7a5-ec242def68b0",
        "userId": "123e4567-e89b-12d3-a456-426614174000",
        "status": "queued",
        "processes": [
          "profile",
          "address",
          "identity",
          "proof-of-address"
        ],
        "provider": "veriff",
        "parameters": {
          "sessions": [
            {
              "sessionId": "550e8400-e29b-41d4-a716-446655440000",
              "integrationName": "my-idv-integration",
              "processes": [
                "profile",
                "identity"
              ]
            },
            {
              "sessionId": "661f9511-f30c-52e5-b827-557766551111",
              "integrationName": "my-poa-integration",
              "processes": [
                "address",
                "proof-of-address"
              ]
            }
          ]
        },
        "createdAt": "2026-01-15T14:23:01.819Z",
        "updatedAt": "2026-01-15T14:23:01.819Z"
      }
    }
    ```

    ## Monitor the ingestion

    Prefer **webhooks** for real-time updates, or fall back to **polling** if webhooks are not feasible.

    * Webhook events (recommended):
      * [kyc-connector.veriff.ingestion.created](/rest-apis/kyc-connector-api/veriff/webhooks/ingestion-created)
      * [kyc-connector.veriff.ingestion.status-changed](/rest-apis/kyc-connector-api/veriff/webhooks/ingestion-status-changed)
        * `status: queued` → ingestion created, waiting to be picked up
        * `status: running` → fetching and submitting provider data to Uphold
        * `status: finished` → processing complete
    * Polling (fallback): [Get ingestion](/rest-apis/kyc-connector-api/veriff/get-ingestion)

    <Warning>
      When the ingestion reaches `finished`, inspect the `result` field for each process. A `completed` result means the data was successfully extracted and submitted to Uphold — it does **not** mean the KYC process itself has been verified. Always confirm KYC process statuses using [Get KYC Overview](/rest-apis/core-api/kyc/get-overview).
    </Warning>

    ## Complete onboarding process

    Once the ingestion finishes, the KYC Connector has submitted only the processes it supports (`profile`, `address`, `identity`, `proof-of-address`). Use [Get KYC Overview](/rest-apis/core-api/kyc/get-overview) to confirm which processes are now `ok` and identify what still needs to be collected.

    Any remaining required processes (e.g. `customerDueDiligence`, `taxDetails`) must still be completed.

    <CardGroup cols={2}>
      <Card title="Via REST API" icon="code" href="/developer-guides/user-onboarding/individual/via-api#complete-kyc-processes">
        Check required processes and prompt the user to submit any outstanding ones. Call the relevant endpoints to submit the data and update process statuses until all are `ok`.
      </Card>

      <Card title="Via KYC Widget" icon="puzzle-piece" href="/developer-guides/user-onboarding/individual/via-kyc-widget">
        Embed the KYC Widget to let the user complete the remaining processes through a pre-built UI.
      </Card>
    </CardGroup>

    ## Check capabilities

    Always check if the required capabilities for the user's intended activities are unlocked before allowing them to transact. Call [List capabilities](/rest-apis/core-api/capabilities/list-user-capabilities) to check restrictions and requirements for each capability.

    ```http theme={null}
    GET /core/capabilities
    ```

    The response includes the list of capabilities with any outstanding `requirements` or `restrictions`.

    ```json Response theme={null}
    {
      "capabilities": [
        {
          "key": "crypto-deposits",
          "enabled": true,
          "requirements": [],
          "restrictions": []
        },
        {
          "key": "crypto-withdrawals",
          "enabled": true,
          "requirements": [
            "user-must-submit-identity"
          ],
          "restrictions": []
        }
      ]
    }
    ```

    <Check>The user is now onboarded and ready to transact.</Check>
  </Tab>
</Tabs>
