Guarantee
Learn how Plaid guarantees ACH transactions
API Reference
View Transfer requests, responses, and example code
View Transfer APIQuickstart
Learn about Plaid's key concepts and run starter code
Get startedGuarantee is currently in closed beta and approval is required to participate. If you're interested in learning more or participating in the beta program, contact Sales or, for existing customers, your Account Manager.
Transfer is only supported in Plaid's Sandbox and Production environments.
Overview
Guarantee is an optional feature in Plaid Transfer. With Guarantee, Plaid analyzes proposed transfers and guarantees a subset of them. If a Plaid-guaranteed transfer is returned, Plaid will cover the cost of the ACH return and the funds will never leave your bank account.
Guarantee also enables faster fund availability. Once Plaid guarantees a transfer, the funds will be included in the next sweep, even if the transfer is not yet settled. Additionally, there is no holding period for guaranteed debit transfers.
Guarantee is backwards compatible with existing Transfer integrations – no changes are necessary to use it. Information about transfer guarantees is provided in the response payloads of the /transfer/authorization/create
and /transfer/create
endpoints.
In order to qualify for a guaranteed transfer, the following fields are required when calling /transfer/authorization/create
: idempotency_key
, user.phone_number
(optional if email_address
provided), user.email_address
(optional if phone_number
provided), device.ip_address
, device.user_agent
, and user_present
.
Using a beacon
Plaid’s beacon collects non-intrusive data that helps our models combat fraudulent transactions. Improved detection helps increase your guarantee coverage and control your return rates. This process occurs behind the scenes and does not impact page load time for consumers. Plaid requires a beacon to be implemented for Guarantee customers who are not using Transfer UI and have a web checkout experience.
Installing a beacon on your webpage
The beacon script for web can be found at https://cdn.plaid.com/beacon/stable/beacon.js and exposes runPlaidBeacon
, which can be used to run it and retrieve a beacon_session_id
. For best results, we recommend loading and running the beacon script upon checkout page load.
1// beacon.ts2declare global {3 interface Window {4 runPlaidBeacon: () => Promise<{ beacon_session_id: string }>;5 }6}78let beaconLoaded: Promise<9 () => Promise<{ beacon_session_id: string }>10> | null = null;1112const beacon = async function(): Promise<{ beacon_session_id: string }> {13 if (beaconLoaded == null) {14 beaconLoaded = new Promise(resolve => {15 const script = document.createElement('script');16 script.type = 'text/javascript';17 script.async = true;18 script.src = 'https://cdn.plaid.com/beacon/stable/beacon.js';19 script.onload = async () => {20 resolve(window.runPlaidBeacon);21 };22 document.head.appendChild(script);23 });24 }25 return beaconLoaded.then(async runPlaidBeacon => {26 return await runPlaidBeacon();27 });28};2930// Returns an Object with beacon_session_id set31beacon();
The beacon_session_id
is cached by runPlaidBeacon
so if you prefer not to store it, you can re-call beacon
at a later point, which will either retrieve the cached value or will re-run the script and return a fresh beacon_session_id
if the cached one has expired.
Including beacon_session_id
on Transfer API requests
The beacon_session_id
will need to be threaded through to the place where you make the API call to Plaid (specifically the /transfer/authorization/create
endpoint) and included on the request body.
1const request: TransferAuthorizationCreateRequest = {2 access_token: 'access-sandbox-71e02f71-0960-4a27-abd2-5631e04f2175',3 account_id: '3gE5gnRzNyfXpBK5wEEKcymJ5albGVUqg77gr',4 type: 'credit',5 network: 'ach',6 amount: '12.34',7 ach_class: 'ppd',8 user: {9 legal_name: 'Anne Charleston',10 },11 beacon_session_id: '97150461-72b3-4779-9a54-6982488ed436',12};1314try {15 const response = await client.transferAuthorizationCreate(request);16 const authorizationId = response.data.authorization.id;17} catch (error) {18 // handle error19}
Guarantees and sweeps
Guarantees
When /transfer/authorization/create
is called, Plaid performs a risk assessment on the proposed transfer and determines whether the transfer can be guaranteed. The response will contain information about the guarantee.
1{2 "authorization": {3 "id": "c685bd6e-108e-4c61-834a-2548a0ff2176",4 "created": "2020-08-06T17:27:15Z",5 "decision": "approved",6 "decision_rationale": null,7 "guarantee_decision": "NOT_GUARANTEED",8 "guarantee_decision_rationale": {9 "code": "RETURN_BANK",10 "description": "..."11 },12 "proposed_transfer": { ... },13 },14 "idempotency_key": "74e0b11e-28a5-11ed-a261-0242ac120002",15 "request_id": "saKrIBuEB9qJZno"16}
If the transfer is guaranteed, the guarantee_decision
decision field in the response will be "GUARANTEED"
and the guarantee_decision_rationale
field will be null
. If the transfer is not guaranteed, the guarantee_decision
field will be "NOT_GUARANTEED"
and the guarantee_decision_rationale
object will include more information about why the transfer could not be guaranteed. This information is also returned in the response payload of /transfer/create
when the transfer is created.
Sweeps
Once Plaid receives a transfer creation request that's been guaranteed, the amount of that transfer is then included in the next sweep. At a later time, if that guaranteed transfer is returned, Plaid does not reverse-sweep the fund and the sweep_status
of the transfer remains as swept
.
For example, you collect a total of $3000 debits from users, of which $500 is guaranteed. On the same day (let’s say before the ACH cutoff window on that day), a $500 sweep is originated. The next day Plaid receives a $100 guaranteed return and a $200 non-guaranteed return. If you have 1 day hold on debits, the net-sum of the sweep on this day would be $2300. In total, you receive $2800. You are only responsible for the $200 return which is not guaranteed.
Simulating Guarantees in Sandbox
In the Sandbox environment, all transfer amounts less than or equal to $20 will be guaranteed, while amounts over $20 will not be guaranteed, allowing you to test both guaranteed and non-guaranteed transfers.
Sample Sandbox scenarios
Create 4 transfers using
/transfer/authorization/create
and/transfer/create
for $5, $10, $20, and $40. All but the $40 transaction will be guaranteed.Simulate a
"posted"
event for all transfers by calling the/sandbox/transfer/simulate
.Simulate a sweep by calling
/sandbox/transfer/sweep/simulate
. Confirm the $75 sweep amount using/transfer/sweep/list
and/transfer/event/list
. Inspect each transfer with/transfer/get
and confirm thatsweep_status
is"swept"
.Simulate a
"returned"
event for the $10, $20, and $40 transfers by calling/sandbox/transfer/simulate
.Simulate a sweep by calling
/sandbox/transfer/sweep/simulate
. Confirm the sweep amount is -$40. Inspect that only the $40 transfer’ssweep_status
is"return_swept"
. In this scenario, the $10 and $20 transfers were guaranteed and are not deducted. The $5 transfer is not deducted as it was not returned, and the returned $40 transfer is deducted as it was not guaranteed.