Add Customer External Bank Accounts
How do I connect a customer's bank account using Plaid?
Overview
Connect customer bank accounts to the Cybrid Platform using one of two Plaid-based approaches:
- Option 1: Plaid Link (Cybrid) — Cybrid generates a Plaid Link token; you drive the Plaid Link SDK in your application. Best for the typical embedded experience with no Plaid account of your own.
- Option 2: Plaid Processor Token (Partner) — You own the Plaid account and generate a processor token in your Plaid integration, then submit it to Cybrid. Best when you already have a Plaid integration and want full control over the Plaid Link experience.
For a high-level comparison, see Plaid Integration.
Prerequisites
- An active Cybrid account and API credentials.
- A
customer_guidfor the user who will link their bank account. See Create a Customer. - For Option 1: a
redirect_uri(web) orandroid_package_name(Android) registered with Cybrid. - For Option 2: a Plaid account with the ability to generate processor tokens.
EnvironmentsExamples use the sandbox base URL
https://bank.sandbox.cybrid.app. For production, usehttps://bank.production.cybrid.app.
Option 1: Plaid Link (Cybrid)
Cybrid generates the Plaid Link token. You initialize Plaid Link in your application and submit
the resulting public_token back to Cybrid to create the external bank account.
Review the official Plaid Link documentation for up-to-date platform-specific details (Web, iOS, Android, or React Native).
Step 1: Generate a Plaid Link token
Create a workflow with type: plaid and
kind: link_token_create. Cybrid asynchronously requests a plaid_link_token from Plaid. Poll
the workflow endpoint until the token is available.
Workflow notes
- The
customer_guidis the customer who will link their bank account.- All redirect URIs must be registered with Cybrid.
POST /api/workflows
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"type": "plaid",
"kind": "link_token_create",
"language": "en",
"link_customization_name": "default",
"customer_guid": "customer_guid",
"redirect_uri": "https://yourapp.com/api/plaid-redirect-uri"
}{
"guid": "workflow_guid",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"type": "plaid",
"state": "storing",
"failure_code": null,
"created_at": "2026-01-01T12:00:00.000Z",
"updated_at": "2026-01-01T12:00:00.000Z"
}Poll GET /api/workflows/{workflow_guid} until state is completed and plaid_link_token is
populated:
{
"guid": "workflow_guid",
"bank_guid": "bank_guid",
"customer_guid": "customer_guid",
"type": "plaid",
"state": "completed",
"failure_code": null,
"plaid_link_token": "plaid_link_token",
"created_at": "2026-01-01T12:00:00.000Z",
"updated_at": "2026-01-01T12:00:05.000Z"
}Workflow states
| State | Description |
|---|---|
storing | The Platform is storing the workflow details in the private store. |
completed | The Platform has created the workflow and generated the link token. |
failed | The workflow was not completed successfully (check failure_code for details). |
OAuth and redirect URIs
Many financial institutions use an OAuth flow, which redirects the customer to their bank's portal for authentication. Register your application's redirect URIs with Cybrid for each environment (sandbox and production). Contact Cybrid support to register your URIs.
For more information, see Plaid's documentation on OAuth redirect URIs.
Sandbox redirect URIsSandbox only supports HTTPS redirect URIs. Separate registrations are required for sandbox and production environments.
Android apps
For Android applications, register your app's package name (e.g., com.yourcompany.yourapp) with
Cybrid in addition to a redirect URI. Use the android_package_name field when creating the Plaid
workflow:
POST /api/workflows
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"type": "plaid",
"kind": "link_token_create",
"language": "en",
"link_customization_name": "default",
"customer_guid": "customer_guid",
"redirect_uri": "https://yourapp.com/api/plaid-redirect-uri",
"android_package_name": "com.yourcompany.yourapp"
}Step 2: Initialize Plaid Link SDK
Use the generated plaid_link_token to initialize the Plaid Link SDK in your client application.
The handler below includes callbacks for success, exit, and other events.
const handler = Plaid.create({
token: 'GENERATED_LINK_TOKEN', // The plaid_link_token from Step 1
onSuccess: (public_token, metadata) => {
// A Plaid public_token and account metadata are returned
// Use these values to create an external bank account in Step 3
// https://plaid.com/docs/link/web/#onsuccess
},
onLoad: () => {},
onExit: (err, metadata) => {
// Handle the case where the user exits the flow
// https://plaid.com/docs/link/web/#onexit
},
onEvent: (eventName, metadata) => {
// Optionally subscribe to events during the Plaid flow
// https://plaid.com/docs/link/web/#onevent
},
});
Callback loggingImplement clear logging for each callback in your application.
Sandbox environmentIn the Cybrid Sandbox, the generated
plaid_link_tokenautomatically initializes the Plaid Link SDK in its sandbox mode, so you can test without using real personal information.
Sandbox requires a matching Persona nameMatch the customer's Persona-verified name to Plaid's default sandbox identity (
Alberta Charleson) before linking the Plaid account. Without a name match, the downstream bank account identity verification does not auto-pass and fails into Persona document submission. See Verify an Individual Customer for the exact values to enter.
Handling callbacks
onSuccess
onSuccessFires when the customer successfully links an account. Returns a public_token and a metadata
object containing the account id. You use both values in the next step.
One account per workflowA customer can only link one external bank account per workflow. To link multiple accounts, create a unique workflow for each.
onExit
onExitFires when the customer leaves the flow without linking an account, with optional err and
metadata arguments. To diagnose drop-off causes, log only scrubbed or redacted details or
non-sensitive fields such as request IDs, metadata.status, and high-level error codes or
messages. Do not persist raw metadata or account/institution details in application logs.
Empty exit metadataWhen a returning customer exits during Plaid's SMS verification step — before selecting an institution or entering credentials —
metadata.institutionisnullandmetadata.accountsis[].metadata.statusmay also return""instead of a step name likechoose_device. This is a known Plaid edge case where exit metadata cannot be populated from cached state.
Share error details with CybridWhen troubleshooting SDK issues, capture and share callback error details —
err, request IDs,metadata.status, and high-level error codes — with Cybrid support. These details help diagnose integration issues faster.
Step 3: Create the external bank account
With the public_token and account id (inside the accounts array of metadata) from the
onSuccess callback, call
POST /api/external_bank_accounts
with the Plaid-specific parameters.
POST /api/external_bank_accounts
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"name": "Customer Checking Account",
"account_kind": "plaid",
"customer_guid": "customer_guid",
"asset": "USD",
"plaid_public_token": "plaid_public_token",
"plaid_account_id": "plaid_account_id"
}{
"guid": "external_bank_account_guid",
"name": "Customer Checking Account",
"account_kind": "plaid",
"customer_guid": "customer_guid",
"asset": "USD",
"state": "storing",
"created_at": "2026-01-01T16:05:40.757Z"
}For a detailed walkthrough, see the recipe Adding a Customer's Verified External Bank Account.
Option 2: Plaid Processor Token (Partner)
If you have your own Plaid account, generate a Plaid Processor Token in your Plaid integration and
submit it to Cybrid. See
Plaid's processor token documentation
for details on generating tokens; use modern_treasury as the processor value.
Submit the token to Cybrid via POST /api/external_bank_accounts with
account_kind: plaid_processor_token:
POST /api/external_bank_accounts
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
{
"name": "Customer Checking Account",
"account_kind": "plaid_processor_token",
"customer_guid": "customer_guid",
"asset": "USD",
"plaid_processor_token": "processor-production-xxxxx-xxxxx",
"plaid_institution_id": "ins_123456",
"plaid_account_mask": "0000",
"plaid_account_name": "Plaid Checking"
}{
"guid": "external_bank_account_guid",
"name": "Customer Checking Account",
"account_kind": "plaid_processor_token",
"customer_guid": "customer_guid",
"asset": "USD",
"plaid_institution_id": "ins_123456",
"plaid_account_mask": "0000",
"plaid_account_name": "Plaid Checking",
"state": "storing",
"created_at": "2026-01-01T16:05:40.757Z"
}Payment rail routing
ACH vs. wire routingWhen a bank account is linked via Plaid, the ABA routing number is captured and stored. When initiating a transfer, specify the
payment_railparameter (achorwire) to process the payment using the appropriate routing. Some US banks have different routing numbers for ACH versus wire transactions. If wire transfers fail due to routing issues with a Plaid-linked account, use the counterparty external bank accounts method to explicitly specify routing details for the intended payment rail.
Refresh expired connections
Plaid bank connections expire periodically and require the customer to re-authenticate. When this
happens, the external bank account's state transitions to refresh_required. To restore the
connection, follow the steps in
Refresh External Bank Accounts.
Next steps
Updated 7 days ago
