Introduction to Income
Verify income and paystubs with Income.
Explore API
API Reference
View Income requests, responses, and example code
View Income APIQuickstart
View the starter Income sample app and code
View Income QuickstartTroubleshooting
View Income error codes and troubleshooting guides
View Income troubleshooting guideOverview
Plaid Income (currently US only) helps you verify anyone's income and employment in seconds, facilitating an improved decisioning and underwriting process. Depending on the Income product you choose, you can request information such as pay stub data, income streams, and historical income. You can verify a user's income via three products:
Payroll Income: Retrieve income information, including the information available on a pay stub, from a user-connected payroll account. For an example of data returned, see the API Reference.

Document Income: Retrieve parsed income information via user-uploaded documents such as a pay stub, W-2, or 1099 form. For an example of data returned, see the API Reference.

Bank Income: Retrieve income information from a user-connected bank account. Data available includes a breakdown of income streams to the account, as well as recent and historical income. For an example of data returned, see the API Reference.

Income is configurable, allowing you to choose at the time of connection which income verification method best suits your user’s needs. The Document Income solution is a natural fallback to the Payroll Income solution, but you are also able to mix and match income verification methods.
For a fuller view of a borrower's financial situation, Income can also be used with Assets, which provides user-permissioned asset verification.
Depending on your use case, you may want to enable different income verification methods. If your use case relies on net income or income deposited in a user’s bank account, you can use Bank Income. If you plan to use other Plaid products, such as Auth and Balance for payments, or Assets for asset verification, Bank Income allows for a single Link experience, without requiring your user to go through multiple flows. For use cases that require gross income verification, you may want to use Payroll and/or Document Income.
Method | Data source | Processing time | Income supported | Integrates w/other Plaid APIs |
---|---|---|---|---|
Bank Income | User logs in to bank account | Instant | Net / gross (W2, self-employment, gig, multi-stream) | Yes |
Payroll Income | User logs in to payroll provider | Instant | ~80% of US workforce (both W2 and gig) | No |
Document Income | User uploads W2 or pay stubs | ~15 min | Any W2 or pay stub income | No |
Income integration process
- Call
/user/create
to create auser_token
that will represent the end user interacting with your application. This step will only need to be done once per end user. - (Optional) Call
/credit/payroll_income/precheck
with theuser_token
. This endpoint will indicate Plaid's confidence that a user will be able to complete the Payroll Income flow and can increase conversion by customizing the Payroll flow in Link for the specific user. For users where the endpoint returns a low confidence in their ability to connect via Payroll Income, we recommend you launch Link with either Document Income or Bank Income instead. - Call
/link/token/create
. In addition to the required parameters, you will need to provide the following:- For
user_token
, provide theuser_token
from/user/create
. - For
products
, use["income_verification"]
. If using Bank Income, you can also specify additional products, but note that it is not recommended to specifytransactions
along withincome_verification
; if you want to use Transactions with Bank Income, initialize Bank Income first. For more details, see Choosing how to initialize products. - For
income_verification.income_source_types
, use eitherpayroll
(for Payroll and Document Income) orbank
(for Bank Income). If using Bank Income, you must also specify how many days of data to collect viaincome_verification.bank_income.days_requested
. You can further customize the flows enabled and the amount of data collected via optional parameters; see the API Reference for more details. - Provide a
webhook
URI with the endpoint where you will receive Plaid webhooks. - If you collect income information directly from your users, provide it in the
income_verification.stated_income_sources
parameter. This data is used to improve the accuracy of data sent back to you, such as income stream categories.
- For
- On the client side, create an instance of Link using the
link_token
returned by/link/token/create
; for more details, see the Link documentation. - Open Link in your web or mobile client and listen to the
onSuccess
andonExit
callbacks, which will fire once the user has finished or exited the Link session.- If using Bank Income, call
/credit/sessions/get
in your server after receivingonSuccess
, passing in theuser_token
from step 1.- If the user has finished the Bank Income verification flow, then the most recent session will have a
bank_income_result
with statusAPPROVED
. - If you are using other Plaid products such as Auth or Balance alongside Bank Income, make sure to capture each
public_token
from theitem_add_results
array returned by/credit/sessions/get
and exchange it for anaccess_token
. For more details on token exchange flows, see the Token exchange flow. - If using a Multi-Item session, you will also need to call
/credit/sessions/get
after receiving theonExit
callback; for more details, see Enabling Multi Item Sessions for Bank Income.
- If the user has finished the Bank Income verification flow, then the most recent session will have a
- If using Payroll or Document Income, listen for the
INCOME: INCOME_VERIFICATION
webhook. For more details, see Income webhooks.
- If using Bank Income, call
- (Optional, Document Income only) To retrieve document fraud signals as part of the Document Income flow, call
/credit/payroll_income/risk_signals/get
. - To retrieve data, call the credit endpoints using the
user_token
.- For Payroll or Document Income, call
/credit/payroll_income/get
. - For Bank Income, call
/credit/bank_income/get
.
- For Payroll or Document Income, call
Income webhooks
When using Payroll or Document Income, Plaid will asynchronously process the income data and send an INCOME: INCOME_VERIFICATION
webhook once processing is complete. If processing was successful, the webhook's verification_status
value will be VERIFICATION_STATUS_PROCESSING_COMPLETE
. If you attempt to retrieve the income data before it has been processed, you may receive a 400 response with the error code PRODUCT_NOT_READY
. Awaiting the webhook before calling /credit/payroll_income/get
is strongly recommended.
Processing will usually complete within a few seconds if the user's income was verified via Payroll Income. If the user verified their income via Document Income, processing may take up to 45 minutes.
When using Bank Income, no webhooks are sent; data will be available immediately.
Testing Income
Income can be tested in Sandbox against test data without contacting Plaid. In order to test Income against live Items in either Development or Production, you will need to first request access by submitting a product access request Support ticket explaining your use case.
In the Sandbox environment, when testing Document Income, the contents of the actual document will not be processed and Sandbox will instead use pre-populated test data. This data will be available immediately. To test that your application properly handles the real-world delayed processing behavior of Document Income, test in the Development environment.
/credit/payroll_income/get
can optionally be tested in Sandbox without using Link. Call /user/create
, pass the returned user_token
to /sandbox/public_token/create
(ins_90
is a good sample institution_id
for testing Income in Sandbox), and then call /credit/payroll_income/get
. The output of /sandbox/public_token/create
will not be used, but calling it initializes the user token for testing.
To test the /credit/payroll_income/precheck
endpoint in Sandbox, use test employer objects with the employer names employer_good
or employer_bad
, to generate HIGH
or LOW
confidence scores. employer_multi
can be used to generate a HIGH
confidence score with multiple payroll options. Any other employer will result in an UNKNOWN
confidence score. Likewise, use the test access tokens access_good
or access_bad
to generate HIGH
or LOW
confidence scores. Any other access token will result in an UNKNOWN
confidence score.
Plaid provides a GitHub repo with test data for testing Income; make sure to update any test data in these files to be dated within the last 90 days before using this data in Sandbox. For more information on configuring custom Sandbox data, see Configuring the custom user account.
Testing Bank Income
To help you test Bank Income, Plaid provides a custom Sandbox user with Bank Income. To use the custom user, select a non-OAuth institution within Link and use username user_bank_income
and password {}
. This will provide up to two years of income data with various income categories and pay frequencies. Please note: the basic Sandbox credentials (user_good
/pass_good
) will not return data when used to test Bank Income.
If you’d like to test Bank Income with custom data, Plaid also provides a test JSON configuration object. To load this data into Sandbox, update the JSON object so that all transaction dates are within the date range requested and then copy and paste the JSON into the Sandbox Users pane in the Dashboard.
/credit/bank_income/get
can optionally be tested in Sandbox without using Link. Call /user/create
and pass the returned user_token
to /sandbox/public_token/create
. /sandbox/public_token/create
must be called with the following request body:
1{2 "client_id": "your-client-id-goes-here",3 "secret": "your-sandbox-secret-goes-here",4 "institution_id": "ins_20", //any valid institution id is fine5 "initial_products": ["income_verification"],6 "user_token": "user-token-goes-here", //use the user_token from the `/user/create` call made earlier7 "options": {8 "override_username": "user_bank_income",9 "override_password": "{}",10 "income_verification": {11 "income_source_types": ["bank"],12 "bank_income": {13 "days_requested": 180 //any number of days under 730 is valid14 }15 }16 },17}
After calling /sandbox/public_token/create
, call /credit/bank_income/get
using the same user_token
. The output of /sandbox/public_token/create
will not be used, but calling it initializes the user token for testing.
Enabling multi-Item sessions for Bank Income
Many users get income deposited into multiple institutions. To help capture a user’s full income profile, you can allow your users to link multiple accounts within the same link session on web integrations.

To enable this flow, when calling /link/token/create
set the bank_income.enable_multiple_items
option to true
.
After the user has exited Link and you receive an onSuccess
or onExit
callback, there will be a distinct item_add_result
returned in the /credit/sessions/get
response for each Item the user successfully linked. If the user has completed the Bank Income verification flow for a given Item, there will be a corresponding bank_income_result
for that Item with status APPROVED. Ensure that you call /credit/sessions/get
for both onSuccess
and onExit
Link callbacks, as the Link callback will only reflect the state of the last Item linked.
While you can access Bank Income data with the user_token
, if you are planning to use these account connections for other Plaid products (such as Auth, Balance, etc.), make sure to exchange each public token found in the item_add_result
s for an access token, using /item/public_token/exchange
.
Verifying Bank Income for existing Items
If your user has already connected their depository bank account to your application for a different product, you can add Bank Income to the existing Item via update mode.
To do so, in the /link/token/create
request described above, populate the access_token
field with the access token for the Item. If the user connected their account less than two years ago, they can bypass the Link credentials pane and complete just the Income Verification step. Otherwise, they will be prompted to complete the full Plaid Bank Income Link flow.
Optional Document Income features
Fraud detection
To detect potential document fraud or document tampering during the Document Income flow, use the optional /credit/payroll_income/risk_signals/get
endpoint. This endpoint is not enabled by default; to request access, contact support or your Plaid Account Manager.
Customizing document types
To limit which types of documents your users can upload, create a Link customization in the Dashboard after you have received Production access. For more details, see Document upload settings.
Sample app code
For an example of an app that incorporates Income, see the React and NodeJS-based Income Sample app. This application uses Income and Liability data to help determine whether the user can qualify for financing on a pre-owned hoverboard. It supports the use of Payroll, Document, and Bank Income data.
Next steps
To learn more about Income endpoints, see the Income API Reference. For additional guidance and tips on implementing Income, you can also see the Plaid income verification solution guide.
If you're ready to launch to Production, see the Launch checklist.