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 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.
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. 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.
|Scenario||Authorization Decision||Decision Rationale Code|
|Plaid performed a balance check and determined there are sufficient funds for the transaction amount||Approved|
|Plaid couldn't verify the account balance because the item is created through same-day micro-deposits||Approved||"|
|Plaid couldn't verify the account balance because the item is created through the migrate account endpoint||Approved||"|
|Plaid couldn't verify the account balance because the item went into a stale state||Approved||"|
|Plaid couldn't verify the account balance due to an error||Approved|
|User-account doesn't have sufficient balance to complete the debit transfer||Declined|
|Plaid determined the transfer is high-risk||Declined|
|Transfer limit(s) such as daily or monthly transaction limits are being exceeded with this transfer||Declined|
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.
authorization_id and other required fields to the
/transfer/create endpoint. You can also provide the optional fields
description, to provide a string that will be visible to the user, and
metadata, to provide 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 Transfer 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
credit_funds_source=prefunded_rtp_credits 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.
Instant Payout transfers are funded using your Plaid Ledger balance. See Using funds from your Plaid Ledger Balance for more details on how to set up and use the Plaid Ledger.
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
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 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 also applies to the sweep. 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 statments. 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 a
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 represented in Plaid Transfer by a
funding_account_id. This account is configured with Plaid Transfer during your onboarding by using the details provided in your application. You can find your list of
funding_account_ids in the Accounts page of your Plaid Dashboard under the Account ID column. A "sweep" pushes money into, or pulls money from, a funding account.
By default, a transfer will automatically kick off the appropriate sweep to complete the flow of funds between the consumer account and your business checking account. 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 to your business checking account. If a transfer is initiated to payout your customers with ACH credits, a sweep will be automatically generated to pull money from your business checking account to fund those transfers. If you are issuing payouts via Plaid Ledger, no sweep will be generated as the funds are withdrawn from your available balance. For more details, see the Flow of funds.