# Integrate the KYC tier system for the Embedded Components onramp Learn about KYC verification tiers, the information required for each, and how to detect when a user's purchase amount is limited by their verification level. All users must pass KYC verification before they can buy crypto with the onramp. Users can provide additional information to increase their purchase limits. This guide covers the KYC tiers, the information required for each tier, and how you can detect when a user’s purchase amount is limited by the amount of KYC information provided. ## Before you begin Before you begin, [integrate the Embedded Components Onramp](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md). ## KYC tier comparison The following table summarizes the requirements for each KYC tier. | KYC tier | User inputs | | -------- | --------------------------- | | L0 | Name, phone, email, address | | L1 | + Date of birth, SSN | | L2 | + Photo ID, selfie | ## KYC API ### Use attachKYCInfo for L0 and L1 KYC Call `attachKYCInfo` to initiate the L0 and L1 KYC verification processes for a user. The fields collected by `attachKYCInfo` depend on the tier: - **L0**: `firstName`, `lastName`, `address` - **L1**: All L0 fields, plus `dateOfBirth`, `idNumber`, `idType` L0 and L1 verification are asynchronous. Call this API and check the verification status before you create an onramp session. The `Create a CryptoOnrampSession` API returns a `400` error if the user has pending verifications. Continue retrieving the verification result until no verification remains pending. The following table summarizes how to use the `verifications` field in the API response to determine whether a user is verified: | User | Verified | | ---- | -------------------------------------------------- | | L0 | `kyc_verified: true`, `phone_verified: true` | | L1 | `kyc_verified: true` | | L2 | `kyc_verified: true`, `id_document_verified: true` | ### Use verifyIdentity for L2 KYC Call `verifyIdentity` to present a Stripe-hosted flow where the user uploads an identity document and a selfie. L2 verification is asynchronous. Your backend must call the [Retrieve a CryptoCustomer](https://docs.stripe.com/api/crypto/customers/retrieve.md) API with the `customerId`. The API returns the L2 verification status in `id_document_verified`. ### Handling KYC error for createCryptoPaymentToken Users must submit their L0 KYC information before you can collect payment methods. If a user hasn’t completed L0 verification, `createCryptoPaymentToken` returns a `crypto_onramp_missing_minimum_identity_verification` error. Handle this error by prompting the user to submit their L0 KYC information. ### Interpreting limit errors from CryptoOnrampSession Your backend must call the [Create a CryptoOnrampSession](https://docs.stripe.com/api/crypto/onramp_sessions/create.md) API to create a [CryptoOnrampSession](https://docs.stripe.com/api/crypto/onramp_sessions/object.md). If the user reaches a purchase limit, the `Create a CryptoOnrampSession` API returns an HTTP `400` error with a JSON object that describes the error. Your application can use these errors to request more information from the user so they can complete the transaction. If the `Create a CryptoOnrampSession` API returns an HTTP `400` error with one of the following error codes, call the [Retrieve a CryptoCustomer](https://docs.stripe.com/api/crypto/customers/retrieve.md) API with the `customerId` to determine the next step: - `crypto_onramp_missing_minimum_identity_verification` - `crypto_onramp_missing_identity_verification` - `crypto_onramp_missing_document_verification` The following table summarizes how to use the `provided_fields` field in the API response to determine a user’s tier: | User | Provided fields | | ---- | ------------------------------------------------------------------------------------------------------------------------------------------ | | L0 | `first_name`, `last_name`, `address_line_1`, (`address_line_2`), `address_city`, `address_state`, `address_postal_code`, `address_country` | | L1 | All L0 fields, plus `id_number`, `id_type`, `dob` | | L2 | All L1 fields, plus `id_document`, `selfie` | The following table summarizes how to use both the error code from the [Create a CryptoOnrampSession](https://docs.stripe.com/api/crypto/onramp_sessions/create.md) API and the `provided_fields` field from the [Retrieve a CryptoCustomer](https://docs.stripe.com/api/crypto/customers/retrieve.md) API to determine the next step. | Error code | Meaning | Next step | | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `crypto_onramp_missing_minimum_identity_verification` | L0 verification failed. The customer must provide full L0 data to complete the transaction: - The user is an L0 user and they didn’t pass the minimum identity verification required to create a session. | Prompt the user to provide valid L0 KYC information, including name, phone, email, and address. | | `crypto_onramp_missing_identity_verification` | L1 verification is required. The customer must provide full or partial L1 data to complete the transaction: - The user is an L1 user and they didn’t pass the L1 identity verification required to create a session. - The user is a verified L0 user but the transaction requires L1 verification. | Inspect [Retrieve a CryptoCustomer](https://docs.stripe.com/api/crypto/customers/retrieve.md) API response `provided_fields` to determine the next step. - `provided_fields` contains both `dob` and `id_number`. Prompt the user to provide full L1 KYC information, including name, adddress, date of birth and Social Security number. - `provided_fields` doesn’t contain `dob` and `id_number`. Prompt the user to provide only `dob`, `id_number`, `id_type`, then upload partially with `attachKYCInfo` (only include these three fields). | | `crypto_onramp_missing_document_verification` | L2 verification is required. The customer must provide a photo ID and selfie to complete the transaction: - The user is an L2 user and they didn’t pass the L2 document identity verification required to create a session. - The user is a verified L0 user but the transaction requires L2 verification. - The user is a verified L1 user but the transaction requires L2 verification. | Inspect [Retrieve a CryptoCustomer](https://docs.stripe.com/api/crypto/customers/retrieve.md) API response `provided_fields` to determine the next step. - If the user is an L2 user (`provided_fields` contains `dob`, `id_number`, `id_document` and `selfie`). Prompt the user to complete L2 KYC verification with `verifyIdentity`. - If the user is an L0 user (`provided_fields` doesn’t contain `dob`, `id_number`, `id_document` and `selfie`). Prompt the user to collect only `dob`, `id_number`, `id_type` upload partially with `attachKYCInfo`, then prompt the user to complete L2 KYC verification with `verifyIdentity`. - If the user is an L1 user (`provided_fields` contains both `dob` and `id_number` but not `id_document` and `selfie`). Prompt the user to complete L2 KYC verification with `verifyIdentity`. |