Plaid Integration

This guide explains how to integrate Plaid through Lynx so your users can securely link external bank accounts and you can use those linked accounts for verified funding workflows.

Plaid

Plaid is the third-party provider that powers the bank-linking experience.

Plaid is the service that:

  • presents the institution selection flow
  • handles the bank authentication experience
  • lets the user choose which account to link

Lynx integrates with Plaid on your behalf and provides an abstraction layer so you can work through Lynx’s integration contract instead of implementing Plaid directly end to end.

What this integration does

Lynx provides a wrapper around Plaid that lets your application:

  1. Launch a Plaid Link flow from your UI
  2. Let your user authenticate with their financial institution
  3. Return the selected account information to your application
  4. Link that account to the member in Lynx using a verified account-linking API

Once the account is linked, Lynx maintains the Plaid token required to securely support future member contribution flows.


Terminology

This guide uses the following terms throughout the Plaid + Lynx integration flow.

Member

The member is the end user in your application who is linking an external bank account.

This is the person who:

  • starts the Plaid linking flow from your UI
  • authenticates with their bank
  • selects the external account they want to connect

In Lynx APIs and payloads, this user is identified by the clientMemberId.

Link token

A link token is a short-lived token generated by Lynx and used to start the Plaid Link session.

Your application obtains this token by calling the Lynx Get Link Token endpoint, then passes it into Lynx.init(...) as the token field. Without a valid link token, the Plaid window cannot be launched.

Example:

token: 'link-sandbox-20236f21-6e8d-4565-97c7-c7a8db351005'
https://yourapp.com/plaid/callback

partnerAccessToken

The partnerAccessToken is the Lynx field name used when sending the callback token to the Link External Account Verified endpoint.

In the example integration flow, this value comes from the callback’s public_token. Even though the callback parameter is named public_token, when you send it to Lynx you store it in the partnerAccessToken field.

partnerAccountId

The partnerAccountId is the Lynx field name for the external account identifier selected by the user during the Plaid flow.

In the example provided, this value comes from:

metadata.account_id

You pass it to Lynx when calling Link External Account Verified so Lynx knows exactly which external bank account was chosen by the member.

Redirect URL

The redirect URL is the page on your website that Plaid sends the user back to after they leave your site to authenticate with their bank.

This is important for institutions that use an OAuth or redirect-based authentication flow. In those cases:

  1. the user starts on your site
  2. Plaid sends them to their bank
  3. the bank returns them to your redirect URL
  4. the Lynx/Plaid flow resumes from that page

This URL must be:

  • registered with Lynx ahead of time
  • passed when calling Get Link Token
  • available in your application so the integration can resume correctly after the redirect

A simple example might be:

https://yourapp.com/plaid/callback

High-level integration flow

At a high level, the integration works like this:

  1. Register your redirect URL with Lynx
  2. Generate a Lynx/Plaid link token
  3. Load the LynxPlaid.js script in your frontend
  4. Initialize the Plaid flow from your application
  5. Let the user select and authorize their bank account
  6. Receive the account details in your callback
  7. Send those details to Lynx to verify and link the external account

Prerequisites

Before implementing the integration, make sure you have the following:

  • A Lynx environment and API credentials
  • A valid redirect URL that will be registered with Lynx
  • A frontend page that will host the Plaid Link experience
  • Access to the Lynx API endpoints for:
    • Get Link Token
    • Link External Account Verified

Important: The page URL where you initialize the Plaid script must be registered with Lynx, or the flow will not work correctly.


Step 1: Register your redirect URL with Lynx

Before your application can launch the Plaid flow, your redirect URL must be registered with Lynx.

To register it, contact your Lynx Customer Success representative.

Why this matters

Plaid may redirect the user away from your site during authentication, depending on the institution and flow. Lynx uses the registered redirect URL to ensure the user is safely returned to your application and the integration can resume successfully.


Step 2: Install the Lynx Plaid script

Include the Lynx Plaid script on the page where you want to launch the account-linking flow:

<script src="https://path/to/LynxPlaid.js"></script>

The script source can be found below.

Important

The page loading this script must be hosted at a URL that has been registered with Lynx.


Step 3: Generate a link token

Call the Lynx Get Link Token endpoint to generate the token required to initialize the Plaid Link modal.

When calling this endpoint, include the same redirect URL you registered with Lynx.

Endpoint

Purpose

The response includes a link token that your frontend will pass into Lynx.init(...).

Notes

  • Treat the link token as short-lived and generate it when needed
  • The token should be generated for the specific member who is linking an account
  • The redirect URL supplied here must match the one registered with Lynx

Step 4: Initialize the Plaid flow

After you generate a link token, initialize Lynx Plaid from your frontend.

Example

Lynx.init({
  clientMemberId: '12345678',
  token: 'link-sandbox-20236f21-6e8d-4565-97c7-c7a8db351005',
  callback: (public_token, metadata) => {
    const account = {
      data: {
        memberBankAccount: {
          partnerAccessToken: public_token,
          partnerAccountId: metadata.account_id,
          name: `${metadata.institution.name} - ${metadata.account.name}`,
          type: metadata.account.subtype
        }
      }
    };

    console.log(account);
  }
});

Lynx.init configuration

Lynx.init() accepts a single configuration object.

Fields

clientMemberId

The Lynx member ID for the user linking the account.

clientMemberId: '12345678'

token

The link token returned by the Lynx Get Link Token API.

token: 'link-sandbox-...'

callback

A function that runs after the user successfully links an account.

It receives:

  • public_token: the value you should pass to Lynx as partnerAccessToken
  • metadata: an object containing account and institution details, including the value you should pass as partnerAccountId
callback: (public_token, metadata) => {
  // build request payload for Link External Account Verified
}

Step 5: User completes the Plaid flow

When Lynx.init(...) is called, Lynx opens the Plaid Link experience for the user.

The user then:

  1. Selects their financial institution
  2. Authenticates with that institution
  3. Chooses the external bank account they want to link

Depending on the institution, the user may be temporarily redirected to the bank’s site and then returned to your registered redirect URL.


Step 6: Handle the callback response

After the user successfully completes the flow, your callback receives the token and metadata needed to link the account through Lynx.

Expected callback values

  • public_token → map this to partnerAccessToken
  • metadata.account_id → map this to partnerAccountId

You can also use metadata to create a human-readable account name for your UI or payload.

Example payload construction

callback: (public_token, metadata) => {
  const payload = {
    data: {
      memberBankAccount: {
        partnerAccessToken: public_token,
        partnerAccountId: metadata.account_id,
        name: `${metadata.institution.name} - ${metadata.account.name}`,
        type: metadata.account.subtype
      }
    }
  };

  // Send payload to your backend or directly to Lynx, depending on your architecture
  console.log(payload);
}

Step 7: Link the verified external account in Lynx

Once you have partnerAccessToken and partnerAccountId, call the Lynx Link External Account Verified endpoint to finalize the link.

Endpoint

Required values

This API amongst other parameters requires:

  • partnerAccessToken
  • partnerAccountId
  • name (A description of the account e.g. John's Checking Account)

You must also include any other required fields expected by the endpoint. Please consult the endpoint for more details.

Outcome

After this call succeeds, the user’s external bank account is linked in Lynx and can be used in supported contribution workflows.


Recommended implementation pattern

For most integrations, the best pattern is:

Frontend

  • Load LynxPlaid.js
  • Request a link token from your backend
  • Call Lynx.init(...)
  • Receive the callback values from Lynx/Plaid
  • Construct callback-derived account payload for Link External Account Verified and send to backend

Backend

  • Call Lynx Get Link Token
  • Return the link token to the frontend
  • Receive the callback-derived account payload from the frontend
  • Call Link External Account Verified
  • Persist any application-specific status needed for your UX

This keeps Lynx API interaction centralized and easier to secure and monitor.


End-to-end example

Below is a simplified example showing a typical sequence.

1. Your backend requests a link token from Lynx

Backend calls:

  • Get Link Token

Backend receives:

{
  "token": "link-sandbox-20236f21-6e8d-4565-97c7-c7a8db351005"
}

2. Your frontend initializes the flow

Lynx.init({
  clientMemberId: '12345678',
  token: 'link-sandbox-20236f21-6e8d-4565-97c7-c7a8db351005',
  callback: async (public_token, metadata) => {
    const payload = {
      data: {
        member: {
          clientMemberId: '12345678'
        },
        clientOrg: {
          name: 'Health_Plan_ABC'
        },
        memberBankAccount: {
          partnerAccessToken: public_token,
          partnerAccountId: metadata.account_id,
          name: `${metadata.institution.name} - ${metadata.account.name}`,
          type: metadata.account.subtype
        }
      }
    };

    await fetch('/api/link-external-account', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });
  }
});

3. Your backend finalizes the account link

Your backend receives the payload and calls:

  • Link External Account Verified

If successful, the account is now linked in Lynx.


Error handling recommendations

Your implementation should account for the following scenarios:

User exits before completing the flow

The user may close the Plaid modal or abandon authentication before finishing.

Recommendation:
Show a non-blocking message such as:
“Bank account linking was canceled. You can try again at any time.”

Redirect flow interruption

Some institutions require redirects. If the redirect URL is not registered correctly, the user may fail to return to the application in a usable state.

Recommendation:
Confirm that:

  • the redirect URL is registered with Lynx
  • the same redirect URL is passed when generating the link token
  • the initialization page URL is also approved/registered as required

Missing account metadata

In rare cases, your application may not receive expected account details.

Recommendation:
Validate that the callback includes:

  • public_token
  • metadata.account_id

If either is missing, do not call Link External Account Verified.

API failures when linking the account

The final Lynx API call may fail due to validation issues or missing fields.

Recommendation:
Log the request correlation details and surface a user-friendly error such as:
“We couldn’t link that account right now. Please try again or contact support.”


Security and implementation notes

  • Do not persist sensitive tokens in insecure client-side storage unless explicitly required by your architecture
  • Prefer sending callback results to your backend and completing the final Lynx API call server-side
  • Validate all required fields before calling Lynx
  • Use environment-specific credentials and tokens
  • Test redirect flows carefully, especially for institutions that require OAuth-style handoff

Common pitfalls

Below are the most common issues teams run into when implementing the Lynx + Plaid integration.

1. Redirect URL is not registered with Lynx

If your redirect URL has not been registered with Lynx, the Plaid flow may fail when the user is sent back from their financial institution.

Why it happens:
The integration requires you to register the redirect URL with Lynx before using it.

How to avoid it:

  • Register the redirect URL with Lynx before development or testing
  • Confirm the exact URL value with your Lynx Customer Success contact
  • Make sure the same redirect URL is used consistently in your implementation

2. The redirect URL used in token generation does not match the registered URL

A common mistake is registering one redirect URL with Lynx but passing a different one when calling Get Link Token.

Why it happens:
The markdown states that the redirect URL passed to Get Link Token should be the same redirect URL registered in step 1.

How to avoid it:

  • Store the redirect URL in configuration so the same value is reused everywhere
  • Avoid manually retyping the URL across environments
  • Double-check sandbox, staging, and production values separately

3. Initializing LynxPlaid.js from an unapproved page

The page URL where the script is initialized must be registered with Lynx. If it is not, the flow may not work.

Why it happens:
Teams often focus on the redirect URL but forget that the page hosting the script must also be approved.

How to avoid it:

  • Confirm the launch page URL with Lynx
  • Test from the exact page your users will use in production
  • Do not assume that only the callback page matters

4. Forgetting to map public_token to partnerAccessToken

The callback example returns a public_token, but the payload sent to Lynx uses the field name partnerAccessToken. That naming difference can confuse implementers.

Why it happens:
Different names are used for the callback input and the Lynx API field.

How to avoid it:
Map it explicitly in your code:

partnerAccessToken: public_token

Document this mapping internally so engineers and AI tools do not treat them as separate values.


5. Forgetting to map metadata.account_id to partnerAccountId

The callback returns account metadata, but Lynx expects the selected account identifier in the partnerAccountId field. The original example maps this from metadata.account_id.

How to avoid it:
Map it explicitly:

partnerAccountId: metadata.account_id

Validate that metadata.account_id is present before calling the Lynx linking endpoint.


6. Assuming the callback payload can be passed through without validation

The sample callback builds a payload object for the Lynx API, but implementers may assume every field is always present.

Why it happens:
Sample code often looks complete, so teams skip defensive validation.

How to avoid it:
Before calling Lynx, verify that you actually received:

  • public_token
  • metadata
  • metadata.account_id

If any are missing, stop and surface an error instead of sending a malformed request.


7. Treating the link token as reusable or long-lived

The link token is a short-lived token created by Get Link Token and used to initialize the Plaid component for the current flow.

Why it happens:
Teams may try to cache tokens too aggressively or reuse them across sessions.

How to avoid it:

  • Generate the token close to the time the user starts linking
  • Do not assume an old token will still be valid later
  • Regenerate the token when restarting a failed or abandoned flow

Recommended checklist

Before going live, confirm:

  • the redirect URL is registered with Lynx
  • the script is initialized from an approved page
  • the same redirect URL is used when generating the link token
  • public_token is mapped to partnerAccessToken
  • metadata.account_id is mapped to partnerAccountId
  • redirect-based institutions have been tested
  • the full payload for Link External Account Verified is validated before submission

What Lynx manages vs. what you manage

Lynx manages

  • The abstraction layer around Plaid
  • Link token generation
  • Secure maintenance of the Plaid token after account linking
  • Verified account-linking support for contribution workflows

You manage

  • Registering the redirect URL with Lynx
  • Calling Lynx APIs from your application
  • Hosting the frontend experience
  • Initializing LynxPlaid.js
  • Handling the callback
  • Submitting the verified external account link request

Reference implementation details

The currently documented LynxPlaid.js implementation is shown below for transparency:

window.Lynx = {
  init: function (e) {
    let t = Plaid.create({
      token: e.token,
      onSuccess: e.onSuccess,
      onExit: e.onExit,
      received_redirect_uri: window.location.href
    });
    t.open();
  },
  open: function () {
    let e = JSON.parse(localStorage.getItem("lynxData"));
    (handler = Plaid.create({
      token: e.token,
      onSuccess() {},
      onLoad() {},
      onExit(e, t) {},
      onEvent(e, t) {},
      receivedRedirectUri: window.location.href
    })).open();
  }
};

(script = document.createElement("script")).src = "https://cdn.plaid.com/link/v2/stable/link-initialize.js";
script.type = "text/javascript";
script.defer = true;
document.getElementsByTagName("head").item(0).appendChild(script);

window.onload = function () {
  let e = new URLSearchParams(window.location.search),
      t = Object.fromEntries(e.entries());
  if (t.oauth_state_id !== undefined) {
    Lynx.open();
  }
};

Note: When implementing, follow the documented integration contract in this guide rather than depending on internal implementation details of the script.


Integration checklist

Before going live, confirm the following:

  • Redirect URL has been registered with Lynx
  • The same redirect URL is passed to Get Link Token
  • The page hosting LynxPlaid.js is registered with Lynx
  • Your frontend can successfully call Lynx.init(...)
  • Your callback correctly maps:
    • public_tokenpartnerAccessToken
    • metadata.account_idpartnerAccountId
  • Your backend or service successfully calls Link External Account Verified
  • Error handling is in place for cancellations, redirect failures, and API validation issues
  • The full flow has been tested in the correct environment

API references


Support

If you need your redirect URL registered or updated, contact your Lynx Customer Success representative.