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

# Import User KYC Data

> Use existing KYC data for faster onboarding

If you already verify users with an identity verification (IDV) provider like Sumsub or Persona, you can send that data to Crossmint before creating an onramp order. When the data is complete, users can skip in-checkout identity verification.

If you prefer to have individual users provide their KYC data client-side, Crossmint supports that as well. See the [React Quickstart](/onramp/quickstarts/react) for that approach.

## How It Works

1. Verify the user with your IDV provider
2. Have the user accept Crossmint's <a href="https://www.crossmint.com/legal/privacy-policy" target="_blank">Privacy Policy</a>
3. [Register the user's KYC data](/identity/register-user-data) with Crossmint
4. Create an onramp order to the wallet linked to that user
5. Crossmint runs sanctions, Politically Exposed Persons (PEP), and compliance checks
6. The user completes payment

## Accept Crossmint's Privacy Policy

Before sharing any user KYC data with Crossmint, the user must accept Crossmint's <a href="https://www.crossmint.com/legal/privacy-policy" target="_blank">Privacy Policy</a>. Record their acceptance with the [Accept Legal Document](/api-reference/users/accept-legal-document) endpoint **before** registering KYC data:

```bash cURL theme={null}
curl --request PUT \
    --url 'https://staging.crossmint.com/api/2025-06-09/users/userId:YOUR_USER_ID/legal-documents' \
    --header 'X-API-KEY: <x-api-key>' \
    --header 'Content-Type: application/json' \
    --data '{
        "type": "crossmint-privacy-policy",
        "acceptedAt": "2025-10-05T14:48:00Z"
    }'
```

See the [Identity Quickstart](/identity/quickstart) for more details on the privacy policy and the users endpoints.

## Create an Onramp Order

Once the user is registered with their KYC data, you can create an onramp order. The order will use the registered KYC data for compliance checks.

<Warning>
  **Important**: Crossmint links pre-registered KYC data to an order using the user's email address. The `payment.receiptEmail` value must match the email used when registering the user's KYC data with the [Create User API](/api-reference/users/upsert-user).
</Warning>

<CodeGroup>
  ```js Node.js theme={null}
  const options = {
      method: 'POST',
      headers: {
          'X-API-KEY': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      body: JSON.stringify({
          recipient: {
              walletAddress: "YOUR_WALLET_ADDRESS"
          },
          payment: {
              method: "card",
              receiptEmail: "YOUR_USER_EMAIL"
          },
          lineItems: [
              {
                  tokenLocator: "base-sepolia:0x036CbD53842c5426634e7929541eC2318f3dCF7e",
                  executionParameters: {
                      mode: "exact-in",
                      amount: "1"
                  }
              }
          ]
      })
  };

  fetch('https://staging.crossmint.com/api/2022-06-09/orders', options)
      .then(response => response.json())
      .then(response => console.log(response))
      .catch(err => console.error(err));
  ```

  ```bash cURL theme={null}
  curl --request POST \
      --url https://staging.crossmint.com/api/2022-06-09/orders \
      --header 'X-API-KEY: YOUR_API_KEY' \
      --header 'Content-Type: application/json' \
      --data '{
          "recipient": {
              "walletAddress": "YOUR_WALLET_ADDRESS"
          },
          "payment": {
              "method": "card",
              "receiptEmail": "YOUR_USER_EMAIL"
          },
          "lineItems": [
              {
                  "tokenLocator": "base-sepolia:0x036CbD53842c5426634e7929541eC2318f3dCF7e",
                  "executionParameters": {
                      "mode": "exact-in",
                      "amount": "1"
                  }
              }
          ]
      }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://staging.crossmint.com/api/2022-06-09/orders"

  payload = {
      "recipient": {
          "walletAddress": "YOUR_WALLET_ADDRESS"
      },
      "payment": {
          "method": "card",
          "receiptEmail": "YOUR_USER_EMAIL"
      },
      "lineItems": [
          {
              "tokenLocator": "base-sepolia:0x036CbD53842c5426634e7929541eC2318f3dCF7e",
              "executionParameters": {
                  "mode": "exact-in",
                  "amount": "1"
              }
          }
      ]
  }
  headers = {
      "X-API-KEY": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.post(url, json=payload, headers=headers)

  print(response.json())
  ```
</CodeGroup>

<Info>
  The `lineItems` field accepts either a single object or an array. The examples above use an array for consistency, but you can also pass a single line item object directly.
</Info>

### Linking KYC Data to Orders

When you create an order, Crossmint automatically looks up the user's KYC data based on the email address provided in `payment.receiptEmail`. Here is the complete flow:

<Steps>
  <Step title="Accept the privacy policy">
    Record the user's privacy-policy acceptance first (see the **Accept Crossmint's Privacy Policy** section above). This is required before any KYC data is shared with Crossmint.
  </Step>

  <Step title="Register user with KYC data">
    First, register the user's KYC information using the [Create User API](/api-reference/users/upsert-user). Make sure to include the user's email in the `email` field within `kycData`:

    ```javascript theme={null}
    const userLocator = "userId:YOUR_USER_ID";

    const options = {
        method: 'PUT',
        headers: {
            'X-API-KEY': 'YOUR_API_KEY',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            userDetails: {
                firstName: "John",
                lastName: "Doe",
                dateOfBirth: "1995-01-01",
                countryOfResidence: "DE"
            },
            kycData: {
                nationality: "DE",
                addressOfResidence: {
                    line1: "123 Hauptstrasse",
                    line2: "Apt 5",
                    city: "Berlin",
                    stateOrRegion: "Berlin",
                    postalCode: "10115"
                },
                email: "YOUR_USER_EMAIL",
                identityDocument: {
                    type: "passport",
                    number: "AS12321",
                    issuingCountryCode: "DE"
                },
                ipAddresses: ["203.0.113.1"]
            }
        })
    };

    fetch(`https://staging.crossmint.com/api/2025-06-09/users/${userLocator}`, options)
        .then(response => response.json())
        .then(response => console.log(response))
        .catch(err => console.error(err));
    ```
  </Step>

  <Step title="Create order with matching email">
    When creating the onramp order, use the same email address in `payment.receiptEmail`:

    ```javascript theme={null}
    const options = {
        method: 'POST',
        headers: {
            'X-API-KEY': 'YOUR_API_KEY',
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            recipient: {
                walletAddress: "YOUR_WALLET_ADDRESS"
            },
            payment: {
                method: "card",
                receiptEmail: "YOUR_USER_EMAIL"
            },
            lineItems: [
                {
                    tokenLocator: "base-sepolia:0x036CbD53842c5426634e7929541eC2318f3dCF7e",
                    executionParameters: {
                        mode: "exact-in",
                        amount: "1"
                    }
                }
            ]
        })
    };

    fetch('https://staging.crossmint.com/api/2022-06-09/orders', options)
        .then(response => response.json())
        .then(response => console.log(response))
        .catch(err => console.error(err));
    ```
  </Step>
</Steps>

## Order Responses

<AccordionGroup>
  <Accordion title="Success: Full KYC Data Present">
    When all required KYC data has been provided and validated, the order moves to the payment phase:

    ```json theme={null}
    {
      "clientSecret": "...",
      "order": {
        "orderId": "987e81ab-8c8f-464e-95e9-11ceda80d559",
        "phase": "payment",
        "locale": "en-US",
        "lineItems": [...],
        "quote": {...},
        "payment": {
          "method": "card",
          "currency": "usd",
          "status": "awaiting-payment"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Success: Additional KYC Inquiry">
    When full KYC data is present but Crossmint needs to run additional compliance checks, the order enters a processing state. This typically resolves within a few seconds as Crossmint runs the appropriate checks:

    ```json theme={null}
    {
      "clientSecret": "...",
      "order": {
        "orderId": "987e81ab-8c8f-464e-95e9-11ceda80d559",
        "phase": "payment",
        "locale": "en-US",
        "lineItems": [...],
        "quote": {...},
        "payment": {
          "method": "card",
          "currency": "usd",
          "status": "pending-kyc-review"
        }
      }
    }
    ```
  </Accordion>

  <Accordion title="Error: Missing KYC Data">
    If no user personal data is provided, or if the data is insufficient, the order will fail:

    ```json theme={null}
    {
      "error": true,
      "message": "Required full KYC user data is missing to complete the order"
    }
    ```
  </Accordion>
</AccordionGroup>

## Guides

<CardGroup cols={2}>
  <Card title="Registering a User" icon="user-plus" iconType="duotone" href="/identity/register-user-data" />

  <Card title="Data Requirements" icon="list-check" iconType="duotone" href="/identity/data-requirements" />
</CardGroup>
