Skip to content
Create account
or
Sign in
The Stripe Docs logo
/
Ask AI
Create account
Sign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseManaged Payments
Use Payment Links
Build a checkout page
Build an advanced integration
Build an in-app integration
Payment methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment interfaces
Payment Links
Checkout
Web Elements
In-app Elements
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
In-person payments
Terminal
Beyond payments
Incorporate your company
Crypto
Financial Connections
    Overview
    Get started
    Use cases
    Fundamentals
    Testing
    Supported institutions
    Collect accounts for data
    ACH Direct Debit payments
    Connect payouts
    Other data-powered products
    Access account data
    Balances
    Ownership
    Transactions
    Ownership match
    Manage accounts
    Disconnections
    Webhooks
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
HomePaymentsFinancial Connections

Verify bank account ownership with Financial ConnectionsPrivate preview

Use the Ownership Match API to request match scores on ownership data.

The Ownership Match API helps you verify that your user owns a given bank account. It computes match scores by comparing Financial Connections ownership data with input owner information.

Before you begin

You must have a completed Financial Connections registration to access ownership in live mode. Visit your Dashboard settings to check the state of your registration or begin the registration process. Financial Connections test data is always available.

To access Ownership Match, you must set the API version and beta header to financial_connections_ownership_match_api_preview=v1 in each API request.

Request access to an account's ownership data
Server-side

Detailed steps

  • Access ownership for a Financial Connections Account

You must collect a Financial Connections Account before you can access its ownership data.

Specify the data permissions you need access to with the permissions parameter in the API. Ownership match requires the ownership permission.

Your user can view the set of requested data permissions in the authentication flow.

We recommend that you use prefetch to initiate the ownership refresh as soon as your user connects their account in the authentication flow.

When the ownership data becomes available, we send a financial connections webhook.

Call the Ownership Match API
Server-side

You can pass ownership data to the API using one of the following methods:

  • Create a Customer object for Stripe to compare against
  • Collect a Financial Connections Account with an account holder of type Customer
  • Submit the data through the owner_information parameter

Ownership match accepts up to four input fields, one of which must be from the following list.

  • Name
  • Email address
  • Phone number: Include the plus symbol (+) and country code for international
  • Address: Requires all address fields except line 2

Note

Including all ownership fields increases the score accuracy. For example, you can weigh each field’s match score and use it in your risk modeling.

Create a Customer object Recommended

We recommend that you create a Customer to represent your user. Include all the data you have available that you want to match against.

Stripe loads and matches the data without requiring you to handle sensitive customer data when not strictly required.

For example, you can collect both a Customer and a Financial Connections Account through Stripe products, such as ACH payments in Checkout. After doing so, you can request an ownership match and make a risk decision based on the match result without seeing the customer’s ownership data, and possibly triggering PCI compliance liability.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node
Go
.NET
No results
curl https://api.stripe.com/v1/customers \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d name="Jenny Rosen" \ --data-urlencode email="jennyrosen@example.com" \ --data-urlencode phone="+1 212-555-5555" \ -d "address[line1]"="354 Oyster Point Blvd" \ -d "address[city]"="South San Francisco" \ -d "address[postal_code]"=94080 \ -d "address[state]"=CA \ -d "address[country]"=US

This returns a Customer with the ownership details ownership match can use.

{ "id": "cus_NffrFeUfNV2Hib", "object": "customer", "created": 1651783000, "name": "Jenny Rosen", "address": { "line1": "354 Oyster Point Blvd", "line2": null, "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }, "email": "jennyrosen@example.com", "phone": "+1 212-555-5555", "livemode": false // ... }

Pass the Customer id into the API to match against the Financial Connections Account.

Command Line
cURL
No results
curl https://api.stripe.com/v1/financial_connections/ownership_match \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -H "Stripe-Version: 2025-07-30.basil; financial_connections_ownership_match_api_preview=v1" \ -d financial_connections_account=fca_1MwVK82eZvKYlo2Cjw8FMxXf \ -d type=customer \ -d customer=cus_NffrFeUfNV2Hib

Collect a Financial Connections Account with account holder of type Customer

You can collect a Financial Connections Account with an associated Customer by setting customer to the existing Customer id, and setting its account holder to type customer when creating a Financial Connections Session.

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node
Go
.NET
No results
curl https://api.stripe.com/v1/setup_intents \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -d customer=cus_NffrFeUfNV2Hib \ -d "payment_method_types[]"=us_bank_account \ -d "payment_method_options[us_bank_account][financial_connections][permissions][]"=ownership \ -d "payment_method_options[us_bank_account][financial_connections][permissions][]"=payment_method \ -d "payment_method_options[us_bank_account][financial_connections][prefetch][]"=ownership

This creates a Financial Connections Account with the necessary ownership permissions and an associated Customer. Successful prefetch or refresh of ownership returns the account, including its associated Financial Connections ownership data when ownership is expanded.

{ "id": "fca_1MwVK82eZvKYlo2Cjw8FMxXf", "object": "financial_connections.account", "created": 1651783222, "account_holder": { "customer": "cus_NffrFeUfNV2Hib", "type": "customer" }, "ownership": { "id": "fcaowns_1NtI9uBHO5VeT9SUSRe21lqt", "object": "financial_connections.account_ownership", "created": 1651784999, "owners": { "object": "list", "data": [ { "name": "Jennifer Rosen", "email": "jennyrosen@test.com", "phone": null, "ownership": "fcaowns_1NtI9uBHO5VeT9SUSRe21lqt", "raw_address": "354 Oyster Point Blvd South San Francisco, CA 94080 USA", "refreshed_at": 1651784999 } ], "has_more": false, "url": "/v1/financial_connections/accounts/fca_zbyrdjTrwcYZJZc6WBs6GPid/owners?ownership=fcaowns_1NtI9uBHO5VeT9SUSRe21lqt" } }, "ownership_refresh": { "status": "succeeded", "last_attempted_at": 1651784999, "next_refresh_available_at": 1651785000 }, "permissions": ["ownership", "payment_method"], "prefetch": ["ownership"] // ... }

You can pass the Financial Connections Account id without a specified input type to match its Financial Connections ownership data with its associated account holder Customer data.

Command Line
cURL
No results
curl https://api.stripe.com/v1/financial_connections/ownership_match \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -H "Stripe-Version: 2025-07-30.basil; financial_connections_ownership_match_api_preview=v1" \ -d financial_connections_account=fca_1MwVK82eZvKYlo2Cjw8FMxXf

Submit the data through the owner information parameter

If you choose not to collect ownership data through a Customer, you can also pass user-provided ownership data directly to the API through the owner_information parameter.

{ "owner_information": { "name": "Jenny Rosen", "email": "jennyrosen@example.com", "phone": "+1 212-555-5555", "address": { "line1": "354 Oyster Point Blvd", "line2": null, "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" } } }

Pass the owner information in the API to match against the Financial Connections Account.

Command Line
cURL
No results
curl https://api.stripe.com/v1/financial_connections/ownership_match \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"
\ -H "Stripe-Version: 2025-07-30.basil; financial_connections_ownership_match_api_preview=v1" \ -d financial_connections_account=fca_1MwVK82eZvKYlo2Cjw8FMxXf \ -d type=owner_information \ -d "owner_information[name]"="Jenny Rosen" \ --data-urlencode "owner_information[email]"="jennyrosen@example.com" \ --data-urlencode "owner_information[phone]"="+1 212-555-5555" \ -d "owner_information[address][line1]"="354 Oyster Point Blvd" \ -d "owner_information[address][line2]"= \ -d "owner_information[address][city]"="South San Francisco" \ -d "owner_information[address][state]"=CA \ -d "owner_information[address][postal_code]"=94080 \ -d "owner_information[address][country]"=US

Make decisions based on match results
Server-side

The Ownership Match API returns a 0-100 match score for each input field you supply. You can feed this match score into your own risk logic and modeling, as shown in the examples provided. For example, you can set score thresholds in order to proceed with a payment, or to require more verification such as identity documentation upload before proceeding.

Depending on your risk tolerance and other risk signals from your customer data, you can adjust your logic to require an exact or strong match to proceed with an action, such as continuing a payment or allowing a payout to the account.

function makeRiskDecision(matchResult: Stripe.FinancialConnections.OwnershipMatch) { const nameScore = matchResult.results.name?.match_score? || 0; const addressScore = matchResult.results.address?.match_score? || 0; const emailScore = matchResult.results.email?.match_score? || 0; const phoneScore = matchResult.results.phone?.match_score? || 0; const overallScore = (nameScore + addressScore + emailScore + emailScore) / 4 if (overallScore >= 70) { proceedWithPayment(); } else if (overallScore >= 60) { stepUpVerification(); } else { cancelPayment(); } }

Examples of score interpretations

Name, Email, Address

Sample of match scores compared to the name “Jenny Jane Rosen”, the email “jennyrosen@example.com”, and the following address:

{ "line1": "354 Oyster Point Blvd", "line2": "Fl 1", "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }
ScoreInterpretationName exampleEmail exampleAddress example
100Exact match“Jenny Jane Rosen”“jennyrosen@example.com”
{ "line1": "354 Oyster Point Blvd.", "line2": "Fl. 1", "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }
85-99Very strong match, such as a few characters off“Jneny Jane Rosen”“jenny.rosen@example.com”
{ "line1": "354 Oyster Point Blvd.", "line2": null, "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }
70-84Strong match, such as majority matches“Jenny Rosen”“jennyrosen12345@example.com”
{ "line1": "354 Oyster Point", "line2": "Fl. 10", "city": "San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }
60-69Possible match, such as partial matches or nicknames“Jennifer Rosen”“jennyrosen@test.com”
{ "line1": "354 OP Blvd.", "line2": null, "city": "South SF", "state": "CA", "postal_code": "94080", "country": "US" }
30-59Weak match, such as possible household member or similar fields“Mark Rosen”“marksmith@example.com”
{ "line1": "510 Townsend St.", "line2": null, "city": "San Francisco", "state": "CA", "postal_code": "94103", "country": "US" }
0-29No or unlikely match“Mark Smith”“marksmith@test.com”
{ "line1": "1 University Ave.", "line2": "Fl. 10", "city": "Toronto", "state": "ON", "postal_code": "M5J 2P1", "country": "CA" }

Phone

Sample of phone match scores compared to the phone number “+1 212-555-5555”.

Note

The phone sample interpretation score ranges are broader, because there are fewer granular variations in phone numbers.

ScoreInterpretationExamples
100Exact match“+12125555555”, “(212) 555-5555”
70-99Possible match, such as a digit off or a missing number“212 555 5559” “212 555 555”
50-69Weak match, such as all the same except area code“347 555 5555”
20-49Unlikely match, such as only the same area code“212 999 9999”
0-19No match“347 999 9999”

Sample response

The Ownership Match API also returns the matched owner information and ownership id, as shown in the following sample API response:

{ "id": "fcom_1NtI9uBHO5VeT9SUKLJU5suZ", "object": "financial_connections.ownership_match", "created": 1745858181, "financial_connections_account": "fca_1MwVK82eZvKYlo2Cjw8FMxXf", "type": "customer", "owner_information": { "name": "Jenny Rosen", "address": { "line1": "354 Oyster Point Blvd", "line2": null, "city": "South San Francisco", "state": "CA", "postal_code": "94080", "country": "US" }, "email": "jennyrosen@example.com", "phone": "+1 212-555-5555" }, "customer": "cus_NffrFeUfNV2Hib", "ownership": "fcaowns_1NtI9uBHO5VeT9SUSRe21lqt", "results": { "name": { "match_score": 85, "missing_data": false }, "address": { "match_score": 100, "missing_data": false }, "email": { "match_score": 65, "missing_data": false }, "phone": { "match_score": null, "missing_data": true } } }
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Join our early access program.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc