Sandbox endpoints
API reference for Sandbox endpoints
Introduction
Plaid's Sandbox environment provides a number of endpoints that can be used to configure testing scenarios. These endpoints are unique to the Sandbox environment and cannot be used in Production. For more information on these endpoints, see Sandbox.
| In this section | |
|---|---|
/sandbox/public_token/create | Bypass the Link flow for creating an Item |
/sandbox/processor_token/create | Bypass the Link flow for creating an Item for a processor partner |
/sandbox/item/reset_login | Trigger the ITEM_LOGIN_REQUIRED state for an Item |
/sandbox/user/reset_login | (Income and Check) Force Item(s) for a Sandbox user into an error state |
/sandbox/item/fire_webhook | Fire a specific webhook |
/sandbox/item/set_verification_status | (Auth) Set a verification status for testing micro-deposits |
/sandbox/transfer/fire_webhook | (Transfer) Fire a specific webhook |
/sandbox/transfer/ledger/deposit/simulate | (Transfer) Simulate a deposit sweep event |
/sandbox/transfer/ledger/simulate_available | (Transfer) Simulate converting pending balance into available balance |
/sandbox/transfer/ledger/withdraw/simulate | (Transfer) Simulate a withdraw sweep event |
/sandbox/transfer/simulate | (Transfer) Simulate a transfer event |
/sandbox/transfer/refund/simulate | (Transfer) Simulate a refund event |
/sandbox/transfer/sweep/simulate | (Transfer) Simulate a transfer sweep event |
/sandbox/transfer/test_clock/create | (Transfer) Create a test clock for testing recurring transfers |
/sandbox/transfer/test_clock/advance | (Transfer) Advance the time on a test clock |
/sandbox/transfer/test_clock/get | (Transfer) Get details about a test clock |
/sandbox/transfer/test_clock/list | (Transfer) Get details about all test clocks |
/sandbox/income/fire_webhook | (Income) Fire a specific webhook |
/sandbox/cra/cashflow_updates/update | (Check) Simulate an update for Cash Flow Updates |
/sandbox/payment/simulate | (Payment Initiation) Simulate a payment |
/sandbox/transactions/create | (Transactions) Create custom transactions for Items |
/sandbox/public_token/create
Create a test Item
Use the /sandbox/public_token/create endpoint to create a valid public_token for an arbitrary institution ID, initial products, and test credentials. The created public_token maps to a new Sandbox Item. You can then call /item/public_token/exchange to exchange the public_token for an access_token and perform all API actions. /sandbox/public_token/create can also be used with the user_custom test username to generate a test account with custom data, or with Plaid's pre-populated Sandbox test accounts.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.institution_idinitial_productsinstitution_id supports. This array may not be empty.1 assets, auth, identity, income_verification, investments_auth, investments, liabilities, payment_initiation, signal, standing_orders, statements, transactions, transferoptionsnull.webhookurl override_usernameuser_good.user_good override_passwordpass_good.pass_good transactionsstart_datedate end_datedate statementsstart_datedate end_datedate income_verificationincome_verification is included in the initial_products array.income_source_typesbank and payroll. Currently you can only specify one of these options.bank, payrollbank_incomeincome_verification is included in the initial_products array and bank is specified in income_source_types.days_requesteduser_tokenconst publicTokenRequest: SandboxPublicTokenCreateRequest = {
institution_id: institutionID,
initial_products: initialProducts,
};
try {
const publicTokenResponse = await client.sandboxPublicTokenCreate(
publicTokenRequest,
);
const publicToken = publicTokenResponse.data.public_token;
// The generated public_token can now be exchanged
// for an access_token
const exchangeRequest: ItemPublicTokenExchangeRequest = {
public_token: publicToken,
};
const exchangeTokenResponse = await client.itemPublicTokenExchange(
exchangeRequest,
);
const accessToken = exchangeTokenResponse.data.access_token;
} catch (error) {
// handle error
}
Response fields
public_token/item/public_token/exchangerequest_id{
"public_token": "public-sandbox-b0e2c4ee-a763-4df5-bfe9-46a46bce993d",
"request_id": "Aim3b"
}/sandbox/processor_token/create
Create a test Item and processor token
Use the /sandbox/processor_token/create endpoint to create a valid processor_token for an arbitrary institution ID and test credentials. The created processor_token corresponds to a new Sandbox Item. You can then use this processor_token with the /processor/ API endpoints in Sandbox. You can also use /sandbox/processor_token/create with the user_custom test username to generate a test account with custom data.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.institution_idoptionsnull.override_usernameuser_good.user_good override_passwordpass_good.pass_good const request: SandboxProcessorTokenCreateRequest = {
institution_id: institutionID,
};
try {
const response = await plaidClient.sandboxProcessorTokenCreate(request);
const processorToken = response.data.processor_token;
} catch (error) {
// handle error
}
Response fields
processor_token/processor/ endpoints.request_id{
"processor_token": "processor-sandbox-b0e2c4ee-a763-4df5-bfe9-46a46bce993d",
"request_id": "Aim3b"
}/sandbox/item/reset_login
Force a Sandbox Item into an error state
/sandbox/item/reset_login/ forces an Item into an ITEM_LOGIN_REQUIRED state in order to simulate an Item whose login is no longer valid. This makes it easy to test Link's update mode flow in the Sandbox environment. After calling /sandbox/item/reset_login, You can then use Plaid Link update mode to restore the Item to a good state. An ITEM_LOGIN_REQUIRED webhook will also be fired after a call to this endpoint, if one is associated with the Item.
In the Sandbox, Items will transition to an ITEM_LOGIN_REQUIRED error state automatically after 30 days, even if this endpoint is not called.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_tokenconst request: SandboxItemResetLoginRequest = {
access_token: accessToken,
};
try {
const response = await plaidClient.sandboxItemResetLogin(request);
// create a public_token for the Item and use it to
// initialize Link in update mode.
const pt_request: itemPublicTokenCreateRequest = {
access_token: accessToken,
};
const pt_response = await plaidClient.itemCreatePublicToken(pt_request);
const publicToken = pt_response.public_token;
} catch (error) {
// handle error
}
Response fields
reset_logintrue if the call succeededrequest_id{
"reset_login": true,
"request_id": "m8MDnv9okwxFNBV"
}/sandbox/user/reset_login
Force item(s) for a Sandbox User into an error state
/sandbox/user/reset_login/ functions the same as /sandbox/item/reset_login, but will modify Items related to a User. This endpoint forces each Item into an ITEM_LOGIN_REQUIRED state in order to simulate an Item whose login is no longer valid. This makes it easy to test Link's update mode flow in the Sandbox environment. After calling /sandbox/user/reset_login, You can then use Plaid Link update mode to restore Items associated with the User to a good state. An ITEM_LOGIN_REQUIRED webhook will also be fired after a call to this endpoint, if one is associated with the Item.
In the Sandbox, Items will transition to an ITEM_LOGIN_REQUIRED error state automatically after 30 days, even if this endpoint is not called.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.user_tokenitem_idsitem_ids associated with the User to be reset. If empty or null, this field will default to resetting all Items associated with the User.const request: SandboxUserResetLoginRequest = {
user_token: 'user-environment-12345678-abcd-4bcd-abcd-1234567890ab',
item_ids: ['eVBnVMp7zdTJLkRNr33Rs6zr7KNJqBFL9DrE6']
};
try {
const response = await plaidClient.sandboxUserResetLogin(request);
} catch (error) {
// handle error
}
Response fields
request_id{
"reset_login": true,
"request_id": "n7XQnv8ozwyFPBC"
}/sandbox/item/fire_webhook
Fire a test webhook
The /sandbox/item/fire_webhook endpoint is used to test that code correctly handles webhooks. This endpoint can trigger the following webhooks:DEFAULT_UPDATE: Webhook to be fired for a given Sandbox Item simulating a default update event for the respective product as specified with the webhook_type in the request body. Valid Sandbox DEFAULT_UPDATE webhook types include: AUTH, IDENTITY, TRANSACTIONS, INVESTMENTS_TRANSACTIONS, LIABILITIES, HOLDINGS. If the Item does not support the product, a SANDBOX_PRODUCT_NOT_ENABLED error will result.NEW_ACCOUNTS_AVAILABLE: Fired to indicate that a new account is available on the Item and you can launch update mode to request access to it.SMS_MICRODEPOSITS_VERIFICATION: Fired when a given same day micro-deposit item is verified via SMS verification.LOGIN_REPAIRED: Fired when an Item recovers from the ITEM_LOGIN_REQUIRED without the user going through update mode in your app.PENDING_DISCONNECT: Fired when an Item will stop working in the near future (e.g. due to a planned bank migration) and must be sent through update mode to continue working.RECURRING_TRANSACTIONS_UPDATE: Recurring Transactions webhook to be fired for a given Sandbox Item. If the Item does not support Recurring Transactions, a SANDBOX_PRODUCT_NOT_ENABLED error will result.SYNC_UPDATES_AVAILABLE: Transactions webhook to be fired for a given Sandbox Item. If the Item does not support Transactions, a SANDBOX_PRODUCT_NOT_ENABLED error will result.PRODUCT_READY: Assets webhook to be fired when a given asset report has been successfully generated. If the Item does not support Assets, a SANDBOX_PRODUCT_NOT_ENABLED error will result.ERROR: Assets webhook to be fired when asset report generation has failed. If the Item does not support Assets, a SANDBOX_PRODUCT_NOT_ENABLED error will result.USER_PERMISSION_REVOKED: Indicates an end user has revoked the permission that they previously granted to access an Item. May not always fire upon revocation, as some institutions’ consent portals do not trigger this webhook. Upon receiving this webhook, it is recommended to delete any stored data from Plaid associated with the account or Item.USER_ACCOUNT_REVOKED: Fired when an end user has revoked access to their account on the Data Provider's portal. This webhook is currently sent only for PNC Items, but may be sent in the future for other financial institutions. Upon receiving this webhook, it is recommended to delete any stored data from Plaid associated with the account or Item.
Note that this endpoint is provided for developer ease-of-use and is not required for testing webhooks; webhooks will also fire in Sandbox under the same conditions that they would in Production (except for webhooks of type TRANSFER).
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_tokenwebhook_typeAUTH, HOLDINGS, INVESTMENTS_TRANSACTIONS, ITEM, LIABILITIES, TRANSACTIONS, ASSETSwebhook_codeDEFAULT_UPDATE, NEW_ACCOUNTS_AVAILABLE, SMS_MICRODEPOSITS_VERIFICATION, USER_PERMISSION_REVOKED, USER_ACCOUNT_REVOKED, PENDING_DISCONNECT, RECURRING_TRANSACTIONS_UPDATE, LOGIN_REPAIRED, SYNC_UPDATES_AVAILABLE, PRODUCT_READY, ERROR// Fire a DEFAULT_UPDATE webhook for an Item
const request: SandboxItemFireWebhookRequest = {
access_token: accessToken
webhook_code: 'DEFAULT_UPDATE'
};
try {
const response = await plaidClient.sandboxItemFireWebhook(request);
} catch (error) {
// handle error
}
Response fields
webhook_firedtrue if the test webhook_code was successfully fired.request_id{
"webhook_fired": true,
"request_id": "1vwmF5TBQwiqfwP"
}/sandbox/item/set_verification_status
Set verification status for Sandbox account
The /sandbox/item/set_verification_status endpoint can be used to change the verification status of an Item in in the Sandbox in order to simulate the Automated Micro-deposit flow.
For more information on testing Automated Micro-deposits in Sandbox, see Auth full coverage testing.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_tokenaccount_idaccount_id of the account whose verification status is to be modifiedverification_statusautomatically_verified, verification_expiredconst request: SandboxItemSetVerificationStatusRequest = {
access_token: accessToken,
account_id: accountID,
verification_status: 'automatically_verified',
};
try {
const response = await plaidClient.sandboxItemSetVerificationStatus(request);
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "1vwmF5TBQwiqfwP"
}/sandbox/transfer/fire_webhook
Manually fire a Transfer webhook
Use the /sandbox/transfer/fire_webhook endpoint to manually trigger a TRANSFER_EVENTS_UPDATE webhook in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.webhookurl const request: SandboxTransferFireWebhookRequest = {
webhook: 'https://www.example.com',
};
try {
const response = await plaidClient.sandboxTransferFireWebhook(request);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/simulate
Simulate a transfer event in Sandbox
Use the /sandbox/transfer/simulate endpoint to simulate a transfer event in the Sandbox environment. Note that while an event will be simulated and will appear when using endpoints such as /transfer/event/sync or /transfer/event/list, no transactions will actually take place and funds will not move between accounts, even within the Sandbox.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.transfer_idtest_clock_idvirtual_time on the provided test_clock.event_typeposted, settled, failed, funds_available, or returned.An error will be returned if the event type is incompatible with the current transfer status. Compatible status --> event type transitions include:
pending --> failedpending --> postedposted --> returnedposted --> settledsettled --> funds_available (only applicable to ACH debits.)failure_reason"failed" or "returned". Null value otherwise.failure_codeR01. A failure code will be provided if and only if the transfer status is returned. See ACH return codes for a full listing of ACH return codes and RTP/RfP error codes for RTP error codes.ach_return_codeR01. A return code will be provided if and only if the transfer status is returned. For a full listing of ACH return codes, see Transfer errors.descriptionwebhookTRANSFER_EVENTS_UPDATE webhook should be sent.url const request: SandboxTransferSimulateRequest = {
transfer_id,
event_type: 'posted',
failure_reason: failureReason,
};
try {
const response = await plaidClient.sandboxTransferSimulate(request);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/refund/simulate
Simulate a refund event in Sandbox
Use the /sandbox/transfer/refund/simulate endpoint to simulate a refund event in the Sandbox environment. Note that while an event will be simulated and will appear when using endpoints such as /transfer/event/sync or /transfer/event/list, no transactions will actually take place and funds will not move between accounts, even within the Sandbox.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.refund_idtest_clock_idvirtual_time on the provided test_clock.event_typerefund.posted, refund.settled, refund.failed, or refund.returned.An error will be returned if the event type is incompatible with the current refund status. Compatible status --> event type transitions include:
refund.pending --> refund.failedrefund.pending --> refund.postedrefund.posted --> refund.returnedrefund.posted --> refund.settledrefund.posted events can only be simulated if the refunded transfer has been transitioned to settled. This mimics the ordering of events in Production.failure_reason"failed" or "returned". Null value otherwise.failure_codeR01. A failure code will be provided if and only if the transfer status is returned. See ACH return codes for a full listing of ACH return codes and RTP/RfP error codes for RTP error codes.ach_return_codeR01. A return code will be provided if and only if the transfer status is returned. For a full listing of ACH return codes, see Transfer errors.descriptionwebhookTRANSFER_EVENTS_UPDATE webhook should be sent.url const request: SandboxTransferRefundSimulateRequest = {
refund_id: refundId,
event_type: 'refund.posted',
};
try {
const response = await plaidClient.sandboxTransferRefundSimulate(request);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/sweep/simulate
Simulate creating a sweep
Use the /sandbox/transfer/sweep/simulate endpoint to create a sweep and associated events in the Sandbox environment. Upon calling this endpoint, all transfers with a sweep status of swept will become swept_settled, all posted or pending transfers with a sweep status of unswept will become swept, and all returned transfers with a sweep status of swept will become return_swept.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.test_clock_idvirtual_time on the test_clock. If the date of virtual_time is on weekend or a federal holiday, the next available banking day is used.webhookTRANSFER_EVENTS_UPDATE webhook should be sent.url try {
const response = await plaidClient.sandboxTransferSweepSimulate({});
const sweep = response.data.sweep;
} catch (error) {
// handle error
}
Response fields
sweep/sandbox/transfer/sweep/simulate endpoint.
Can be null if there are no transfers to include in a sweep.idfunding_account_idledger_idcreateddate-time amountIf amount is not present, the sweep was net-settled to zero and outstanding debits and credits between the sweep account and Plaid are balanced.
iso_currency_codesettleddate expected_funds _available_datedate status"pending" - The sweep is currently pending
"posted" - The sweep has been posted
"settled" - The sweep has settled. This is the terminal state of a successful credit sweep.
"returned" - The sweep has been returned. This is the terminal state of a returned sweep. Returns of a sweep are extremely rare, since sweeps are money movement between your own bank account and your own Ledger.
"funds_available" - Funds from the sweep have been released from hold and applied to the ledger's available balance. (Only applicable to deposits.) This is the terminal state of a successful deposit sweep.
"failed" - The sweep has failed. This is the terminal state of a failed sweep.pending, posted, settled, funds_available, returned, failed, nulltrigger"manual" - The sweep is created manually by the customer
"incoming" - The sweep is created by incoming funds flow (e.g. Incoming Wire)
"balance_threshold" - The sweep is created by balance threshold setting
"automatic_aggregate" - The sweep is created by the Plaid automatic aggregation process. These funds did not pass through the Plaid Ledger balance.manual, incoming, balance_threshold, automatic_aggregatedescriptionnetwork_trace_idFor
ach or same-day-ach transfers, this is the ACH trace number.
For rtp transfers, this is the Transaction Identification number.
For wire transfers, this is the IMAD (Input Message Accountability Data) number.failure_reason"failed" or "returned". Null value otherwise.failure_codeR01. A failure code will be provided if and only if the sweep status is returned. See ACH return codes for a full listing of ACH return codes and RTP/RfP error codes for RTP error codes.descriptionrequest_id{
"sweep": {
"id": "d5394a4d-0b04-4a02-9f4a-7ca5c0f52f9d",
"funding_account_id": "8945fedc-e703-463d-86b1-dc0607b55460",
"created": "2020-08-06T17:27:15Z",
"amount": "12.34",
"iso_currency_code": "USD",
"settled": "2020-08-07",
"network_trace_id": null
},
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/ledger/deposit/simulate
Simulate a ledger deposit event in Sandbox
Use the /sandbox/transfer/ledger/deposit/simulate endpoint to simulate a ledger deposit event in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.sweep_idevent_typeposted, settled, failed, or returned.An error will be returned if the event type is incompatible with the current ledger sweep status. Compatible status --> event type transitions include:
sweep.pending --> sweep.postedsweep.pending --> sweep.failedsweep.posted --> sweep.settledsweep.posted --> sweep.returnedsweep.settled --> sweep.returnedsweep.posted, sweep.settled, sweep.returned, sweep.failedfailure_reason"failed" or "returned". Null value otherwise.failure_codeR01. A failure code will be provided if and only if the transfer status is returned. See ACH return codes for a full listing of ACH return codes and RTP/RfP error codes for RTP error codes.ach_return_codeR01. A return code will be provided if and only if the transfer status is returned. For a full listing of ACH return codes, see Transfer errors.descriptionconst request: SandboxTransferLedgerDepositSimulateRequest = {
sweep_id: 'f4ba7a287eae4d228d12331b68a9f35a',
event_type: 'sweep.posted',
};
try {
const response = await plaidClient.sandboxTransferLedgerDepositSimulate(
request,
);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/ledger/simulate_available
Simulate converting pending balance to available balance
Use the /sandbox/transfer/ledger/simulate_available endpoint to simulate converting pending balance to available balance for all originators in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.ledger_idoriginator_client_idtest_clock_idvirtual_timestamp on the test clock will be converted.webhookTRANSFER_EVENTS_UPDATE webhook should be sent.url try {
const response = await plaidClient.sandboxTransferLedgerSimulateAvailable({});
const available = response.data.balance.available;
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/ledger/withdraw/simulate
Simulate a ledger withdraw event in Sandbox
Use the /sandbox/transfer/ledger/withdraw/simulate endpoint to simulate a ledger withdraw event in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.sweep_idevent_typeposted, settled, failed, or returned.An error will be returned if the event type is incompatible with the current ledger sweep status. Compatible status --> event type transitions include:
sweep.pending --> sweep.postedsweep.pending --> sweep.failedsweep.posted --> sweep.settledsweep.posted --> sweep.returnedsweep.settled --> sweep.returnedsweep.posted, sweep.settled, sweep.returned, sweep.failedfailure_reason"failed" or "returned". Null value otherwise.failure_codeR01. A failure code will be provided if and only if the transfer status is returned. See ACH return codes for a full listing of ACH return codes and RTP/RfP error codes for RTP error codes.ach_return_codeR01. A return code will be provided if and only if the transfer status is returned. For a full listing of ACH return codes, see Transfer errors.descriptionconst request: SandboxTransferLedgerWithdrawSimulateRequest = {
sweep_id: 'f4ba7a287eae4d228d12331b68a9f35a',
event_type: 'sweep.posted',
};
try {
const response = await plaidClient.sandboxTransferLedgerWithdrawSimulate(
request,
);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/test_clock/create
Create a test clock
Use the /sandbox/transfer/test_clock/create endpoint to create a test_clock in the Sandbox environment.
A test clock object represents an independent timeline and has a virtual_time field indicating the current timestamp of the timeline. Test clocks are used for testing recurring transfers in Sandbox.
A test clock can be associated with up to 5 recurring transfers.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.virtual_time2006-01-02T15:04:05Z.date-time const request: SandboxTransferTestClockCreateRequest = {
virtual_time: '2006-01-02T15:04:05Z',
};
try {
const response = await plaidClient.sandboxTransferTestClockCreate(request);
const test_clock = response.data.test_clock;
} catch (error) {
// handle error
}
Response fields
test_clocktest_clock_idtest_clock_id was included in the /transfer/recurring/create request. For more details, see Simulating recurring transfers.virtual_time2006-01-02T15:04:05Z.date-time request_id{
"test_clock": {
"test_clock_id": "b33a6eda-5e97-5d64-244a-a9274110151c",
"virtual_time": "2006-01-02T15:04:05Z"
},
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/test_clock/advance
Advance a test clock
Use the /sandbox/transfer/test_clock/advance endpoint to advance a test_clock in the Sandbox environment.
A test clock object represents an independent timeline and has a virtual_time field indicating the current timestamp of the timeline. A test clock can be advanced by incrementing virtual_time, but may never go back to a lower virtual_time.
If a test clock is advanced, we will simulate the changes that ought to occur during the time that elapsed.
For example, a client creates a weekly recurring transfer with a test clock set at t. When the client advances the test clock by setting virtual_time = t + 15 days, 2 new originations should be created, along with the webhook events.
The advancement of the test clock from its current virtual_time should be limited such that there are no more than 20 originations resulting from the advance operation on each recurring_transfer associated with the test_clock.
For example, if the recurring transfer associated with this test clock originates once every 4 weeks, you can advance the virtual_time up to 80 weeks on each API call.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.test_clock_idtest_clock_id was included in the /transfer/recurring/create request. For more details, see Simulating recurring transfers.new_virtual_time2006-01-02T15:04:05Z.date-time const request: SandboxTransferTestClockAdvanceRequest = {
test_clock_id: 'b33a6eda-5e97-5d64-244a-a9274110151c',
new_virtual_time: '2006-01-02T15:04:05Z',
};
try {
const response = await plaidClient.sandboxTransferTestClockAdvance(request);
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/test_clock/get
Get a test clock
Use the /sandbox/transfer/test_clock/get endpoint to get a test_clock in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.test_clock_idtest_clock_id was included in the /transfer/recurring/create request. For more details, see Simulating recurring transfers.const request: SandboxTransferTestClockGetRequest = {
test_clock_id: 'b33a6eda-5e97-5d64-244a-a9274110151c',
};
try {
const response = await plaidClient.sandboxTransferTestClockGet(request);
const test_clock = response.data.test_clock;
} catch (error) {
// handle error
}
Response fields
test_clocktest_clock_idtest_clock_id was included in the /transfer/recurring/create request. For more details, see Simulating recurring transfers.virtual_time2006-01-02T15:04:05Z.date-time request_id{
"test_clock": {
"test_clock_id": "b33a6eda-5e97-5d64-244a-a9274110151c",
"virtual_time": "2006-01-02T15:04:05Z"
},
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/transfer/test_clock/list
List test clocks
Use the /sandbox/transfer/test_clock/list endpoint to see a list of all your test clocks in the Sandbox environment, by ascending virtual_time. Results are paginated; use the count and offset query parameters to retrieve the desired test clocks.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.start_virtual_time2019-12-06T22:35:49Z)date-time end_virtual_time2019-12-06T22:35:49Z)date-time count1 25 25 offset0 0 const request: SandboxTransferTestClockListRequest = {
count: 2,
};
try {
const response = await plaidClient.sandboxTransferTestClockList(request);
const test_clocks = response.data.test_clocks;
} catch (error) {
// handle error
}
Response fields
test_clockstest_clock_idtest_clock_id was included in the /transfer/recurring/create request. For more details, see Simulating recurring transfers.virtual_time2006-01-02T15:04:05Z.date-time request_id{
"test_clocks": [
{
"test_clock_id": "b33a6eda-5e97-5d64-244a-a9274110151c",
"virtual_time": "2006-01-02T15:04:05Z"
},
{
"test_clock_id": "a33a6eda-5e97-5d64-244a-a9274110152d",
"virtual_time": "2006-02-02T15:04:05Z"
}
],
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/income/fire_webhook
Manually fire an Income webhook
Use the /sandbox/income/fire_webhook endpoint to manually trigger a Payroll or Document Income webhook in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.item_iduser_iduser_id of the User associated with this webhook, warning, or error.webhookurl verification_statusVERIFICATION_STATUS_PROCESSING_COMPLETE: The income verification status processing has completed. If the user uploaded multiple documents, this webhook will fire when all documents have finished processing. Call the /income/verification/paystubs/get endpoint and check the document metadata to see which documents were successfully parsed.VERIFICATION_STATUS_PROCESSING_FAILED: A failure occurred when attempting to process the verification documentation.VERIFICATION_STATUS_PENDING_APPROVAL: (deprecated) The income verification has been sent to the user for review.VERIFICATION_STATUS_PROCESSING_COMPLETE, VERIFICATION_STATUS_PROCESSING_FAILED, VERIFICATION_STATUS_PENDING_APPROVALwebhook_codeINCOME_VERIFICATION, INCOME_VERIFICATION_RISK_SIGNALSconst request: SandboxIncomeFireWebhookRequest = {
item_id: 'Rn3637v1adCNj5Dl1LG6idQBzqBLwRcRZLbgM',
webhook: 'https://webhook.com/',
verification_status: 'VERIFICATION_STATUS_PROCESSING_COMPLETE',
};
try {
const response = await plaidClient.sandboxIncomeFireWebhook(request);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/cra/cashflow_updates/update
Trigger an update for Cash Flow Updates
Use the /sandbox/cra/cashflow_updates/update endpoint to manually trigger an update for Cash Flow Updates (Monitoring) in the Sandbox environment.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.user_tokenwebhook_codesLARGE_DEPOSIT_DETECTED, LOW_BALANCE_DETECTED, NEW_LOAN_PAYMENT_DETECTED, NSF_OVERDRAFT_DETECTEDconst request: SandboxCraCashflowUpdatesUpdateRequest = {
user_token: 'user-environment-12345678-abcd-4bcd-abcd-1234567890ab',
webhook_codes: ['LARGE_DEPOSIT_DETECTED', 'LOW_BALANCE_DETECTED'],
};
try {
const response = await plaidClient.sandbox_cra_cashflow_updates_update(request);
// empty response upon success
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "mdqfuVxeoza6mhu"
}/sandbox/payment/simulate
Simulate a payment event in Sandbox
Use the /sandbox/payment/simulate endpoint to simulate various payment events in the Sandbox environment. This endpoint will trigger the corresponding payment status webhook.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.payment_idwebhookstatusValid statuses include:
PAYMENT_STATUS_INITIATEDPAYMENT_STATUS_INSUFFICIENT_FUNDSPAYMENT_STATUS_FAILEDPAYMENT_STATUS_EXECUTEDPAYMENT_STATUS_SETTLEDPAYMENT_STATUS_CANCELLEDPAYMENT_STATUS_REJECTED
const request: SandboxPaymentSimulateRequest = {
payment_id: 'payment-id-sandbox-feca8a7a-5591-4aef-9297-f3062bb735d3',
status: "PAYMENT_STATUS_INITIATED"
};
try {
const response = await plaidClient.sandbox_payment_simulate(request);
} catch (error) {
// handle error
}
Response fields
request_idold_statusCore lifecycle statuses:
PAYMENT_STATUS_INPUT_NEEDED: Transitional. The payment is awaiting user input to continue processing. It may re-enter this state if additional input is required.PAYMENT_STATUS_AUTHORISING: Transitional. The payment is being authorised by the financial institution. It will automatically move on once authorisation completes.PAYMENT_STATUS_INITIATED: Transitional. The payment has been authorised and accepted by the financial institution and is now in transit. A payment should be considered complete once it reaches the PAYMENT_STATUS_EXECUTED state or the funds settle in the recipient account.PAYMENT_STATUS_EXECUTED: Terminal. The funds have left the payer’s account and the payment is en route to settlement. Support is more common in the UK than in the EU; where unsupported, a successful payment remains in PAYMENT_STATUS_INITIATED before settling. When using Plaid Virtual Accounts, PAYMENT_STATUS_EXECUTED is not terminal—the payment will continue to PAYMENT_STATUS_SETTLED once funds are available.PAYMENT_STATUS_SETTLED: Terminal. The funds are available in the recipient’s account. Only available to customers using Plaid Virtual Accounts.Failure statuses:
PAYMENT_STATUS_INSUFFICIENT_FUNDS: Terminal. The payment failed due to insufficient funds. No further retries will succeed until the payer’s balance is replenished.PAYMENT_STATUS_FAILED: Terminal (retryable). The payment could not be initiated due to a system error or outage. Retry once the root cause is resolved.PAYMENT_STATUS_BLOCKED: Terminal (retryable). The payment was blocked by Plaid (e.g., flagged as risky). Resolve any compliance or risk issues and retry.PAYMENT_STATUS_REJECTED: Terminal. The payment was rejected by the financial institution. No automatic retry is possible.PAYMENT_STATUS_CANCELLED: Terminal. The end user cancelled the payment during authorisation.Standing-order statuses:
PAYMENT_STATUS_ESTABLISHED: Terminal. A recurring/standing order has been successfully created.Deprecated (to be removed in a future release):
PAYMENT_STATUS_UNKNOWN: The payment status is unknown.PAYMENT_STATUS_PROCESSING: The payment is currently being processed.PAYMENT_STATUS_COMPLETED: Indicates that the standing order has been successfully established.PAYMENT_STATUS_INPUT_NEEDED, PAYMENT_STATUS_PROCESSING, PAYMENT_STATUS_INITIATED, PAYMENT_STATUS_COMPLETED, PAYMENT_STATUS_INSUFFICIENT_FUNDS, PAYMENT_STATUS_FAILED, PAYMENT_STATUS_BLOCKED, PAYMENT_STATUS_UNKNOWN, PAYMENT_STATUS_EXECUTED, PAYMENT_STATUS_SETTLED, PAYMENT_STATUS_AUTHORISING, PAYMENT_STATUS_CANCELLED, PAYMENT_STATUS_ESTABLISHED, PAYMENT_STATUS_REJECTEDnew_statusCore lifecycle statuses:
PAYMENT_STATUS_INPUT_NEEDED: Transitional. The payment is awaiting user input to continue processing. It may re-enter this state if additional input is required.PAYMENT_STATUS_AUTHORISING: Transitional. The payment is being authorised by the financial institution. It will automatically move on once authorisation completes.PAYMENT_STATUS_INITIATED: Transitional. The payment has been authorised and accepted by the financial institution and is now in transit. A payment should be considered complete once it reaches the PAYMENT_STATUS_EXECUTED state or the funds settle in the recipient account.PAYMENT_STATUS_EXECUTED: Terminal. The funds have left the payer’s account and the payment is en route to settlement. Support is more common in the UK than in the EU; where unsupported, a successful payment remains in PAYMENT_STATUS_INITIATED before settling. When using Plaid Virtual Accounts, PAYMENT_STATUS_EXECUTED is not terminal—the payment will continue to PAYMENT_STATUS_SETTLED once funds are available.PAYMENT_STATUS_SETTLED: Terminal. The funds are available in the recipient’s account. Only available to customers using Plaid Virtual Accounts.Failure statuses:
PAYMENT_STATUS_INSUFFICIENT_FUNDS: Terminal. The payment failed due to insufficient funds. No further retries will succeed until the payer’s balance is replenished.PAYMENT_STATUS_FAILED: Terminal (retryable). The payment could not be initiated due to a system error or outage. Retry once the root cause is resolved.PAYMENT_STATUS_BLOCKED: Terminal (retryable). The payment was blocked by Plaid (e.g., flagged as risky). Resolve any compliance or risk issues and retry.PAYMENT_STATUS_REJECTED: Terminal. The payment was rejected by the financial institution. No automatic retry is possible.PAYMENT_STATUS_CANCELLED: Terminal. The end user cancelled the payment during authorisation.Standing-order statuses:
PAYMENT_STATUS_ESTABLISHED: Terminal. A recurring/standing order has been successfully created.Deprecated (to be removed in a future release):
PAYMENT_STATUS_UNKNOWN: The payment status is unknown.PAYMENT_STATUS_PROCESSING: The payment is currently being processed.PAYMENT_STATUS_COMPLETED: Indicates that the standing order has been successfully established.PAYMENT_STATUS_INPUT_NEEDED, PAYMENT_STATUS_PROCESSING, PAYMENT_STATUS_INITIATED, PAYMENT_STATUS_COMPLETED, PAYMENT_STATUS_INSUFFICIENT_FUNDS, PAYMENT_STATUS_FAILED, PAYMENT_STATUS_BLOCKED, PAYMENT_STATUS_UNKNOWN, PAYMENT_STATUS_EXECUTED, PAYMENT_STATUS_SETTLED, PAYMENT_STATUS_AUTHORISING, PAYMENT_STATUS_CANCELLED, PAYMENT_STATUS_ESTABLISHED, PAYMENT_STATUS_REJECTED{
"request_id": "m8MDnv9okwxFNBV",
"old_status": "PAYMENT_STATUS_INPUT_NEEDED",
"new_status": "PAYMENT_STATUS_INITIATED"
}/sandbox/transactions/create
Create sandbox transactions
Use the /sandbox/transactions/create endpoint to create new transactions for an existing Item. This endpoint can be used to add up to 10 transactions to any Item at a time.
This endpoint can only be used with Items that were created in the Sandbox environment using the user_transactions_dynamic test user. You can use this to add transactions to test the /transactions/get and /transactions/sync endpoints.
Request fields
client_idclient_id. The client_id is required and may be provided either in the PLAID-CLIENT-ID header or as part of a request body.secretsecret. The secret is required and may be provided either in the PLAID-SECRET header or as part of a request body.access_tokentransactionsdate_transacteddate date_posteddate amountdouble descriptioniso_currency_codeconst request: SandboxTransactionsCreateRequest = {
access_token: accessToken,
transactions: [
{
amount: 100.50,
date_posted: '2025-06-08',
date_transacted: '2025-06-08',
description: 'Tim Hortons'
},
{
amount: -25.75,
date_posted: '2025-06-08',
date_transacted: '2025-06-08',
description: 'BestBuy',
iso_currency_code: 'CAD'
}
]
};
try {
const response = await plaidClient.sandbox_transactions_create(request);
} catch (error) {
// handle error
}
Response fields
request_id{
"request_id": "m8MDnv9okwxFNBV"
}