Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Yodlee

Yodlee (Envestnet) is an enterprise-grade financial data aggregation API that requires a formal partnership agreement — there is no free self-service developer sandbox. For most Bolt.new developers, Plaid is the more accessible alternative with a free sandbox and simpler onboarding. For enterprise fintech developers with Yodlee partnership access, integrate via the Fastlink widget for bank linking and REST API calls through Next.js API routes.

What you'll learn

  • How Yodlee's enterprise partnership model differs from Plaid's self-service developer access, and when to choose each
  • How to integrate Yodlee's Fastlink widget in a React component for bank account authentication
  • How to make authenticated Yodlee API calls using JWT tokens through Next.js server-side API routes
  • How to build a financial data dashboard in Bolt.new that displays connected account balances and transactions from Yodlee
  • Why Plaid is the recommended alternative for Bolt.new developers without enterprise Yodlee access
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate21 min read30 minutesOtherApril 2026RapidDev Engineering Team
TL;DR

Yodlee (Envestnet) is an enterprise-grade financial data aggregation API that requires a formal partnership agreement — there is no free self-service developer sandbox. For most Bolt.new developers, Plaid is the more accessible alternative with a free sandbox and simpler onboarding. For enterprise fintech developers with Yodlee partnership access, integrate via the Fastlink widget for bank linking and REST API calls through Next.js API routes.

Integrating Yodlee Financial Data with Bolt.new

Yodlee, now part of Envestnet, is one of the oldest and most established financial data aggregation platforms, powering consumer financial apps since 1999. It connects to over 21,000 financial institutions globally and has been used by major banks, personal finance apps (including the late Mint, which used Yodlee under the hood for its early bank connectivity), and enterprise fintech companies. Yodlee's breadth of international coverage and its institutional client base make it a common choice for enterprise fintech teams building in jurisdictions where Plaid's coverage is limited.

However, Yodlee has a fundamentally different business model than developer-friendly APIs like Plaid or Stripe. Yodlee requires a formal partnership agreement before granting API access — there is no self-service developer registration, no free public sandbox accessible to individual developers, and no pay-as-you-go pricing. Prospective customers go through a sales process, sign contracts, and are provisioned with API credentials as part of a commercial relationship. This model makes Yodlee well-suited for enterprise fintech teams with legal and compliance teams, but significantly less accessible for indie developers or early-stage startups building with Bolt.new.

For Bolt.new developers who do have Yodlee enterprise access, the integration uses two components: the Fastlink widget (a hosted JavaScript flow for bank account authentication that loads in an iframe or redirect flow, similar in purpose to Plaid Link), and Yodlee's REST API for retrieving account data and transactions once accounts are connected. This guide covers both, with clear notes on where Plaid is the more practical alternative for most Bolt.new use cases. If you do not yet have Yodlee credentials, skip to the alternatives section — Plaid's free sandbox lets you build and validate the same functionality before committing to an enterprise financial data contract.

Integration method

Bolt Chat + API Route

Yodlee integrates with Bolt.new through a two-part flow: the Fastlink widget (a JavaScript embed for bank account authentication, similar to Plaid Link) loads in the browser, while all API calls for account data and transactions happen through Next.js API routes using Yodlee's REST API with JWT authentication. Yodlee requires a formal enterprise partnership for API access — there is no free public sandbox. For developers without Yodlee access, Plaid provides the same functionality with a free developer sandbox and simpler self-service onboarding.

Prerequisites

  • A Yodlee enterprise partnership account — contact Yodlee sales at yodlee.com to begin the partnership process; API credentials are not available without a commercial agreement
  • YODLEE_CLIENT_ID, YODLEE_SECRET, and YODLEE_CONFIG_NAME from your Yodlee partnership agreement, stored in your Bolt project's .env file
  • A Bolt.new project using Next.js for server-side API routes — Yodlee API credentials must never be exposed in client-side code
  • Understanding that Yodlee's Fastlink widget requires a User Login Name concept — each end user in your app must have a registered Yodlee user before they can use Fastlink
  • For developers without Yodlee access: a free Plaid developer account at dashboard.plaid.com as the accessible alternative for testing bank connectivity features

Step-by-step guide

1

Understand Yodlee's access model and compare with Plaid

Before writing any integration code, understanding Yodlee's enterprise access model is essential — it directly shapes whether Yodlee is the right choice for your Bolt.new project. Yodlee requires enterprise partnership to access any API endpoint, including a sandbox or development environment. The partnership process involves a sales conversation, legal review, contract negotiation, and provisioning of credentials. Typical timelines for new Yodlee partnerships run from a few weeks to a few months. Yodlee's pricing is enterprise contract-based, generally starting at several thousand dollars per month for mid-market clients. There is no published self-service pricing, no free tier, and no trial without a sales engagement. This stands in sharp contrast to Plaid, which offers a free developer account at dashboard.plaid.com that can be created in minutes, includes a Sandbox environment with realistic test data and institutions, and has a self-service development-to-production upgrade path. Plaid's Sandbox requires no credit card, no sales call, and no contract — you can build and test a complete bank connectivity feature in a Bolt.new app the same day you create a Plaid account. When does Yodlee win over Plaid? International coverage is the primary reason enterprises choose Yodlee. Plaid has excellent coverage in the US and Canada, reasonable coverage in Europe (UK, France, Spain, Netherlands, Ireland), and limited coverage elsewhere. Yodlee covers 21,000+ institutions across North America, Europe, Australia, India, and parts of Asia — substantially broader for global fintech products. Enterprise SLAs, dedicated support, and deeper data enrichment are secondary considerations that matter more to established fintechs than to Bolt-built startups. For most Bolt.new developers reading this page, the recommendation is: start with Plaid. Build your MVP, validate that users want bank connectivity, and if you reach scale and need Yodlee's international coverage or enterprise data contracts, the migration is a backend change — the frontend components (bank linking widget, account display, transaction list) are nearly identical between Plaid and Yodlee at the code level. This guide covers both, letting you build with either credential set.

Bolt.new Prompt

Set up the configuration for a financial data integration that supports both Yodlee (enterprise) and Plaid (accessible alternative). Create lib/financial/config.ts that exports: FINANCIAL_PROVIDER (from process.env.FINANCIAL_PROVIDER, defaulting to 'plaid'), YODLEE_CONFIG object (clientId, secret, configName, apiBase from env vars), PLAID_CONFIG object (clientId, secret, env, apiBase from env vars). Create a unified type interface for accounts: FinancialAccount with id, name, type, institution, balance, currency. Add both YODLEE_CLIENT_ID, YODLEE_SECRET, YODLEE_CONFIG_NAME and PLAID_CLIENT_ID, PLAID_SECRET to .env as placeholders. Add a comment explaining Yodlee requires enterprise partnership while Plaid has a free developer sandbox.

Paste this in Bolt.new chat

lib/financial/config.ts
1// lib/financial/config.ts
2// Financial data provider configuration
3// Yodlee: requires enterprise partnership (yodlee.com/contact-us)
4// Plaid: free developer account available at dashboard.plaid.com
5
6export type FinancialProvider = 'yodlee' | 'plaid';
7
8export const FINANCIAL_PROVIDER: FinancialProvider =
9 (process.env.FINANCIAL_PROVIDER as FinancialProvider) ?? 'plaid';
10
11export const YODLEE_CONFIG = {
12 clientId: process.env.YODLEE_CLIENT_ID ?? '',
13 secret: process.env.YODLEE_SECRET ?? '',
14 configName: process.env.YODLEE_CONFIG_NAME ?? '',
15 // Yodlee environments: 'sandbox' (partnership required), 'production'
16 apiBase: process.env.YODLEE_ENV === 'production'
17 ? 'https://production.api.yodlee.com/ysl'
18 : 'https://sandbox.api.yodlee.com/ysl',
19};
20
21export const PLAID_CONFIG = {
22 clientId: process.env.PLAID_CLIENT_ID ?? '',
23 secret: process.env.PLAID_SECRET ?? '',
24 // Plaid environments: 'sandbox' (free), 'development', 'production'
25 env: process.env.PLAID_ENV ?? 'sandbox',
26 apiBase: `https://${process.env.PLAID_ENV ?? 'sandbox'}.plaid.com`,
27};
28
29// Unified account type for display layer — same shape regardless of provider
30export interface FinancialAccount {
31 id: string;
32 name: string;
33 type: string;
34 institution: string;
35 balance: number;
36 currency: string;
37 providerAccountId?: string;
38}
39
40export interface FinancialTransaction {
41 id: string;
42 accountId: string;
43 description: string;
44 amount: number;
45 type: 'income' | 'expense';
46 category: string;
47 date: string;
48 pending: boolean;
49}

Pro tip: If you have Yodlee partnership access, set FINANCIAL_PROVIDER=yodlee in your .env. If you are starting with Plaid (the accessible default), set FINANCIAL_PROVIDER=plaid or omit the variable. The abstraction layer lets you migrate providers later without changing the React components.

Expected result: The financial config module is in place with provider-agnostic type definitions. The .env file has placeholder variables for both Yodlee and Plaid credentials. The FINANCIAL_PROVIDER variable controls which backend the API routes will use.

2

Implement Yodlee authentication with JWT tokens

Yodlee's REST API uses JWT-based authentication with two token types: the App-Level token (client credentials grant) and the User-Level token (required for user-specific data like accounts and transactions). Most API calls require the User-Level token, which means you must first register a Yodlee user for each of your app's users, then generate a token scoped to that user. The App-Level token is obtained by POSTing to Yodlee's /auth/token endpoint with your Client ID and Client Secret as Basic authentication (base64 encoded). The response contains an access_token valid for 30 minutes. Store this token in memory (not a database) since you will refresh it frequently. User management in Yodlee introduces a concept that differs from most APIs: each of your application's end users must be registered in Yodlee's system with a unique loginName. When a new user signs up for your Bolt app and wants to connect their bank, you first call Yodlee's user registration endpoint to create a Yodlee user record for them, then generate a user-scoped token for that user's subsequent Fastlink and account API calls. The User-Level token flow: first, call /auth/token with your App-Level token as Bearer auth and the user's loginName in the request body. Yodlee returns a user-specific JWT. All subsequent calls to /accounts, /transactions, and the Fastlink token endpoint use this user-level token as Bearer auth. User-level tokens expire after 1800 seconds (30 minutes) and must be refreshed. For Bolt.new apps, implement a token refresh utility that caches the user's Yodlee token in your Supabase database with an expiry timestamp. Before each API call, check if the cached token is within 5 minutes of expiry and refresh it if so. This avoids token expiration errors mid-session. Note: Yodlee's Sandbox environment has the same authentication flow as production but uses sandbox credentials and returns synthetic bank data. The sandbox API base URL is https://sandbox.api.yodlee.com/ysl — ensure your YODLEE_ENV environment variable is set to 'sandbox' during development.

Bolt.new Prompt

Build Yodlee authentication utilities. Create lib/yodlee/auth.ts with two functions: (1) getAppToken() that POSTs to {YODLEE_CONFIG.apiBase}/auth/token with Basic auth (base64 of clientId:secret) and returns the JWT access token, (2) getUserToken(loginName: string) that POSTs to /auth/token with Bearer App-Level token and loginName in the request body, returning a user-scoped JWT. Create an API route at app/api/yodlee/token/route.ts that accepts a POST with loginName, calls getUserToken(), and returns the token. Cache the App-Level token in module scope with expiry check. Add TypeScript interfaces for Yodlee token responses.

Paste this in Bolt.new chat

lib/yodlee/auth.ts
1// lib/yodlee/auth.ts
2import { YODLEE_CONFIG } from '@/lib/financial/config';
3
4interface YodleeTokenResponse {
5 token: {
6 accessToken: string;
7 issuedAt: string;
8 expiresIn: number;
9 };
10}
11
12// Module-level cache for app-level token
13let cachedAppToken: { token: string; expiresAt: number } | null = null;
14
15export async function getYodleeAppToken(): Promise<string> {
16 // Return cached token if still valid (with 2-minute buffer)
17 if (cachedAppToken && Date.now() < cachedAppToken.expiresAt - 120_000) {
18 return cachedAppToken.token;
19 }
20
21 const credentials = Buffer.from(
22 `${YODLEE_CONFIG.clientId}:${YODLEE_CONFIG.secret}`
23 ).toString('base64');
24
25 const response = await fetch(`${YODLEE_CONFIG.apiBase}/auth/token`, {
26 method: 'POST',
27 headers: {
28 Authorization: `Basic ${credentials}`,
29 'Content-Type': 'application/x-www-form-urlencoded',
30 Api-Version: '1.1',
31 },
32 body: 'grant_type=client_credentials',
33 });
34
35 if (!response.ok) {
36 const error = await response.text();
37 throw new Error(`Yodlee app token failed: ${response.status} ${error}`);
38 }
39
40 const data: YodleeTokenResponse = await response.json();
41 cachedAppToken = {
42 token: data.token.accessToken,
43 expiresAt: Date.now() + data.token.expiresIn * 1000,
44 };
45 return cachedAppToken.token;
46}
47
48export async function getYodleeUserToken(loginName: string): Promise<string> {
49 const appToken = await getYodleeAppToken();
50
51 const response = await fetch(`${YODLEE_CONFIG.apiBase}/auth/token`, {
52 method: 'POST',
53 headers: {
54 Authorization: `Bearer ${appToken}`,
55 'Content-Type': 'application/x-www-form-urlencoded',
56 loginName,
57 'Api-Version': '1.1',
58 },
59 body: 'grant_type=client_credentials',
60 });
61
62 if (!response.ok) {
63 const error = await response.text();
64 throw new Error(`Yodlee user token failed: ${response.status} ${error}`);
65 }
66
67 const data: YodleeTokenResponse = await response.json();
68 return data.token.accessToken;
69}

Pro tip: The loginName sent to Yodlee's user token endpoint must exactly match the loginName used when registering the user in Yodlee's system. Use a consistent identifier from your own user system (e.g., the Supabase user UUID) as the Yodlee loginName — it never changes and is unique.

Expected result: The Yodlee authentication utilities generate App-Level and User-Level JWTs. The module-level cache prevents unnecessary token refresh calls. API routes that import getYodleeUserToken() can make authenticated calls to Yodlee's API endpoints.

3

Integrate the Yodlee Fastlink widget for bank account linking

Yodlee Fastlink is the bank account authentication widget — it handles the complex process of connecting to thousands of different financial institutions with their varying authentication methods (username/password, MFA, OAuth, security questions). Fastlink is a hosted JavaScript application that Yodlee provides; your app loads it in an iframe or redirected window, the user authenticates with their bank inside Fastlink, and upon completion Fastlink calls a callback function in your page. The Fastlink widget has two loading modes: iFrame mode (embeds directly in your page inside an iframe element) and window mode (opens as a popup or redirects to Fastlink's hosted URL). The iFrame mode provides a smoother user experience since the user stays on your page, while window mode is simpler to implement and works better on mobile. For a Bolt.new app, iFrame mode is recommended for desktop-first products. To open Fastlink, your app first generates a Fastlink-specific access token (a User-Level token with Fastlink scope) by calling your /api/yodlee/token route with the user's loginName. Then your React component calls window.fastlink.open() with the token, your configName (a Yodlee configuration identifier that controls the widget appearance and enabled features), and callback functions for success, error, and close events. The onSuccess callback receives an event object with account data. The most important field is providerAccountId — the ID of the newly linked bank connection. After successful linking, call your /api/yodlee/accounts route to fetch the full account details for the new connection. Fastlink configuration (colors, logo, enabled features, supported account types) is managed in the Yodlee developer portal under your Config settings. The configName in your code references a named configuration profile. Enterprise partners typically have separate configs for development and production environments. Critical WebContainer note: Fastlink works in Bolt's WebContainer preview for development since it is an outbound load of Yodlee's hosted JavaScript. However, Yodlee's webhook notifications (for transaction updates and account status changes) require a deployed URL. Test the Fastlink widget flow in preview, but set up webhooks only after deploying to Netlify or Bolt Cloud.

Bolt.new Prompt

Build a Yodlee Fastlink integration component. Create components/YodleeFastlink.tsx that: (1) Fetches a Fastlink token from /api/yodlee/token on mount (pass the current user's loginName), (2) Dynamically loads the Yodlee Fastlink script from YODLEE_FASTLINK_URL (from process.env), (3) When the script loads, calls window.fastlink.open() with params: fastLinkURL from YODLEE_FASTLINK_URL env var, accessToken from step 1, params.configName from YODLEE_CONFIG_NAME env var, (4) Handles onSuccess callback by calling /api/yodlee/accounts and displaying the newly linked accounts, (5) Handles onError with an error message, (6) Renders an iframe container div. Add a 'Connect Your Bank' button that triggers the Fastlink open. Use TypeScript.

Paste this in Bolt.new chat

components/YodleeFastlink.tsx
1// components/YodleeFastlink.tsx
2'use client';
3import { useEffect, useRef, useState } from 'react';
4
5interface YodleeAccount {
6 id: string;
7 accountName: string;
8 accountType: string;
9 providerName: string;
10 balance?: { amount: number; currency: string };
11}
12
13interface YodleeWindow extends Window {
14 fastlink?: {
15 open: (params: object, containerId: string) => void;
16 close: () => void;
17 };
18}
19
20export function YodleeFastlink({ loginName }: { loginName: string }) {
21 const [accounts, setAccounts] = useState<YodleeAccount[]>([]);
22 const [loading, setLoading] = useState(false);
23 const [error, setError] = useState<string>('');
24 const containerRef = useRef<HTMLDivElement>(null);
25 const scriptLoaded = useRef(false);
26
27 useEffect(() => {
28 if (scriptLoaded.current) return;
29 // Load Yodlee Fastlink script — URL provided by Yodlee partnership
30 const fastlinkUrl = process.env.NEXT_PUBLIC_YODLEE_FASTLINK_URL;
31 if (!fastlinkUrl) return;
32
33 const script = document.createElement('script');
34 script.src = `${fastlinkUrl}/authenticate/restserver/fastlink`;
35 script.async = true;
36 document.body.appendChild(script);
37 scriptLoaded.current = true;
38 }, []);
39
40 const openFastlink = async () => {
41 setLoading(true);
42 setError('');
43
44 try {
45 // Get user-scoped Fastlink token
46 const tokenRes = await fetch('/api/yodlee/token', {
47 method: 'POST',
48 headers: { 'Content-Type': 'application/json' },
49 body: JSON.stringify({ loginName }),
50 });
51 const { token } = await tokenRes.json();
52
53 const yodleeWindow = window as YodleeWindow;
54 if (!yodleeWindow.fastlink) {
55 setError('Fastlink script not loaded. Check NEXT_PUBLIC_YODLEE_FASTLINK_URL.');
56 setLoading(false);
57 return;
58 }
59
60 yodleeWindow.fastlink.open(
61 {
62 fastLinkURL: process.env.NEXT_PUBLIC_YODLEE_FASTLINK_URL,
63 accessToken: `Bearer ${token}`,
64 params: {
65 configName: process.env.NEXT_PUBLIC_YODLEE_CONFIG_NAME ?? 'Aggregation',
66 },
67 onSuccess: async (data: { providerAccountId: string }) => {
68 console.log('Fastlink success, providerAccountId:', data.providerAccountId);
69 // Fetch newly linked accounts
70 const accountsRes = await fetch(`/api/yodlee/accounts?loginName=${loginName}`);
71 const accountsData = await accountsRes.json();
72 setAccounts(accountsData.accounts ?? []);
73 setLoading(false);
74 },
75 onError: (data: { message: string }) => {
76 setError(`Fastlink error: ${data.message}`);
77 setLoading(false);
78 },
79 onClose: () => setLoading(false),
80 },
81 'yodlee-fastlink-container'
82 );
83 } catch (err) {
84 setError(err instanceof Error ? err.message : 'Failed to open Fastlink');
85 setLoading(false);
86 }
87 };
88
89 return (
90 <div className="space-y-4">
91 <button
92 onClick={openFastlink}
93 disabled={loading}
94 className="rounded-lg bg-blue-600 px-6 py-3 font-medium text-white hover:bg-blue-700 disabled:opacity-50"
95 >
96 {loading ? 'Connecting...' : 'Connect Your Bank'}
97 </button>
98
99 {error && <p className="text-sm text-red-600">{error}</p>}
100
101 {/* Fastlink renders into this container */}
102 <div id="yodlee-fastlink-container" ref={containerRef} className="min-h-[500px]" />
103
104 {accounts.length > 0 && (
105 <div className="mt-6">
106 <h3 className="font-semibold">Connected Accounts</h3>
107 {accounts.map((account) => (
108 <div key={account.id} className="mt-2 rounded border p-3">
109 <p className="font-medium">{account.accountName}</p>
110 <p className="text-sm text-gray-500">{account.providerName} · {account.accountType}</p>
111 {account.balance && (
112 <p className="text-sm">{account.balance.currency} {account.balance.amount.toFixed(2)}</p>
113 )}
114 </div>
115 ))}
116 </div>
117 )}
118 </div>
119 );
120}

Pro tip: The YODLEE_FASTLINK_URL is specific to your Yodlee environment (sandbox vs production) and is provided by Yodlee as part of your partnership onboarding. It typically follows the pattern https://{environment}.yodlee.com. Prefix it with NEXT_PUBLIC_ in your .env since it needs to be accessible from the browser-side component.

Expected result: Clicking 'Connect Your Bank' opens the Yodlee Fastlink widget in the page container. After completing bank authentication in the widget, connected accounts appear below the button with institution names, account types, and current balances.

4

Fetch accounts and transactions from Yodlee API

With bank accounts linked through Fastlink, the Yodlee REST API provides endpoints for fetching account details, balances, and transaction history. All API calls use the User-Level JWT token as Bearer authentication and target the same Yodlee API base URL used for authentication. The accounts endpoint, GET /accounts, returns all linked accounts for the authenticated user. Key fields include: id, accountName, accountType, providerName (bank name), providerAccountId, balance (current balance), availableBalance, accountNumber (masked), and refreshInfo (when data was last synced). Yodlee accounts can be checking, savings, credit card, investment, loan, or insurance accounts. The transactions endpoint, GET /transactions, returns paginated transactions. Important query parameters include: fromDate (YYYY-MM-DD format), toDate, accountId (filter by specific account), categoryId, keyword (search in transaction descriptions), skip (pagination offset), and top (page size, max 500). Yodlee transactions have detailed categorization: each transaction has a category object with a detailed category name from Yodlee's taxonomy (e.g., 'Groceries', 'Gas Stations', 'Utilities') and a high-level category (e.g., 'Food', 'Automotive', 'Bills and Utilities'). Create two Next.js API routes: /api/yodlee/accounts and /api/yodlee/transactions. Both routes read the user's loginName from the request (from a cookie or session), call getYodleeUserToken() to get a fresh user-level JWT, and make the respective Yodlee API calls. The routes transform Yodlee's response format into the FinancialAccount and FinancialTransaction types from your config module, providing a consistent interface whether you are using Yodlee or Plaid as the backend provider. Yodlee data freshness: Yodlee's aggregated data is not always real-time. Most banks update data every 1-6 hours through Yodlee's background refresh system. The refreshInfo object on each account tells you when data was last successfully synced. For near-real-time balance checks, Yodlee has a manual refresh endpoint (POST /providerAccounts/{id}/refresh) that triggers an immediate data pull — use this when users click a 'Refresh' button.

Bolt.new Prompt

Build Yodlee accounts and transactions API routes. (1) Create app/api/yodlee/accounts/route.ts that reads loginName from query params, calls getYodleeUserToken(loginName), then calls GET {YODLEE_CONFIG.apiBase}/accounts with the Bearer token and Api-Version: 1.1 header, and returns accounts mapped to FinancialAccount type. (2) Create app/api/yodlee/transactions/route.ts that fetches transactions from /transactions?fromDate=30_days_ago&toDate=today&top=50 with the user token, maps to FinancialTransaction type (set type as 'expense' if amount.amount > 0), and returns the list. Create a FinancialDashboard client component that fetches from both routes and displays accounts and recent transactions.

Paste this in Bolt.new chat

app/api/yodlee/accounts/route.ts
1// app/api/yodlee/accounts/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { YODLEE_CONFIG, type FinancialAccount } from '@/lib/financial/config';
4import { getYodleeUserToken } from '@/lib/yodlee/auth';
5
6export async function GET(request: NextRequest) {
7 const loginName = request.nextUrl.searchParams.get('loginName');
8 if (!loginName) {
9 return NextResponse.json({ error: 'loginName is required' }, { status: 400 });
10 }
11
12 try {
13 const userToken = await getYodleeUserToken(loginName);
14
15 const response = await fetch(`${YODLEE_CONFIG.apiBase}/accounts`, {
16 headers: {
17 Authorization: `Bearer ${userToken}`,
18 'Api-Version': '1.1',
19 'Content-Type': 'application/json',
20 },
21 });
22
23 if (!response.ok) {
24 return NextResponse.json(
25 { error: `Yodlee accounts API error: ${response.status}` },
26 { status: response.status }
27 );
28 }
29
30 const data = await response.json();
31
32 const accounts: FinancialAccount[] = (data.account ?? []).map((acc: {
33 id: number;
34 accountName: string;
35 accountType: string;
36 providerName: string;
37 balance?: { amount: number; currency: string };
38 providerAccountId: number;
39 }) => ({
40 id: String(acc.id),
41 name: acc.accountName,
42 type: acc.accountType,
43 institution: acc.providerName,
44 balance: acc.balance?.amount ?? 0,
45 currency: acc.balance?.currency ?? 'USD',
46 providerAccountId: String(acc.providerAccountId),
47 }));
48
49 return NextResponse.json({ accounts });
50 } catch (error) {
51 const message = error instanceof Error ? error.message : 'Request failed';
52 return NextResponse.json({ error: message }, { status: 500 });
53 }
54}

Pro tip: Yodlee requires the Api-Version: 1.1 header on all API requests — without it, requests may fail or return unexpected responses. Always include this header alongside the Authorization: Bearer token in every Yodlee API call.

Expected result: The /api/yodlee/accounts route returns connected bank accounts with names, types, institutions, and current balances. The /api/yodlee/transactions route returns recent transactions. The financial dashboard component displays accounts and transactions for the authenticated user.

Common use cases

Enterprise Personal Finance Dashboard with Yodlee Data

A financial wellness portal for enterprise clients where employees or customers connect their personal bank accounts via Yodlee's Fastlink widget, then see aggregated account balances, spending summaries, and net worth across all connected institutions. Targeted at enterprise B2B2C deployments where the organization has a Yodlee partnership.

Bolt.new Prompt

Build a financial dashboard using Yodlee. Create Next.js API routes: (1) /api/yodlee/token that generates a Yodlee API access token using the client credentials (YODLEE_CLIENT_ID and YODLEE_SECRET from process.env) via POST to https://production.api.yodlee.com/ysl/auth/token, (2) /api/yodlee/accounts that calls GET https://production.api.yodlee.com/ysl/accounts with the bearer token and returns account names, types, and balances, (3) /api/yodlee/transactions that fetches recent transactions for the connected accounts. Build a dashboard showing account cards with balances and a transaction list. Note that Fastlink widget URL and credentials must come from your Yodlee enterprise partnership.

Copy this prompt to try it in Bolt.new

Yodlee Fastlink Bank Account Connection Flow

A React component that opens Yodlee's Fastlink widget, guides the user through selecting their bank and authenticating, and receives a callback when accounts are successfully linked. The Fastlink token is generated server-side for security, the widget loads in a modal overlay, and the success callback triggers a server-side account fetch.

Bolt.new Prompt

Build a Yodlee Fastlink integration. Create an API route at /api/yodlee/fastlink-token that generates a Fastlink access token by calling Yodlee's token endpoint with the user's login name. Build a React component called YodleeFastlink that: (1) Fetches the Fastlink token from the API route, (2) Opens the Fastlink widget using window.fastlink.open() with the token and configName from YODLEE_CONFIG_NAME env var, (3) Handles the onSuccess callback by calling the /api/yodlee/accounts route to fetch newly linked accounts, (4) Handles onError and onClose callbacks. Show a 'Connect Your Bank' button to trigger the flow. Display connected accounts after successful linking.

Copy this prompt to try it in Bolt.new

Plaid as the Accessible Alternative for Bank Connectivity

For Bolt.new developers without Yodlee enterprise access, Plaid provides identical bank account linking functionality with a free developer sandbox. This use case demonstrates building the same account dashboard as the Yodlee integration using Plaid's Link widget and transactions API — a practical starting point that can be migrated to Yodlee later if needed.

Bolt.new Prompt

I want to build bank account connectivity but don't have Yodlee access. Build the equivalent using Plaid instead. Create a Next.js API route at /api/plaid/link-token that calls Plaid's sandbox endpoint https://sandbox.plaid.com/link/token/create with PLAID_CLIENT_ID and PLAID_SECRET from process.env, user.client_user_id, products ['transactions'], country_codes ['US']. Build a ConnectBankButton component that loads the Plaid Link SDK from https://cdn.plaid.com/link/v2/stable/link-initialize.js, opens Link with the token, and calls /api/plaid/exchange on success. Fetch accounts from /api/plaid/accounts. Test with Sandbox credentials: user_good / pass_good.

Copy this prompt to try it in Bolt.new

Troubleshooting

Yodlee API returns 401 Unauthorized with 'Y002' error code even with a fresh access token

Cause: The Api-Version header is missing or incorrect, the loginName in the user token request does not match a registered Yodlee user, or the token was generated for a different environment (sandbox vs production).

Solution: Verify that every Yodlee API call includes the 'Api-Version: 1.1' header. Check that the loginName used in getYodleeUserToken matches a user registered in your Yodlee system. Confirm YODLEE_ENV matches your credentials — sandbox credentials do not work against production endpoints and vice versa. Check the Yodlee developer portal for exact API version requirements for your partnership contract.

typescript
1// Always include Api-Version header in Yodlee requests
2const response = await fetch(`${YODLEE_CONFIG.apiBase}/accounts`, {
3 headers: {
4 Authorization: `Bearer ${userToken}`,
5 'Api-Version': '1.1', // Required for all Yodlee REST API calls
6 'Content-Type': 'application/json',
7 },
8});

Yodlee Fastlink widget does not open — window.fastlink is undefined

Cause: The Yodlee Fastlink script has not loaded before openFastlink() is called, NEXT_PUBLIC_YODLEE_FASTLINK_URL is not set in the .env file, or the script URL is incorrect for your Yodlee environment.

Solution: Verify NEXT_PUBLIC_YODLEE_FASTLINK_URL is set in your .env file with the URL provided in your Yodlee partnership credentials. The Fastlink URL differs between sandbox and production. Add a check in the openFastlink function: if (!(window as YodleeWindow).fastlink) show an error message. Use the script onload event to enable the 'Connect Your Bank' button only after the script loads successfully.

typescript
1// Only enable the button after Fastlink script loads
2const [fastlinkReady, setFastlinkReady] = useState(false);
3
4useEffect(() => {
5 const script = document.createElement('script');
6 script.src = `${process.env.NEXT_PUBLIC_YODLEE_FASTLINK_URL}/authenticate/restserver/fastlink`;
7 script.onload = () => setFastlinkReady(true);
8 script.onerror = () => setError('Failed to load Yodlee Fastlink script');
9 document.body.appendChild(script);
10}, []);
11
12// Disable button until ready
13<button disabled={!fastlinkReady || loading}>Connect Your Bank</button>

Yodlee API calls work in development but fail after deploying to Netlify with CORS errors

Cause: The Yodlee API calls are being made from the browser (client-side React) instead of from the Next.js API route (server-side). CORS errors occur because Yodlee's API does not whitelist your Netlify domain for direct browser calls.

Solution: Ensure all Yodlee API calls happen in Next.js API routes (app/api/yodlee/*/route.ts), never directly from React components. React components should only call your own API routes (/api/yodlee/accounts), which then proxy to Yodlee server-side. Server-side fetch calls are not subject to CORS — CORS only applies to browser-to-server requests. This pattern also keeps your Yodlee credentials (stored in server-only env vars without NEXT_PUBLIC_ prefix) out of the browser bundle.

typescript
1// WRONG: Direct browser call to Yodlee API
2const data = await fetch('https://sandbox.api.yodlee.com/ysl/accounts', ...);
3
4// CORRECT: Call your own API route (server-side proxy to Yodlee)
5const data = await fetch(`/api/yodlee/accounts?loginName=${loginName}`);

Yodlee transactions show stale data that is several hours old despite accounts being connected

Cause: Yodlee aggregates bank data on a schedule (typically every 1-6 hours depending on the institution and your partnership SLA). The data returned reflects the last successful refresh time shown in the refreshInfo field on each account, not real-time bank data.

Solution: Trigger a manual data refresh using Yodlee's refresh endpoint before fetching transactions when fresh data is critical. Add a 'Refresh Data' button in your UI that calls POST /providerAccounts/{providerAccountId} with action=refresh, then waits for the refresh to complete before fetching new transaction data. Show the last refresh time from the account's refreshInfo.lastRefreshed field so users know how recent the data is.

typescript
1// Trigger manual account refresh
2async function refreshYodleeAccount(providerAccountId: string, loginName: string) {
3 const userToken = await getYodleeUserToken(loginName);
4 await fetch(`${YODLEE_CONFIG.apiBase}/providerAccounts/${providerAccountId}`, {
5 method: 'PUT',
6 headers: { Authorization: `Bearer ${userToken}`, 'Api-Version': '1.1' },
7 body: JSON.stringify({ action: 'refresh' }),
8 });
9 // Wait briefly for refresh to process before fetching new data
10 await new Promise(resolve => setTimeout(resolve, 5000));
11}

Best practices

  • For most Bolt.new developers without Yodlee enterprise access, use Plaid for development and early-stage products — Plaid's free sandbox lets you build and validate the same bank connectivity features before committing to a Yodlee enterprise contract
  • Never expose Yodlee client credentials in client-side code — YODLEE_CLIENT_ID and YODLEE_SECRET must remain in server-only environment variables (no NEXT_PUBLIC_ prefix) and all Yodlee API calls must go through Next.js API routes
  • Cache Yodlee app-level tokens in module scope with expiry tracking rather than generating a new token on every API call — app-level tokens last 30 minutes and frequent regeneration adds unnecessary latency
  • Display the lastRefreshed timestamp from Yodlee's refreshInfo on each account card — users need to know if their balance data is 1 hour old vs 12 hours old to trust the information
  • Implement error handling for Yodlee's 'Y codes' error taxonomy — Yodlee uses specific error codes (Y002 for auth failures, Y008 for invalid parameters, etc.) that provide more diagnostic information than HTTP status codes alone
  • Register Yodlee webhooks after deploying to Netlify or Bolt Cloud — webhooks for account refresh status, new transactions, and connection errors require a publicly accessible HTTPS URL that Bolt's WebContainer cannot provide
  • Build an abstraction layer (as shown in the financial/config.ts step) that normalizes Plaid and Yodlee data to the same format — this allows switching providers or running both in parallel without changing your React components

Alternatives

Frequently asked questions

Does Yodlee have a free developer sandbox for Bolt.new development?

Yodlee does not offer a free public sandbox accessible to individual developers. All Yodlee API access, including sandbox environments, requires a formal enterprise partnership agreement. If you need to develop and test bank connectivity features without enterprise credentials, Plaid offers a completely free developer sandbox at dashboard.plaid.com that can be set up in minutes and provides the same bank linking and transaction data functionality.

Does Yodlee Fastlink work in Bolt.new's WebContainer preview?

The Fastlink widget itself loads in the Bolt preview since it is an outbound JavaScript load from Yodlee's CDN. Token generation through your API routes also works in the preview. However, Yodlee webhooks (for transaction updates and account refresh notifications) cannot be received in the WebContainer since it has no public URL. Deploy to Netlify or Bolt Cloud to register webhook endpoints and test the full notification flow.

How does Yodlee compare to Plaid for a Bolt.new app?

For most Bolt.new developers, Plaid is the better starting point — free sandbox, self-service onboarding, and good US/Canada coverage. Yodlee becomes the better choice at enterprise scale when you need broader international bank coverage (21,000+ institutions globally including Asia, India, and Australia), enterprise SLAs, or institutional-grade data contracts. Both use a similar technical pattern in Bolt.new: a JavaScript widget for bank linking and REST API calls through Next.js API routes.

Can I use both Yodlee and Plaid in the same Bolt.new app?

Yes — and it is a practical strategy. Use Plaid for US/Canada users (better developer experience, lower cost) and Yodlee for international users (broader coverage). The financial/config.ts abstraction layer in this guide demonstrates how to normalize both providers' data to the same FinancialAccount and FinancialTransaction types. The React components then display data consistently regardless of which provider sourced it. Route users to the appropriate provider based on their country at the API route level.

How do I get started with Yodlee for a Bolt.new app?

Visit yodlee.com and use the 'Contact Us' form to start a partnership inquiry. Describe your use case, expected user volume, and geographic markets. Yodlee will assign a sales representative who will provide a sandbox environment, API credentials, and Fastlink URL as part of the onboarding process. During the sales process, you can begin development using Plaid's free sandbox so you are not blocked — the code patterns are similar enough that migrating from Plaid to Yodlee is a backend-only change.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.