Database Insights (beta)
Evaluate a manually entered account using Plaid network data
Overview
Database Insights (beta) can increase conversion by providing instant account verification without requiring users to link a bank account via credentials. End users choosing the manual Database Insights path will not be required to log in to their financial institution and instead can enter their account and routing number manually.
Database Insights verifies account and routing numbers by checking the information provided against Plaid's known account numbers, leveraging Plaid's database of over 200 million verified accounts. If no match is found, Plaid will check the account number format against known usages by the institution associated with the given routing number. Database Insights will provide a verification status of 'pass', 'pass with caution', or 'fail' and a set of attributes that contributed to that status, such as whether a match was found or whether Plaid fell back to checking account number formats.
Database Insights does not verify that the user has access to the bank account and Database Insights does also not fully guarantee that the account exists, especially in a 'pass with caution' scenario. For these reasons, Database Insights should only be enabled where there is a low risk of fraud or ACH returns. Examples of use cases where Database Insights may be appropriate include bill payment, rent collection, business to business payments, or subscription payments.
Approximately 30% of Items verified by Database Insights can also be verified by /identity/match
or /signal/evaluate
. For more details, see Identity Match and Signal. All Items verified with Database Insights are also compatible with account ownership identity verification via Identity Document Upload.
Database Insights and Embedded Institution Search are both designed to increase adoption of ACH payment methods and are frequently used together. Database Insights is also fully compatible with the standard, non-Embedded Institution Search Link flow.
Database Insights is currently in closed beta and subject to change. Contact your Plaid account manager to request access.
Database Insights flow
- Starting on a page in your app, the user clicks an action that opens Plaid Link.
- Inside of Plaid Link, the user selects an option to enter the manual verification flow and provides their account and routing number.
- Once the user has submitted their information, Link closes and returns a
public_token
within theonSuccess
callback. - Call
/item/token/exchange
to exchange thepublic_token
for anaccess_token
, then call/auth/get
to obtain the account numbers and the verification results. - Based on the values of the
verification_status
andverification_insights
fields returned by/auth/get
, make a decision whether to proceed with the account information for ACH or to reject the account information as unverified.
When using other flows, customers using a processor partner do not typically need to call /auth/get
, and can directly call /processor/token/create
instead. However, if you are using Database Insights with a processor partner, you must call /auth/get
and check the value of the verification_status
and/or verification_insights
fields before passing a processor token to the partner.
Implementation steps
Create a link_token
Create a link_token
with the following parameters:
- The
products
array should include onlyauth
ortransfer
as a product when using Database Insights. While in most cases additional products can be added to existing Plaid Items, Items created with Database Insights are an exception and cannot be used with any Plaid products other than Auth, Transfer, Signal, or Identity Match.
Approximately 30% of Items verified by Database Insights can also be verified by /identity/match
or Signal. For more details, see Identity Match and Signal. If using Identity Match or Signal in this way, they should be added to the Item via the required_if_supported_products
, optional_products
, or additional_consented_products
fields rather than the products
array.
country_codes
should be set to['US']
– Database Insights is currently only available in the United States.- The
auth
object should specify"database_insights_enabled": true
. - (Optional) Within the
auth
object, specify"auth_type_select_enabled": true
in order to enable Auth Type Select, which will surface the manual entry point for Database Insights on the default Link screen. If Auth Type Select is not enabled, credential-based flows will be the primary UI flow and the Database Insights entry point will only appear as a fallback; for more details, see Default manual verification flow. An exception is that when using Embedded Institution Search (beta), the Database Insights manual entry point will be present on the default Link screen by default.
Database Insights cannot be used in the same session as Database Match, Same-Day Micro-deposits, or Instant Micro-deposits. If any of those flows are explicitly enabled in the auth
object alongside Database Insights, an error will occur when calling /link/token/create
. If they are implicitly enabled due to account default settings, they will be overridden by enabling Database Insights.
1const request: LinkTokenCreateRequest = {2 user: { client_user_id: new Date().getTime().toString() },3 client_name: 'Plaid App',4 products: [Products.Auth],5 country_codes: [CountryCode.Us],6 webhook: 'https://webhook.sample.com',7 language: 'en',8 auth: {9 database_insights_enabled: true10 },11};12try {13 const response = await plaidClient.linkTokenCreate(request);14 const linkToken = response.data.link_token;15} catch (error) {16 // handle error17}
Initialize Link with a link_token
After creating a link_token
for the auth
product, use it to initialize Plaid Link.
When the user successfully inputs their account and routing numbers, the onSuccess()
callback
function will return a public_token
.
1const linkHandler = Plaid.create({2 // Fetch a link_token configured for 'auth' from your app server3 token: (await $.post('/create_link_token')).link_token,4 onSuccess: (public_token, metadata) => {5 // Send the public_token and connected accounts to your app server6 $.post('/exchange_public_token', {7 publicToken: public_token,8 accounts: metadata.accounts,9 });10
11 metadata = {12 ...,13 link_session_id: String,14 institution: {15 name: null, // name is always null for Database Insights16 institution_id: null // institution_id is always null for Database Insights17 },18 accounts: [{19 id: 'vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D',20 mask: '1234',21 name: null,22 type: 'depository',23 subtype: 'checking' | 'savings',24 verification_status: ''25 }]26 }27 },28 // ...29});30
31// Open Link on user-action32linkHandler.open();
Exchange the public token
In your own backend server, call the /item/public_token/exchange
endpoint with the Link public_token
received in the onSuccess
callback to
obtain an access_token
. Persist the returned access_token
and item_id
in your database
in relation to the user.
1// publicToken and accountID are sent from your app to your backend-server2const accountID = 'vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D';3const publicToken = 'public-sandbox-b0e2c4ee-a763-4df5-bfe9-46a46bce993d';4
5// Obtain an access_token from the Link public_token6const response = await client7 .itemPublicTokenExchange({8 public_token: publicToken,9 })10 .catch((err) => {11 // handle error12 });13const accessToken = response.access_token;
1{2 "access_token": "access-sandbox-5cd6e1b1-1b5b-459d-9284-366e2da89755",3 "item_id": "M5eVJqLnv3tbzdngLDp9FL5OlDNxlNhlE55op",4 "request_id": "m8MDnv9okwxFNBV"5}
Fetch Auth data and verification results
Next, we can retrieve Auth data, along with the results of the Database Insights verification check, by calling /auth/get
.
1const accessToken = 'access-sandbox-5cd6e1b1-1b5b-459d-9284-366e2da89755';2
3// Instantly fetch Auth numbers4const request: AuthGetRequest = {5 access_token: accessToken,6};7const response = await client.authGet(request).catch((err) => {8 // handle error9});10const numbers = response.numbers;
1{2 "numbers": {3 "ach": [4 {5 "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",6 "account": "9900009606",7 "routing": "011401533",8 "wire_routing": "021000021"9 }10 ],11 "eft": [],12 "international": [],13 "bacs": []14 },15 "accounts": [16 {17 "account_id": "vzeNDwK7KQIm4yEog683uElbp9GRLEFXGK98D",18 "balances": { Object },19 "mask": "0000",20 "name": null,21 "official_name": null,22 "verification_status": "database_insights_pass",23 "verification_insights": { 24 "network_status": {25 "has_numbers_match": true, 26 "is_numbers_match_verified": true,27 },28 "previous_returns": { 29 "previous_administrative_return": false,30 },31 "account_number_format": "valid", 32 },33 "subtype": "checking",34 "type": "depository"35 }36 ],37 "item": { Object },38 "request_id": "m8MDnv9okwxFNBV"39}
Making a risk determination
The results of the Database Insights verification can be found in the verification_status
and verification_insights
fields returned by /auth/get
. Based on the values in these fields, you will make a business decision on whether to accept the account numbers as verified, take additional risk mitigation steps, or reject the account numbers as unverified.
Testing Database Insights in Sandbox
For test credentials that can be used to test Database Insights in the Sandbox environment, see Testing Database Insights.