Linking accounts and creating transfers
Link accounts and initiate transfers
Before initiating a transfer through Plaid, your end users need to link a bank account to your app using Link, Plaid's client-side widget. Link will connect the user's account and obtain and verify the account and routing number required to initiate a transfer.
See the Link documentation for more details on setting up a Plaid Link session. At a high level, the steps are:
Initialize a Link instance using the
link_tokencreated in the previous step. For more details for your specific platform, see the Link documentation. The user will now go through the Link flow.
onSuccesscallback will indicate the user has completed the Link flow. Call
/item/public_token/exchangeto exchange the
access_token. You will also need to obtain the
account_idof the account you wish to transfer funds to or from; this can also be obtained from the
metadata.accountsfield in the
onSuccesscallback, or by calling
Once a Plaid Item is created through Link, you can then immediately process a transfer utilizing that account or initiate the transfer at a later time.
Several major financial institutions require OAuth connections. Make sure to complete the OAuth security questionnaire at least three weeks ahead of time to ensure your connections are enabled by launch. For more information, see the OAuth Guide.
Importing account and routing numbers
If you are migrating from another payment processor and would like to import known account and routing numbers into Plaid, or planning to implement a custom account linking UI, contact your account manager about using the
/transfer/migrate_account endpoint. This endpoint will return an
account_id for a given pair of account and routing numbers. Items created in this way will always have an authorization decision rationale of
MIGRATED_ACCOUNT_ITEM, since Plaid will be unable to assess transfer risk for these Items.
Expanding institution coverage
To see if an institution supports Transfer, use the institution status page in the Dashboard or the
/institutions/get endpoint. If an institution is listed as supporting Auth, it will support Transfer.
Transfer supports all of the same flows as Auth, including the optional Same Day micro-deposit and Automated micro-deposit flows, which allow you to increase the number of supported institutions. Items created with Same Day micro-deposits will always have an authorization decision rationale of
MANUALLY_VERIFIED_ITEM, since Plaid will be unable to assess transfer risk for these Items. For more details about these flows and instructions on implementing them, see Full Auth coverage.
Authorizing a transfer
Before creating a transfer, transfers must pass a risk check and be authorized by Plaid's authorization engine. By default, the engine will run compliance checks including regulatory and program factors such as rate limits, prohibited accounts, suspicious behavior, etc. These will only decline a small portion (<1%) of account and routing numbers. For debit ACH, the account balance is also checked to ensure there are sufficient funds to complete the transfer.
To use Plaid's authorization engine, call
/transfer/authorization/create. You will be required to specify the
account_id from the account linking step, as well as a
user.legal_name, the transaction
amount, the type of the transaction (
credit), and the transaction
rtp). For ACH transfers, an
ach_class is also required. While not mandatory, an
idempotency_key is also strongly recommended to avoid creating duplicate transfers (or being billed for multiple authorizations). If you are a Platform Payments (beta) customer, you will also include an
originator_client_id. For more details on these parameters, see
/transfer/authorization/create in the API Reference.
Plaid will return
'declined' as the authorization decision along with a
decision_rationale and the
authorization_id. If the transaction is approved, you can proceed to Initiate the transfer. Approved authorizations are valid for 1 hour by default, unless otherwise configured by Plaid support. Denied authorizations will have a
description in the
decision_rationale object that provide additional insight.
To avoid blocking transfers,
/transfer/authorization/create will authorize transfers as
approved in circumstances where Plaid can't accurately predict the risk of return. Always monitor the
decision_rationale to understand the full risk of a transfer before proceeding to the submission step.
See the table below to understand different scenarios of authorization decisions.
|Decision Rationale Code
|Plaid performed a balance check and determined there are sufficient funds for the transaction amount
|Plaid couldn't verify the account balance because the item is created through same-day micro-deposits
|Plaid couldn't verify the account balance because the item is created through the migrate account endpoint
|Plaid couldn't verify the account balance because the item went into a stale state
|Plaid couldn't verify the account balance due to an error
|User-account doesn't have sufficient balance to complete the debit transfer
|Plaid determined the transfer is high-risk
|Transfer limit(s) such as daily or monthly transaction limits are being exceeded with this transfer
Initiating a transfer
After assessing a transfer's risk using the authorization engine and receiving an approved response, you can proceed to submit the transfer for processing.
account_id, and a
description (a string that will be visible to the user) to the
/transfer/create endpoint. To make a transfer for less than the amount authorized, provide an optional
amount; otherwise the transfer will be made for the full authorized amount. The
authorization_id will also function similarly to an idempotency key; attempting to re-use an
authorization_key will not create a new transfer, but will return details about the already created transfer. You can also provide the optional field
metadata to include internal reference numbers or other information to help you reconcile the transfer.
/transfer/create will return
transfer_id as well as the
transfer_status. All transfers begin in a
pending status. This status changes as the transfer moves through the payment network. Whenever the status is updated, a Transfer event will be triggered. To learn more about tracking the status of the transfer, see event monitoring.
Initiating an Instant Payout via RTP or FedNow
Initiating an Instant Payout transfer via RTP or FedNow works the same as initiating an ACH transfer. When initiating an Instant Payout transfer, specify
network=rtp when calling
rtp as the network refers to all real time payment rails; Plaid will automatically route between Real Time Payment rail by TCH or FedNow rails as necessary.
Roughly ~70% of accounts in the United States can receive Instant Payouts. If the account is not eligible to receive an Instant Payout,
/transfer/authorization/create will return an
INVALID_FIELD error code with an error message that the account is ineligible for Instant Payouts. If you'd like to see if the account is eligible for Instant Payouts before calling
/transfer/authorization/create, use the
credit style transfers (where you are sending funds to a user) can be sent using Instant Payout transfers.
ACH processing windows
Transfers that are submitted via the
/transfer/create endpoint will be submitted in the next processing window. For a same-day transfer, the cutoff time for the last window of the day is 3:30PM Eastern Time. For a next-day transfer, the cutoff time is 5:30PM Eastern Time. It is recommended to submit a transfer at least 15 minutes before the cutoff time to guarantee that it will be processed before the cutoff.
Note that same-day transfers submitted after 3:30PM Eastern Time and before 5:30PM Eastern Time will be automatically updated to be next-day and submitted to the network in that following ACH processing window. This update applies to sweeps as well. This process minimizes the risk of return due to insufficient funds by reducing the delay between Plaid's balance check and the submission of the transfer to the ACH network. The settlement time remains the same as it would have been if the transfer had been submitted in next same-day window.
ACH processing windows are active only on banking days. ACH transfers will not be submitted to the network on weekends or bank holidays. Keep this in mind when creating transfers over weekends or on bank holidays. To mitigate, wait until the next banking day and then authorize and create the transfer.
See the flow of funds overview for more details on how, and when, funds move.
Bank statement formatting
Each bank has discretion in how they format an ACH, RTP, or FedNow transaction in their bank statements. The most common pattern used is
[Company Name] [Phone Number] [Transfer Description].
[Company Name]is the name provided in your Transfer application. This must match a legally registered name for your company.
[Phone Number]is the phone number that you provided in your Transfer application.
[Transfer Description]is the string that you passed into the description field of your
To request a change to your phone number or company name, please file a support ticket.
To cancel a previously created transfer, call the
/transfer/cancel endpoint with the appropriate
transfer_id. Note that once Plaid has sent the transfer to the payment network, it cannot be cancelled. Practically speaking, this means that Instant Payouts via RTP/FedNow cannot be cancelled, as these transfers are immediately sent to the payment network. You can check use the
cancellable property found via
/transfer/get to determine if a transfer is eligible for cancellation.
Sweeping funds to funding accounts
There are two types of bank accounts in the Plaid Transfer system.
The first is a consumer checking and savings account connected via Plaid Link, where you are pulling money from or issuing a payout to. In the Transfer API, this account is represented by an
account_id of a Plaid Item. A "transfer" is an intent to move money to or from this account.
The second type of account involved is your own business checking account, which is linked to your Plaid Ledger. This account is configured with Plaid Transfer during your onboarding by using the details provided in your application. A "sweep" pushes money into, or pulls money from, a business checking account. For example, funding your Plaid Ledger account by calling
/transfer/ledger/deposit will trigger a sweep event.
If you are using the legacy funding flows method instead of Plaid Ledger, a transfer will automatically kick off the appropriate sweep to complete the flow of funds. For example, if a number of transfers are initiated to pull money from consumer accounts, a single sweep will then be generated to push the aggregate funds. For more details, see the legacy flow of funds.