Handle verification with the API
Learn how Connect platforms can use webhooks and the API to handle verification of connected accounts.
Platforms with accounts created using the API can provide Stripe with necessary information about their users for Know Your Customer (KYC) purposes. Platforms can use Connect Onboarding to collect KYC information, or use the Accounts and Persons APIs to provide Stripe with required information. We’ll then perform verification, asking for more information when needed.
The rest of this page goes through how platforms:
- Discover verification requirements for a connected account
- Provide the necessary information to Stripe
Note
You can’t use the API to respond to Stripe risk reviews. You can enable your connected accounts to respond using embedded components, Stripe-hosted onboarding, or remediation links. You can also use the Dashboard to respond to risk reviews on behalf of your connected accounts.
Verification process
Before enabling charges and payouts for a connected account, Stripe needs certain information that varies based on:
- The origin country of the connected accounts
- The service agreement type applicable to the connected accounts
- The capabilities requested for the connected accounts
- The business type (for example, individual or company) and company.structure (for example, public corporation or private partnership)
Platforms need to choose the proper onboarding flow for their business and users to meet the KYC requirements. Broadly speaking, this means providing all the requisite information upfront or incrementally. Either way, set up your integration to watch for and respond to requests from Stripe.
- Establish a Connect webhook URL in your webhook settings to watch for activity, especially events of the
account.
type. When using the Persons API, you should also watch forupdated person.
events.updated - Immediately after creating an account, check the
Account
object’s requirements.currently_due attribute for any additional requirements. Obtain any required information from the user and update the connected account. - Continue watching for
account.
event notifications to see if theupdated requirements
hash changes, and reach out to your user for additional information as needed.
When you provide additional information, you don’t need to resubmit any previously verified details. For example, if the dob
is already verified, you don’t need to provide it again in subsequent updates.
Caution
When requirements.
isn’t empty, additional information is required. Connected accounts might be blocked from creating charges, receiving payouts, or performing certain tasks if you don’t provide this information in a timely manner.
Change information after verification
After an individual or company is verified, you can change some of their information, with limitations. See the Update Account API for limitations based on the configuration of the connected account. Contact support to make changes outside of these limitations.
Determine if verification is needed
When you receive an account.
event to your webhook or fetch an account with the API, you receive an Account object. The Account
object’s charges_
and payouts_
attributes indicate whether the account can create charges and accept payouts.
The Account
object has a requirements
hash, representing the requirements needed to verify the account.
The requirements
hash has the following arrays:
eventually_
: Requirements that you might need to collect, depending on whether the corresponding thresholds are reached. After a requirement becomes required, it also appears in thedue currently_
list. If a requirement becomes required and its due date is before the existingdue current_
, thedeadline current_
changes to the corresponding threshold’s enforcement date.deadline currently_
: Requirements that you must collect by thedue current_
for the Account to remaindeadline active
.currently_
is a subset ofdue eventually_
.due past_
: Requirements that have disabled capabilities because they weren’t verified before thedue current_
.deadline past_
is a subset ofdue currently_
.due errors
: Details about validation and verification failures that require particular requirements incurrently_
ordue past_
to be collected again.due requirement
: Identifies the requirement corresponding to the error.code
: An enum value describing why the requirement is invalid or can’t be verified.reason
: An English message describing the error in more detail. The reason string can also suggest how to resolve the error.
disabled_
: Describes why the Account isn’t enabled and why it can’t process charges or transfers.reason current_
: Date by which requirements indeadline currently_
must be collected to keep the Accountdue active
. It represents the earliest deadline across all of the Account’s requested capabilities and risk requirements, including any hidden capabilities.pending_
: Requirements that might become required, depending on the results of verification or review. It’s an empty array unless an asynchronous verification is pending. Unsuccessful verification moves a requirement toverification eventually_
,due currently_
, ordue past_
. A requirement subject to both failed and pending verifications can also remain indue pending_
.verification
The example below shows what the requirements
hash might look like for an account that has some information that’s currently_
, some information that’s eventually_
, and some information that’s raising verification errors
.
{ "id":
, "object": "account", "requirements": { "disabled_reason": null, "current_deadline": 1529085600, "past_due": [], "currently_due": [ "company.tax_id", "company.verification.document", "tos_acceptance.date", "tos_acceptance.ip" ], "eventually_due": [ "company.address.city", "company.address.line1", "company.address.postal_code", "company.address.state", "company.tax_id", "company.verification.document", "external_account", "tos_acceptance.date", "tos_acceptance.ip" ], "errors": [ { "requirement": "company.verification.document", "reason": "The company name on the account couldn't be verified. Either update your business name or upload a document containing the business name.", "code": "failed_name_match" }, ] }, ... }"{{CONNECTED_ACCOUNT_ID}}"
If requirements.
contains entries, check requirements.
. The current_
is a Unix timestamp identifying when information is needed. Usually, if Stripe doesn’t receive the information by the current_
, payouts on the account are disabled. However, other consequences might apply in some situations. For example, if payouts are already disabled and the account is unresponsive to our inquiries, Stripe might also disable the ability to process charges.
Separately, the requirements.disabled_reason property can have a value. The value is a string describing the reason why this account is unable to make payouts or charges. In some instances, platforms and connected accounts can submit a form to resolve or appeal the reason.
- Connected accounts with access to the full Stripe Dashboard and Standard accounts can access additional information (if available) in the Dashboard.
- Platforms in any Connect configuration can navigate to Accounts to review to understand an account’s
disabled_
. You might be able to provide additional information on behalf of your connected accounts. If the disabled reason is associated with an appeal, you can generate a link to a form for the account to resolve the appeal.reason
Reason | Meaning |
---|---|
action_ | You need to request capabilities for the connected account. For details, see Request and unrequest capabilities. |
listed | Account might be on a prohibited persons or companies list (Stripe investigates and either rejects or reinstates the account accordingly). |
rejected. | Account is rejected due to suspected fraud or illegal activity. |
rejected. | The account is rejected from incomplete verification requirements within the required threshold. |
rejected. | Account is rejected because it’s on a third-party prohibited persons or companies list (such as financial services provider or government). |
rejected. | Account is rejected for another reason. |
rejected. | Account is rejected due to suspected terms of service violations. |
requirements. | Additional verification information is required to enable capabilities on this account. |
requirements. | Stripe is currently verifying information on the connected account. No action is required. Inspect the requirements.pending_verification array to see the information being verified. |
under_ | The account is under review by Stripe. |
Validation and verification errors
The Account object includes a requirements.errors array that explains why the validation or verification requirements haven’t been met, which are needed to enable your account and capabilities. The errors
array has the following attributes:
requirement
: Specifies which information from thecurrently_
array is needed.due code
: Indicates the type of error that occurred. See the API reference for all possible error codes.reason
: Explains why the error occurred and how to resolve the error.
Below is an example that shows what the errors
array might look like for an account with requirements that are currently_
. The example shows the reason why the submitted information can’t be used to enable the account, and how to resolve the error. If verification or validation is unsuccessful, requirements can reappear in currently_
with error information. Set a Connect webhook to receive the account.
event to receive these updates.
{ "id":
, "object": "account", "requirements": { "current_deadline": 1234567800, "currently_due": [ "company.address.line1", "{{PERSON_ID}}.verification.document", ], "errors": [ { "requirement": "company.address.line1", "code": "invalid_street_address", "reason": "The provided street address cannot be found. Please verify the street name and number are correct in \"10 Downing Street\"", }, { "requirement": "{{PERSON_ID}}.verification.document", "code": "verification_document_failed_greyscale", "reason": "Greyscale documents cannot be read. Please upload a color copy of the document.", } ] }, ... }"{{CONNECTED_ACCOUNT_ID}}"
If verification or validation is unsuccessful but no requirements are currently due, a webhook triggers indicating that required information is eventually due.
Business information
When information about a business is submitted, Stripe verifies the new information. For example, Stripe might verify that the provided business URL is valid, reachable, and includes information about the business. To retrieve the status of verification information regarding a business, utilize the requirements
on the Account object.
Below is a list of errors related to business information verification:
Error | Resolution |
---|---|
invalid_ | Business names must be easy for people to understand and must consist of recognizable words. |
invalid_ | Generic or well-known business names aren’t supported. Make sure the provided business name matches the account’s business. |
invalid_ | A product description must be at least 10 characters. |
invalid_ | A product description must be different from the URL of the business. |
| See handling URL verification errors below. |
Statement descriptors
Stripe validates the statement descriptor and statement descriptor prefix when set on an account. For example, Stripe might verify that the provided statement descriptor matches the description of the business. When validating the statement descriptor matches the business description, Stripe uses the first 22 characters of the statement descriptor, representing the part that is provided to the card networks. A business description is a close match of the account’s business_
, business_
, or the name of the company or individual.
To retrieve the status of verification information regarding statement descriptors, review the requirements
on the Account object. Below is a list of errors related to statement descriptor verification:
Error | Resolution |
---|---|
invalid_ | A statement descriptor must be at least 5 characters. |
invalid_ | A statement descriptor must be similar to the business name, legal entity name, or URL of the account. |
| Generic or well-known statement descriptors aren’t supported. |
invalid_ | The statement descriptor prefix must be similar to your statement descriptor, business name, legal entity name, or URL. |
Person information
During the verification process, information about the persons associated with an account needs to be collected. If you onboard:
- Only companies, use the Persons API to collect this information.
- Only individuals, you can use the Persons API or the individual hash on the Account object.
- A combination of individuals and companies, use the Persons API to collect this information. This way you collect information in the same manner regardless of business type.
To retrieve the status of verification information regarding a person, use the requirements hash.
Below is a list of errors related to person verification:
Error | Resolution |
---|---|
invalid_ | Stripe couldn’t validate the combination of the city, state, and postal code in the provided address. |
invalid_ | The address of the person must be a valid physical address from which the account conducts business and can’t be a Highway Contract Box. |
invalid_ | The address of the person must be a valid physical address from which the account conducts business and can’t be a private mailbox. |
invalid_ | The person must be at least 13 years old. |
invalid_ | The person’s date of birth must be within the past 120 years. |
invalid_ | Stripe couldn’t validate the phone number on the account. Make sure the formatting matches the country of the person. |
invalid_ | Stripe couldn’t validate the street name and/or number for the provided address. |
| Tax IDs must be a unique set of 9 numbers without dashes or other special characters. |
Acceptable verification documents by country
To learn about specific document requirements, view Acceptable verification documents by country.
Company information
During the verification process, you might need to collect information about the company for an account.
To retrieve the status of verification information regarding an account’s company, use the Account’s company.verification subhash:
{ "id":
, "object": "account", ... "company": { "verification": { "document": null }, ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
You can look up the definition for each verification attribute on the Account object.
Handle document verification problems
Many complications with the verification process involve the uploaded document itself. To help you recognize and handle the most common problems, the table below lists possible values for the error code
(in the requirements.
array) and the likely resolutions for each error.
Below is a list of errors related to document upload:
Error | Resolution |
---|---|
| The upload failed due to a problem with the file itself. Ask your user to provide a new file that meets these requirements:
|
| The provided file isn’t an acceptable form of ID from a supported country, or isn’t a type of legal entity document that is expected. Ask your user to provide a new file that meets that requirement. For a list, see Acceptable ID types by country. |
| Your team can contact Stripe to learn more about why identity verification failed. |
| The issue or expiry date is missing on the document, or the document is expired. If it’s an identity document, its expiration date must be after the date the document was submitted. If it’s an address document, the issue date must be within the last six months. |
Below is a list of errors related to identity verification:
Error | Resolution |
---|---|
verification_ | The name on the account couldn’t be verified. Ask your user to verify that they have provided their full legal name and to also provide a photo ID matching that name. |
| The information on the ID document doesn’t match the information provided by the user. Ask your user to verify and correct the provided information on the account. |
| The document might have been altered so it couldn’t be verified. Your team can contact Stripe to learn more. |
Below is a list of errors related to business verification:
Error | Resolution |
---|---|
| The information on the account couldn’t be verified. Your user can either upload a document to confirm their account details, or update their information on their account. |
| The information that your user provided couldn’t be verified with the IRS. Ask your user to correct any possible errors in the company name or tax ID, or upload a document that contains those fields. (US only) |
| The information on the document doesn’t match the information provided by the user. Ask your user to verify and correct the provided information on the account, or upload a document with information that matches the account. |
| The uploaded document is missing a required field. Ask your user to upload another document that contains the missing field. |
Caution
Don’t resubmit a file that previously failed. Duplicate uploads immediately trigger an error and aren’t rechecked.
Handle URL verification errors
URLs for e-commerce businesses need to conform to certain card network standards. In order to comply with these standards, Stripe conducts a number of verifications when reviewing URLs. To learn about best practices for URLs and common elements for e-commerce businesses, see the website checklist. There are two methods to resolve URL verification errors:
- Using the API: Please see the list of error codes below in order to understand and resolve the issue you are facing. If you need to update the URL, use the Update Account API, which will trigger Stripe to verify the new URL. If you have made changes to the website at the provided URL in order to resolve an error, but do not need to make changes to the URL itself, you can trigger reverification by using the API to change the URL to any other value and then change it back.
- Using the Dashboard: Platforms can use the Accounts to review page or the Actions required list on the Account details page in the Stripe Dashboard to understand the impact to their connected accounts and what actions to take.
Not all URL-related issues can be resolved using the API. Certain types of URL verification errors require additional information on how to access the connected account’s website or to attest that the account is exempt from URL requirements. These types of issues require you or your connected account to provide supplemental information.
In the Dashboard, visit your Accounts to review page or check the Actions required list (if present) on the Account details page to resolve the error. If you can’t resolve the issue, direct your connected account to contact Stripe Support. For guidance on how to review your accounts, see Review actionable accounts.
Note
Stripe’s Terms of Service requires all e-commerce businesses to populate the business_profile.url property with a working URL of their business website when activating an account with the card_
capability. An account is considered an e-commerce business if it promotes or sells any products or services through an online website, social media profile, or mobile application. If the account doesn’t operate a website to promote their business, sell products, or accept payments, they’re required to provide business_profile.product_description instead. A product description needs to detail the type of products being sold as well as the manner in which the account’s customers are being charged (e.g. in person transactions). For more information, please see: Business website for account activation FAQ.
To help you handle the most common errors associated with the business_
field, the following table lists the related error codes (in the requirements.
array) and possible resolutions.
Error | Resolution |
---|---|
invalid_ | The provided URL matches a generic business website that Stripe believes is unrelated to the account. To resolve the issue, provide a URL that is specific to the business. |
invalid_ | The provided URL is in the incorrect format. To resolve the issue, provide a correctly formatted URL, such as https://example. . |
invalid_ | We can’t reach the website at the provided URL. If you block certain regions from viewing your website, temporarily remove the blocker until your website has been verified. |
invalid_ | Information on the website at the provided URL does not match the information on the Stripe account. |
invalid_ | The website at the provided URL is missing either a business name or a clear description of goods and services offered. |
invalid_ | We are unable to verify the account’s business using a website, social media profile, or mobile application at the provided URL. |
invalid_ | We have detected that the account uses a website, social media profile, or mobile application to sell or promote products or services, but a URL hasn’t been provided. To resolve the issue, provide a URL. |
invalid_ | The website does not contain customer service details. |
invalid_ | The website does not contain a return policy and process. |
invalid_ | The website does not contain a refund policy. |
invalid_ | The website does not contain a cancellation policy. |
invalid_ | The website does not contain applicable disclosures for products and services that are subject to legal or export restrictions. |
invalid_ | The website does not contain terms and conditions. |
invalid_ | We are unable to verify the website at the provided URL, because the website is still under construction. |
invalid_ | We are unable to verify the website at the provided URL, because the website is password-protected. |
invalid_ | We are unable to verify the website at the provided URL, because certain regions are blocked from accessing it. If you block certain regions from viewing your website, temporarily remove the blocker until your website has been verified. |
invalid_ | We are unable to verify the website at the provided URL, because the website has no content. |
Handle identity verification
You can respond in two ways to an identity verification change. The first is to perform an Update Account call, correcting or adding information.
Secondarily, we might ask you to upload a document. Depending on how much of the user’s information Stripe has been able to verify, we might require three different types of document uploads. You can determine what documents to upload based on the fields listed in requirements.
:
person.
: Requires a color scan or photo of an acceptable form of ID.verification. document person.
: Requires a color scan or photo of a document verifying the user’s address, such as a utility bill.verification. additional_ document company.
: Requires a proof of entity document establishing the business’ entity ID number, such as the company’s articles of incorporation.verification. document
Uploading a document is a two-step process:
- Upload the file to Stripe
- Attach the file to the account
Note
For security reasons, Stripe doesn’t accept copies of IDs sent by email.
Upload a file
To upload a file, use the Create File API by using a POST to send the file data as part of a multipart/form-data request.
The uploaded file must meet these requirements:
- Color image (8,000 pixels by 8,000 pixels or smaller)
- 10 MB or less
- Identity documents are JPG or PNG format
- Address or legal entity documents are JPG, PNG, or PDF format
Pass the file data in the file
parameter and set the purpose
parameter to identity_
:
This request uploads the file and returns a token:
{ "id":
, "created": 1403047735, "size": 4908 }"{{FILE_ID}}"
You may then use the token’s id
value to attach the file to a connected account for identity verification.
Attach the file
After you upload the file and receive a representative token, provide the file ID using the appropriate field in your Update Account call.
Below is an example for an ID document:
Below is an example for a company document:
This update changes verification.
to pending
. If an additional person needs to be verified, use the Persons API to update them.
Confirm ID verification
If the color scan or photo of the ID passes Stripe’s checks, the document requirement is removed from requirements.
. Satisfying all verification requirements for the person or company triggers an account.
webhook notification signaling the verification process is complete.
Verification can take Stripe from a few minutes, to a couple business days to complete, depending on how readable the provided image is.
If the verification attempt fails, the requirements.
array contains an error stating the cause. The error[reason]
, such as “The image supplied isn’t readable,” is safe to present to your user, but isn’t localized. The response also contains an error[code]
value, such as verification_
, which you can use to localize errors for your users. Upon failure, requirements.
indicates that a new ID upload is required. If the deadline for verification is near, requirements.
might also be populated with a date. Verification failure also triggers an account.
webhook notification.
Handle risk verifications
New risk requirements
The following risk-related requirement data will be generally available on November 12, 2024. You can opt in to receiving it sooner by following the instructions provided by Stripe Support.
Stripe reports risk and compliance requirements in the accounts.requirements attribute. These requirements follow the schema: <id>.
:
id
uniquely identifies information needed by Stripe or our financial partners. This identifier is always prefixed withinterv_
to indicate that it is a risk verification requirement.requirement_
specifically describes the information needed to complete the requirement, such asdescription identity_
,verification rejection_
, and so on.appeal resolution_
specifies how you or your connected account can provide the requested information:path challenge
: Connected accounts must directly respond to challenge prompts. They often require sensitive information, such as a bank account, or information that only the account owner can provide, such as a selfie.form
: Connected accounts can complete form requests, or you can complete them on their behalf.support
: The requirement isn’t directly actionable. Contact Stripe Support.
{ "id":
, "object": "account", "requirements": { "current_deadline": 1234567800, "currently_due": [ "{{REQUIREMENT_ID}}.restricted_or_prohibited_industry_diligence.form" ], "pending_verification": [], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
After satisfying a resolution path, the value of the requirement’s resolution path might change to support
and the requirement also appears in the pending_
section of the requirements hash. Stripe verifies the submitted information and either dismisses the requirement as resolved or posts a new currently due requirement.
{ "id":
, "object": "account", "requirements": { "current_deadline": 1234567800, "currently_due": [], "pending_verification": [ "{{REQUIREMENT_ID}}.restricted_or_prohibited_industry_diligence.support" ], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
You can remediate risk and compliance requirements in any of the following ways, depending on the type of requirement:
- Connect embedded components: You can embed Connect components directly into your website. When a requirement surfaces, direct your users to the account onboarding embedded component, where they’re prompted to complete outstanding requirements directly in your UI. Alternatively, use the Notification banner embedded component to prompt your users for any outstanding requirements.
- Stripe hosted onboarding: You can generate links to direct your connected accounts to complete outstanding requirements programmatically through account links or manually in your platform Dashboard.
- Complete on behalf of your accounts: You can use your platform Dashboard to identify and complete form-based risk requirements from connected account detail on behalf of your accounts.
The following requirement_
values are relevant to requirements shown in the account.
attribute.
Value | Description |
---|---|
business_ | We require additional information about the nature of the business to verify that we can support the account. |
restricted_ | The business might operate in a restricted category (for example, selling alcohol, insurance, or financial products). Stripe might require more information about the nature of the business or licensing information to verify that we can support the account. |
intellectual_ | The business might be selling products or services that are protected by copyright. We require additional information to verify that the account is authorized to sell those products. |
supportability_ | The Stripe terms of service prohibit supporting the business. The account can appeal this determination. |
other_ | We require additional information to verify that we can support the account. |
credit_ | We require additional information about the nature of the business to verify that we can support the account. |
reserve_ | We’ve applied a reserve to the account. The reserve doesn’t impact the account’s ability to accept payments with Stripe. The account can appeal our determination. |
identity_ | The person responsible for the account must verify their identify by uploading an ID document and a selfie. |
url_ | The business URL must reflect the products and services that it provides. Stripe might require them to change the URL before we can support the account. |
address_ | We need to verify the address of the business through document upload. |
domain_ | We need to verify that the account owner controls the URL or domain that they provided. |
bank_ | We need to verify bank account details associated with the business. |
customer_ | We need to verify customer service contact information associated with the business. |
fulfillment_ | We need to verify the business’s fulfillment policy. |
product_ | The business’s Stripe account must include an accurate product description. |
statement_ | We need a statement descriptor that accurately reflects the business. |
capability_ | The Stripe Terms of Service prohibit supporting specific capabilities associated with this business. The account can appeal this determination. |
rejection_ | The Stripe Terms of Service prohibit supporting the business due to the level of risk it presents. The account can appeal this determination. |
platform_ | The platform initiated an intervention on its own connected account. It can be a real intervention or an API integration test. |
other_ | We require additional compliance information that doesn’t fit any of the other descriptions. |
other_ | We require additional business information that doesn’t fit any of the other descriptions. |