Linking accounts and creating transfers
Link accounts and initiate transfers
Account Linking
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:
Call
/link/token/create
, specifyingtransfer
in theproducts
parameter.Initialize an Embedded Institution Search Link instance using the
link_token
created in the previous step. For more details for your specific platform, see the Link documentation. The user will now go through the Link flow.The
onSuccess
callback will indicate the user has completed the Link flow. Call/item/public_token/exchange
to exchange thepublic_token
returned byonSuccess
for anaccess_token
. You will also need to obtain theaccount_id
of the account you wish to transfer funds to or from; this can also be obtained from themetadata.accounts
field in theonSuccess
callback, or by calling/accounts/get
.
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.
Optimizing the Link UI for Transfer
The following Link configuration options are commonly used with Transfer:
- Account select: The "Account Select: Enabled for one account" setting configures the Link UI so that the end user may only select a single account. If you are not using this setting, you will need to build your own UI to let your end user select which linked account they want to use with Transfer. When using Transfer UI, this setting is mandatory.
- Embedded Institution Search: This presentation mode shows the Link institution search screen embedded directly into your UI, before the end user has interacted with Link. Embedded Institution Search increases end user uptake of pay-by-bank payment methods and is strongly recommended when implementing Transfer as part of a pay-by-bank use case where multiple different payment methods are supported.
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, planning to implement a custom account linking UI, or intend to use wire transfers as a payment rail, contact your account manager about using the /transfer/migrate_account
endpoint. This endpoint will return an access_token
and 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 micro-deposit and database-based flows, which allow you to increase the number of supported institutions and provide pathways for end users who can't or don't want to log in to their institutions. Items created with Same Day micro-deposits, Database Insights, or Database Match 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 access_token
and account_id
from the account linking step, as well as a user.legal_name
, the transaction amount
, the type of the transaction (debit
or credit
), and the transaction network
(ach
, same-day-ach
, rtp
, or wire
-- to request wire
transfers, contact your Account Manager). For ACH transfers, an ach_class
is also required. 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.
Failure to provide an idempotency_key
when calling /transfer/authorization/create
may result in duplicate transfers when retrying requests. It is only safe to omit idempotency keys if you have already built and thoroughly tested your own logic to avoid creating or processing duplicate authorizations. Even if you have, idempotency keys are still strongly recommended.
Plaid will return 'approved'
, 'declined'
or 'user_action_required'
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. You may cancel approved authorizations through the /transfer/authorization/cancel
endpoint if you no longer intend to use the authorization. Denied authorizations will have a code
and description
in the decision_rationale
object that provide additional insight.
To avoid blocking transfers, /transfer/authorization/create
may 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 | null |
Plaid couldn't verify the account balance because the item is created through same-day micro-deposits | approved | "MANUALLY_VERIFIED_ITEM " |
Plaid couldn't verify the account balance because the item is created through the migrate account endpoint | approved | "MIGRATED_ACCOUNT_ITEM " |
Plaid couldn't verify the account balance due to an error | approved | "ERROR" |
Plaid couldn't verify the account balance because the item went into a stale state | user_action_required | "ITEM_LOGIN_REQUIRED " |
User-account doesn't have sufficient balance to complete the debit transfer | declined | "NSF" |
Plaid determined the transfer is high-risk | declined | "RISK" |
Transfer limit(s) such as daily or monthly transaction limits are being exceeded with this transfer | declined | "TRANSFER_LIMIT_REACHED" |
ACH SEC codes
The ACH Standard Entry Class (SEC) code is represented in the Plaid API by the ach_class
field and is required for all ACH transfers. SEC codes indicate the type of authorization the originator received in order to submit an ACH payment instruction into the ACH network. Using the incorrect code can result in a failed transfer authorization, ACH returns outside of the expected return window, or, if not remedied, eventual loss of access to Transfer.
Plaid permits only the following SEC codes to be utilized for ACH Transfers:
ACH Debit | ACH Credit | |
---|---|---|
Consumer accounts | web , tel | ppd |
Business accounts | ccd | ccd |
Transfer customers are approved for SEC codes based on the information supplied in the Transfer application. If an unapproved or unsupported SEC code is submitted, the transfer authorization request will fail with the error TRANSFER_FORBIDDEN_ACH_CLASS
.
SEC code definitions:
ccd
- Corporate Credit or Debit. The transfer moves funds to or from a business bank account
ppd
- Prearranged Payment or Deposit. The transfer is part of a pre-existing relationship with a consumer. Can be used for credits or debits.
tel
- Telephone-Initiated Entry. The transfer debits a consumer. Debit authorization has been received orally over the telephone.
web
- Internet-Initiated Entry. The transfer debits a consumer’s bank account. Authorization from the consumer is obtained over the Internet.
SEC codes and ACH returns
SEC codes determine how long Receiving Depository Financial Institutions (RDFIs, i.e. counterparty banks) have to submit ACH returns for the transfers. ACH debit transfers labeled with consumer SEC codes (web
, tel
) permit RDFIs to submit unauthorized returns (R07, R10, R11, etc.) for up to 60 days after the effective date of the transfer, even if the debit was to a business bank account. If a consumer account is debited using a business SEC code (ccd
), the RDFI can return the transfer for up to 60 days with an R05 return code because is it not proper to debit consumers using a business SEC code.
Handling user_action_required
Sometimes Plaid needs to collect additional user input in order to properly assess transfer risk. The most common scenario is to fix a stale Item. In this case, Plaid returns user_action_required
as the authorization decision.
To complete the required user action:
- Create a new link token via
/link/token/create
. Instead of providingaccess_token
, you should settransfer.authorization_id
in the request. - Initialize Link with the
link_token
. Link will automatically guide the user through the necessary steps. - You do not need to repeat the token exchange step in Link's
onSuccess
callback as the Item'saccess_token
remains unchanged.
After completing the required user action, you can retry the /transfer/authorization/create
endpoint with the same request body. You can even reuse the same idempotency_key
as idempotency does not apply to user_action_required
authorizations.
ACH Guarantee
For customers in select industries, Plaid offers an ACH Guarantee that shields you from bank-initiated ACH returns. If your transfers are guaranteed with Plaid, an approved
decision in the authorization process means that the transfer will have the Guarantee applied. To learn more about Plaid's ACH Guarantee and whether you are eligible for this service, contact sales or your Plaid account manager.
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.
Pass the authorization_id
, access_token
, 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_id
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.
Handling errors in transfer creation
If you receive a retryable error code such as a 500 (Internal Server Error) or 429 (Too Many Requests) when creating a transfer, you should retry the transfer; Plaid uses the transfer_id
as an idempotency key, so you can be guaranteed that retries to /transfer/create
will not result in duplicate transfers.
A request to /transfer/create
may fail with a 500 error even if the transfer is successfully created. You should not assume that a 500 error response to a /transfer/create
call means that the transfer failed. As a source of truth for the transfer status, use Transfer events.
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 /transfer/authorization/create
. 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 /transfer/capabilities/get
endpoint.
Only 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 8: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 8: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/transfer/create
request.
To request a change to your phone number or company name, please file a support ticket.
Cancelling transfers
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 access_token
and 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.
Sweeps can be observed via the /transfer/sweep/list
and /transfer/sweep/get
endpoints.
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.
Transfer limits
When you sign up with Plaid Transfer, you will be assigned transfer limits, which are placed on your authorization usage. These limits are initially assigned based on the volume expectations you provide in your transfer application. When you successfully create an authorization using /transfer/authorization/create
, the amount authorized will be counted against your limits. Authorized amounts that aren’t used will stop counting towards your limits if the authorization expires or is canceled (via /transfer/authorization/cancel
).
Any authorization you attempt to create over your limits will be automatically declined.
Limit | Debit | Credit |
---|---|---|
Single Transfer | The maximum amount of a single debit transfer authorization | The maximum amount of a single credit transfer authorization |
Daily | The maximum amount of debit transfers you may authorize in a calendar day | The maximum amount of credit transfers you may authorize in a calendar day |
Monthly | The maximum amount of debit transfers you may authorize in a calendar month | The maximum amount of credit transfers you may authorize in a calendar month |
Daily limits refresh every day and monthly limits refresh on the first day of the month at 12:00 AM EST.
Limit monitoring
You can view your current limits on the “Account Details” page in the Transfer Dashboard. You can monitor your usage against your daily and monthly limits via the Account Information widget on the Overview page. You can also monitor your authorization limits and usage through the Transfer APIs.
The /transfer/configuration/get
endpoint returns your configurations for each of the transfer limits. The /transfer/metrics/get
endpoint contains information about your daily and monthly authorization usage for credit and debit transfers.
Plaid will also send you automatic email notifications when your utilization is approaching your limits. If your daily utilization exceeds 85% of your daily limits or your monthly utilization exceeds 80% of your monthly limits, you will receive automated email alerts. These alerts will be sent to your ACH, Technical, and Billing contacts. You can configure those contacts via the Company Profile page on the Plaid dashboard.
Any call to /transfer/authorization/create
that will cause you to exceed your limits will return the decision "declined"
with the decision rationale code set to TRANSFER_LIMIT_REACHED
. The rationale description identifies which specific limit has been reached.
Requesting limit changes
If you need to change your limits for any reason, you can request changes via the Account Details page in the Plaid Dashboard.