Skip to main content
RapidDev - Software Development Agency
stripe-guide

How to verify a connected account in Stripe

Connected accounts in Stripe require ongoing verification to remain active. Stripe sets requirements with deadlines — if not met, charges or payouts may be disabled. This guide covers how to check verification status, handle requirement updates, upload documents via the API, and monitor account.updated webhooks to keep your connected accounts compliant.

What you'll learn

  • How to check a connected account's verification requirements
  • How to upload identity documents via the Stripe API
  • How to handle requirement deadlines and errors
  • How to monitor verification status with account.updated webhooks
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced6 min read20 minutesStripe API v2024-12+, Node.js 18+March 2026RapidDev Engineering Team
TL;DR

Connected accounts in Stripe require ongoing verification to remain active. Stripe sets requirements with deadlines — if not met, charges or payouts may be disabled. This guide covers how to check verification status, handle requirement updates, upload documents via the API, and monitor account.updated webhooks to keep your connected accounts compliant.

Keeping Connected Accounts Verified and Compliant

Stripe requires connected accounts to verify their identity, business information, and banking details. Verification is not a one-time event — Stripe may request additional information based on regulatory changes, transaction volume, or periodic reviews. Failing to meet requirements by their deadlines can result in disabled charges or payouts. This guide covers the full verification lifecycle for connected accounts.

Prerequisites

  • Stripe account with Connect enabled
  • At least one connected account (Express or Custom)
  • Node.js 18 or later installed
  • Stripe Node.js SDK: npm install stripe

Step-by-step guide

1

Retrieve and inspect verification requirements

Check a connected account's requirements to see what information Stripe needs. Requirements fall into three categories: currently_due, eventually_due, and past_due.

typescript
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2
3async function getRequirements(accountId) {
4 const account = await stripe.accounts.retrieve(accountId);
5
6 console.log('Charges enabled:', account.charges_enabled);
7 console.log('Payouts enabled:', account.payouts_enabled);
8 console.log('\nCurrently due:', account.requirements.currently_due);
9 console.log('Eventually due:', account.requirements.eventually_due);
10 console.log('Past due:', account.requirements.past_due);
11 console.log('Pending verification:', account.requirements.pending_verification);
12
13 if (account.requirements.current_deadline) {
14 const deadline = new Date(account.requirements.current_deadline * 1000);
15 console.log('\nDeadline:', deadline.toISOString());
16 }
17
18 if (account.requirements.errors.length > 0) {
19 console.log('\nErrors:');
20 account.requirements.errors.forEach(e => {
21 console.log(` ${e.requirement}: ${e.reason} (${e.code})`);
22 });
23 }
24
25 return account.requirements;
26}
27
28getRequirements('acct_connectedId');

Expected result: Console displays the account's charge/payout status, all requirement categories, deadline if any, and errors.

2

Upload an identity document

If a requirement like individual.verification.document is listed, upload an identity document (passport, driver's license) via the Files API and attach it to the account.

typescript
1const fs = require('fs');
2
3async function uploadVerificationDocument(accountId, filePath) {
4 // Step 1: Upload the file to Stripe
5 const file = await stripe.files.create({
6 purpose: 'identity_document',
7 file: {
8 data: fs.readFileSync(filePath),
9 name: 'id_document.jpg',
10 type: 'image/jpeg',
11 },
12 });
13 console.log('File uploaded:', file.id);
14
15 // Step 2: Attach to the connected account
16 const account = await stripe.accounts.update(accountId, {
17 individual: {
18 verification: {
19 document: {
20 front: file.id,
21 },
22 },
23 },
24 });
25
26 console.log('Document attached. Pending verification:',
27 account.requirements.pending_verification);
28 return account;
29}
30
31uploadVerificationDocument('acct_connectedId', './id_front.jpg');

Expected result: The document is uploaded and attached. The requirement moves from currently_due to pending_verification.

3

Update business and personal information

For requirements related to business details or personal information, update the account directly via the API.

typescript
1async function updateAccountInfo(accountId) {
2 const account = await stripe.accounts.update(accountId, {
3 business_profile: {
4 mcc: '5734',
5 url: 'https://sellershop.com',
6 product_description: 'Handmade crafts and artwork',
7 },
8 individual: {
9 address: {
10 line1: '456 Market St',
11 city: 'San Francisco',
12 state: 'CA',
13 postal_code: '94105',
14 country: 'US',
15 },
16 dob: { day: 10, month: 3, year: 1985 },
17 ssn_last_4: '0000', // Test value
18 },
19 });
20
21 console.log('Updated. Remaining requirements:', account.requirements.currently_due);
22 return account;
23}

Expected result: Account information is updated and the corresponding requirements are removed from currently_due.

4

Set up account.updated webhook monitoring

Verification happens asynchronously. Listen for account.updated events to track when requirements change, get fulfilled, or fail.

typescript
1const express = require('express');
2const app = express();
3
4app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
5 const sig = req.headers['stripe-signature'];
6 let event;
7 try {
8 event = stripe.webhooks.constructEvent(
9 req.body,
10 sig,
11 process.env.STRIPE_WEBHOOK_SECRET
12 );
13 } catch (err) {
14 return res.status(400).send(`Webhook Error: ${err.message}`);
15 }
16
17 if (event.type === 'account.updated') {
18 const account = event.data.object;
19 const id = account.id;
20
21 // Check for newly failed verifications
22 if (account.requirements.errors.length > 0) {
23 console.log(`[${id}] Verification errors:`);
24 account.requirements.errors.forEach(e => {
25 console.log(` ${e.requirement}: ${e.reason}`);
26 });
27 // Notify seller to resubmit
28 }
29
30 // Check if fully verified
31 if (account.charges_enabled && account.payouts_enabled &&
32 account.requirements.currently_due.length === 0) {
33 console.log(`[${id}] Fully verified!`);
34 }
35
36 // Check for new deadline
37 if (account.requirements.current_deadline) {
38 const dl = new Date(account.requirements.current_deadline * 1000);
39 console.log(`[${id}] Deadline: ${dl.toISOString()}`);
40 }
41 }
42
43 res.json({ received: true });
44});
45
46app.listen(3000);

Expected result: Webhook handler logs verification errors, full verification status, and deadline changes for connected accounts.

Complete working example

verify-connected-account.js
1const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
2const express = require('express');
3const app = express();
4
5app.use(express.json());
6
7// Get verification status for a connected account
8app.get('/api/accounts/:id/verification', async (req, res) => {
9 try {
10 const account = await stripe.accounts.retrieve(req.params.id);
11 const reqs = account.requirements;
12 res.json({
13 chargesEnabled: account.charges_enabled,
14 payoutsEnabled: account.payouts_enabled,
15 currentlyDue: reqs.currently_due,
16 eventuallyDue: reqs.eventually_due,
17 pastDue: reqs.past_due,
18 pendingVerification: reqs.pending_verification,
19 deadline: reqs.current_deadline
20 ? new Date(reqs.current_deadline * 1000).toISOString()
21 : null,
22 errors: reqs.errors,
23 });
24 } catch (err) {
25 res.status(400).json({ error: err.message });
26 }
27});
28
29// Generate onboarding link to fix requirements
30app.post('/api/accounts/:id/fix', async (req, res) => {
31 try {
32 const link = await stripe.accountLinks.create({
33 account: req.params.id,
34 refresh_url: `${req.headers.origin}/verify/refresh?acct=${req.params.id}`,
35 return_url: `${req.headers.origin}/verify/done?acct=${req.params.id}`,
36 type: 'account_onboarding',
37 });
38 res.json({ url: link.url });
39 } catch (err) {
40 res.status(400).json({ error: err.message });
41 }
42});
43
44// Webhook for verification updates
45app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
46 const sig = req.headers['stripe-signature'];
47 let event;
48 try {
49 event = stripe.webhooks.constructEvent(
50 req.body, sig, process.env.STRIPE_WEBHOOK_SECRET
51 );
52 } catch (err) {
53 return res.status(400).send(`Webhook Error: ${err.message}`);
54 }
55 if (event.type === 'account.updated') {
56 const acct = event.data.object;
57 console.log(`Account ${acct.id}:`);
58 console.log(` charges=${acct.charges_enabled} payouts=${acct.payouts_enabled}`);
59 console.log(` due=${acct.requirements.currently_due.length}`);
60 console.log(` errors=${acct.requirements.errors.length}`);
61 }
62 res.json({ received: true });
63});
64
65app.listen(3000, () => console.log('Verification server on port 3000'));

Common mistakes when verifying a connected account in Stripe

Why it's a problem: Only checking requirements at onboarding time and not monitoring ongoing changes

How to avoid: Requirements can change after initial onboarding. Set up account.updated webhooks to catch new requirements.

Why it's a problem: Uploading wrong file types for identity documents

How to avoid: Stripe accepts JPEG, PNG, and PDF for identity documents. File must be under 8MB. Ensure the image is clear and not blurry.

Why it's a problem: Ignoring pending_verification array

How to avoid: Items in pending_verification are being reviewed by Stripe. Do not ask the seller to resubmit until the review completes.

Why it's a problem: Not distinguishing between currently_due and eventually_due

How to avoid: Currently_due must be completed now. Eventually_due has a future deadline. Prioritize currently_due items.

Best practices

  • Build a verification status dashboard for your platform admins showing all connected accounts and their requirements
  • Send automated email reminders to sellers when requirements approach their deadline
  • For Express accounts, generate Account Links so Stripe handles the verification UI for you
  • Store verification errors in your database for support troubleshooting
  • Use test mode file tokens (file_identity_document_success, file_identity_document_failure) to test all verification scenarios
  • If you manage many connected accounts, consider using RapidDev to build automated verification monitoring pipelines

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

How do I verify connected accounts in Stripe Connect? I need to check requirements, upload identity documents, handle failures, and monitor account.updated webhooks. Show me Node.js code.

Stripe Prompt

Help me build a connected account verification system. I need an API endpoint to check verification status, document upload functionality, and webhook handlers for monitoring verification changes. Use Stripe Connect with Node.js.

Frequently asked questions

How often does Stripe request additional verification?

It varies. New requirements can appear due to regulatory changes, increased transaction volume, or periodic reviews. Some accounts may never get additional requests after initial onboarding.

Can I verify a connected account on behalf of the seller?

For Custom accounts, yes — you can collect and submit all information via the API. For Express accounts, the seller must go through Stripe's hosted onboarding flow.

What happens when a verification document is rejected?

The requirement appears in requirements.errors with a reason code (e.g., document_not_readable, document_expired). Generate a new Account Link for the seller to resubmit.

How long does document verification take?

Automated checks complete in seconds. Manual document reviews take 1-3 business days. The account.updated webhook fires when review is complete.

Can a connected account accept payments while verification is pending?

It depends. If charges_enabled is true, the account can still accept payments even if some requirements are pending. Check charges_enabled rather than the requirements list.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.