Skip to main content
RapidDev - Software Development Agency
retool-integrationsREST API Resource

How to Integrate Retool with Yodlee

Connect Retool to Yodlee using a REST API Resource with Yodlee's two-tier authentication: an admin token obtained via client credentials grant for managing users, and a user-specific JWT for accessing financial account data. Build financial aggregation dashboards that display linked bank accounts, transaction histories, account balances, and investment holdings from thousands of financial institutions.

What you'll learn

  • How to configure Yodlee's two-tier authentication (admin token + user JWT) in a Retool REST API Resource
  • How to obtain and refresh Yodlee API tokens using Retool JavaScript queries and Workflows
  • How to query Yodlee accounts, transactions, and holdings endpoints for financial data aggregation
  • How to build a financial dashboard in Retool displaying linked accounts, balances, and transaction history
  • How to handle Yodlee's enterprise API patterns including provider refresh status and data staleness
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced16 min read45 minutesOtherLast updated April 2026RapidDev Engineering Team
TL;DR

Connect Retool to Yodlee using a REST API Resource with Yodlee's two-tier authentication: an admin token obtained via client credentials grant for managing users, and a user-specific JWT for accessing financial account data. Build financial aggregation dashboards that display linked bank accounts, transaction histories, account balances, and investment holdings from thousands of financial institutions.

Quick facts about this guide
FactValue
ToolYodlee
CategoryOther
MethodREST API Resource
DifficultyAdvanced
Time required45 minutes
Last updatedApril 2026

Build a Yodlee Financial Aggregation Dashboard in Retool

Yodlee is a leading enterprise financial data aggregation platform trusted by hundreds of fintech companies and financial institutions to provide normalized access to bank accounts, investment portfolios, credit cards, loans, and transaction histories from over 17,000 financial institutions worldwide. Building a Retool integration with Yodlee enables operations teams to access aggregated financial data without developing a full front-end application.

A Yodlee-powered Retool dashboard can serve multiple use cases: a financial operations panel that shows all linked accounts for a specific user alongside their transaction history; an account health monitor that surfaces accounts with stale data (where Yodlee's connection to the institution has degraded); or a portfolio overview that aggregates investment holdings and calculates allocation percentages across account types. These dashboards are particularly valuable for fintech operations teams who need to investigate user account issues, verify data quality, or provide frontline support without requiring engineers to run database queries.

Yodlee's authentication architecture requires careful management in Retool. Unlike APIs with a single long-lived key, Yodlee requires two sequential token acquisition steps: first, an admin token obtained via OAuth client credentials (valid for 30 minutes), then a user-specific JWT generated using the admin token (also short-lived). Retool Workflows can automate token refresh to keep the dashboard operational without manual intervention. This complexity is the key differentiator between Yodlee (enterprise-grade) and simpler alternatives like Plaid, which uses a more developer-friendly credential model.

Integration method

REST API Resource

Yodlee uses a two-tier authentication architecture. An admin token (obtained via client credentials OAuth) is used for user management operations, while a user-level JWT is required to access any financial data for a specific user. Both tokens are short-lived and must be refreshed regularly. Configure Retool with a REST API Resource pointing to the Yodlee FastLink or Core API base URL, and manage token exchange through JavaScript queries or Retool Workflows. All requests proxy server-side through Retool, ensuring financial credentials never reach the browser.

Prerequisites

  • A Yodlee developer account at developer.yodlee.com — Yodlee requires application registration and approval for production access; sandbox access is available for development
  • Yodlee API credentials: Client ID and Client Secret (provided upon application approval from the Yodlee developer portal)
  • Knowledge of which Yodlee API environment you are targeting: Sandbox (sandbox.api.yodlee.com) or Production (production.api.yodlee.com)
  • At least one Yodlee sandbox user with linked test accounts for development — create test users and link Dag Site bank accounts using Yodlee's sandbox test credentials
  • A Retool account with permission to create Resources, Configuration Variables, and Workflows

Step-by-step guide

1

Obtain Yodlee API credentials and understand the two-tier auth model

Register at developer.yodlee.com and create an application to receive your Yodlee API credentials: a Client ID and Client Secret. For development, Yodlee provides Sandbox access immediately after registration. Production access requires a business agreement and approval process. Once you have credentials, understand Yodlee's two-tier authentication before building anything in Retool — this architecture is fundamentally different from standard single-token APIs and must be handled correctly. Tier 1: Admin Token. Obtained by POSTing to the token endpoint with your Client ID and Client Secret using the client credentials OAuth grant. The admin token is valid for 30 minutes and is used ONLY for user management operations (creating users, getting user lists). It cannot access financial data. Tier 2: User JWT. To access any financial data (accounts, transactions, holdings) for a specific user, you must generate a user-level JWT. This requires a POST to the same token endpoint but including the Yodlee username for the specific user in the request body alongside the admin client credentials. The user JWT is also short-lived (typically 30 minutes). In Retool Settings → Configuration Variables, add: YODLEE_CLIENT_ID, YODLEE_CLIENT_SECRET, and YODLEE_API_BASE_URL (set to https://sandbox.api.yodlee.com/ysl for sandbox or https://production.api.yodlee.com/ysl for production). Mark Client Secret as secret. Token management will be handled by JavaScript queries in the app rather than by the resource configuration directly.

yodlee_admin_token_request.txt
1// Yodlee Admin Token Request — POST body (application/x-www-form-urlencoded)
2// POST to {base_url}/auth/token
3clientId={{ retoolContext.configVars.YODLEE_CLIENT_ID }}
4secret={{ retoolContext.configVars.YODLEE_CLIENT_SECRET }}

Pro tip: Yodlee's sandbox uses pre-built test users and test institutions (called 'Dag Sites'). Log in to your Yodlee developer portal to find the sandbox test credentials for linking bank accounts to your test users — these simulate real bank connections without requiring actual account credentials.

Expected result: You have Yodlee credentials stored in Retool Configuration Variables and understand the two-step token acquisition process required before making any financial data queries.

2

Create the Yodlee REST API Resource and token acquisition queries

In Retool, navigate to the Resources tab and Add Resource. Select REST API. Name it 'Yodlee API'. In the Base URL field, enter {{ retoolContext.configVars.YODLEE_API_BASE_URL }}. Because Yodlee's tokens are dynamic and short-lived (not static configuration values), use 'No Auth' as the authentication type in the resource — you will pass the token in individual query headers using dynamic references. In the Headers section, add a default header: Api-Version = 1.1 (required for all Yodlee requests). Click Save Changes. Now create token management queries in your Retool app. Open or create an app, then in the Code panel create a JavaScript query named 'getAdminToken'. This query POSTs to the Yodlee token endpoint and stores the result. Set the query type to JavaScript and write code that uses fetch() with Retool's built-in utilities to call the token endpoint. Alternatively, create a REST query named 'fetchAdminToken': select the Yodlee API resource, set Method to POST, Path to /auth/token, Body Type to x-www-form-urlencoded, and Body to clientId={{ retoolContext.configVars.YODLEE_CLIENT_ID }}&secret={{ retoolContext.configVars.YODLEE_CLIENT_SECRET }}. Create a second query named 'fetchUserToken' with the same configuration but add the loginName parameter: clientId={{ retoolContext.configVars.YODLEE_CLIENT_ID }}&secret={{ retoolContext.configVars.YODLEE_CLIENT_SECRET }}&loginName={{ userIdInput.value }}. The user token response contains an 'access_token' string — reference this token in subsequent financial data queries as a custom Authorization header: { Authorization: 'Bearer ' + fetchUserToken.data.token.accessToken }.

yodlee_user_token_request.txt
1// Yodlee User Token Request — form-encoded POST
2// Use loginName to get user-specific JWT
3// POST {base_url}/auth/token
4clientId={{ retoolContext.configVars.YODLEE_CLIENT_ID }}&secret={{ retoolContext.configVars.YODLEE_CLIENT_SECRET }}&loginName={{ userIdInput.value }}

Pro tip: Yodlee token responses nest the access token at data.token.accessToken. Always log the full response in the query's Results panel when setting up token queries to confirm the exact JSON path before referencing it in other queries.

Expected result: The fetchAdminToken and fetchUserToken queries successfully return Yodlee JWT tokens visible in the Results panel.

3

Build queries to retrieve accounts and balances

With token acquisition working, build the financial data queries. Create a new query named 'getAccounts', select the Yodlee API resource, set Method to GET, and Path to /accounts. In the Headers section of this specific query, add a custom header: Authorization = Bearer {{ fetchUserToken.data.token.accessToken }}. This passes the user-level JWT for the selected user — if the user token hasn't been fetched yet, set a run dependency: in the query's Advanced settings, under 'Run after query', select fetchUserToken. This ensures the user token is always fresh before the accounts query runs. Add a URL parameter: key 'container', value 'bank,creditCard,investment,insurance,loan' to retrieve all account types. The accounts response contains an 'account' array with objects including: id, accountName, accountNumber (masked), accountType, balance.amount, balance.currency, providerName, refreshInfo.lastRefreshed, and refreshInfo.statusCode. Create a transformer for the accounts query that extracts and normalizes this data, converting balance amounts to a consistent currency display format and calculating data freshness in hours. Create a second query 'getTransactions' with Method GET, Path /transactions, the same Authorization header dependency, and URL parameters: 'fromDate' = {{ dateRange.startDate }}, 'toDate' = {{ dateRange.endDate }}, 'accountId' = {{ accountsTable.selectedRow?.id || '' }}, 'top' = 100.

yodlee_accounts_transformer.js
1// Transformer: normalize Yodlee accounts response
2const accounts = data.account || [];
3return accounts.map(acct => {
4 const lastRefreshed = acct.refreshInfo?.lastRefreshed
5 ? new Date(acct.refreshInfo.lastRefreshed)
6 : null;
7 const hoursOld = lastRefreshed
8 ? Math.floor((Date.now() - lastRefreshed.getTime()) / (1000 * 60 * 60))
9 : null;
10 const statusCode = acct.refreshInfo?.statusCode;
11 const isHealthy = statusCode === 0 || statusCode === 801; // 0=ok, 801=ok_partial
12
13 return {
14 id: acct.id,
15 account_name: acct.accountName,
16 account_number: acct.accountNumber || 'N/A',
17 account_type: acct.accountType,
18 provider: acct.providerName,
19 balance: acct.balance
20 ? `${acct.balance.currency} ${acct.balance.amount.toFixed(2)}`
21 : 'N/A',
22 balance_amount: acct.balance?.amount || 0,
23 last_refreshed: lastRefreshed ? lastRefreshed.toLocaleString() : 'Never',
24 data_age_hours: hoursOld,
25 connection_status: isHealthy ? 'Healthy' : `Error (${statusCode})`
26 };
27});

Pro tip: Yodlee refresh status codes communicate connection health: 0 = success, 801 = partial data, 200-level = MFA/credential issues, 400-level = provider-side errors. Build a status code lookup table in your transformer to convert codes to human-readable messages for support operations.

Expected result: The getAccounts query returns a normalized list of financial accounts with balance, provider, refresh time, and connection health status.

4

Build the financial dashboard UI

With queries configured, build the dashboard. Add a Text Input component named 'userIdInput' at the top with label 'Yodlee User Login Name'. Add a 'Load Data' button that triggers fetchUserToken on click (which cascades to getAccounts via the query dependency). Below the user input, add a Stats row: total account count, total net assets (sum of positive balances), total liabilities (credit card and loan balances), and accounts with connection errors (count where connection_status is not 'Healthy'). Drag a Table component, bind it to {{ getAccounts.data }}, and configure columns: provider, account_name, account_type, balance, last_refreshed, data_age_hours (with conditional formatting: red text if > 24 hours), and connection_status (green for Healthy, red for Error). When a row is selected, trigger the getTransactions query via event handler. Add a second Table component below for transactions, bound to {{ getTransactions.data }}. Create a transformer for transactions that extracts: date, merchant name (from transaction.merchant.name or transaction.description), amount (positive for credits, negative for debits), category (from transaction.highLevelCategoryId or transaction.categoryId lookup), and base type (CREDIT or DEBIT). Add a Date Range Picker that controls the transaction query parameters. For fintech applications managing large user populations across multiple Yodlee accounts, RapidDev can help architect a scalable Retool solution with token caching and multi-user management.

yodlee_transactions_transformer.js
1// Transformer: normalize Yodlee transactions
2const transactions = data.transaction || [];
3return transactions.map(t => ({
4 id: t.id,
5 date: t.date,
6 description: t.merchant?.name || t.description || 'N/A',
7 amount: t.baseType === 'DEBIT'
8 ? -Math.abs(t.amount.amount)
9 : Math.abs(t.amount.amount),
10 currency: t.amount.currency,
11 category: t.categoryType || t.highLevelCategoryId || 'Uncategorized',
12 base_type: t.baseType,
13 account_id: t.accountId,
14 status: t.status
15}));

Pro tip: Yodlee transactions include a 'categoryType' field (TRANSFER, EXPENSE, INCOME, REPAYMENT, UNCATEGORIZE) and a more specific 'categoryId' that maps to Yodlee's 450+ transaction categories. Request the full category list from /transactions/categories to build a lookup map for human-readable category names.

Expected result: The financial dashboard shows account health status and balances in the accounts table, and transaction history for the selected account in the transactions table.

5

Implement token refresh automation with Retool Workflows

Yodlee tokens expire after 30 minutes, which means dashboards left open will eventually fail with 401 errors as tokens expire mid-session. Build an automatic refresh mechanism to keep the dashboard operational. Option 1 — In-app polling: Create a Timer component in Retool (drag from the component panel) and set it to run every 25 minutes. Connect its trigger event to run fetchUserToken (which automatically re-runs getAccounts and getTransactions via dependencies). This keeps the session active for as long as the app is open. Option 2 — Retool Workflow: For more robust token management in production, create a Retool Workflow. Set a schedule trigger at 25-minute intervals. Add a Resource Query block that POSTs to the Yodlee token endpoint using your admin credentials and stores the token in a Retool Database row keyed by user ID. In your Retool app, read the current token from Retool Database rather than calling the token endpoint directly. This decouples token management from the dashboard UI. Add error handling to both approaches: if a token fetch fails (network error or invalid credentials), display an error notification in the dashboard and disable query triggers to prevent cascading failures. Reference the access token in financial data query headers dynamically: in each query's Headers section, add Authorization = Bearer {{ fetchUserToken.data?.token?.accessToken || '' }}. The optional chaining (?.) prevents errors if the token query hasn't run yet.

token_validation_check.js
1// JavaScript: check token validity before running financial queries
2const tokenData = fetchUserToken.data?.token;
3if (!tokenData || !tokenData.accessToken) {
4 utils.showNotification({
5 title: 'Authentication Required',
6 description: 'Yodlee session expired. Re-enter user ID and click Load Data.',
7 type: 'warning'
8 });
9 return;
10}
11// Token valid — trigger dependent queries
12await getAccounts.trigger();
13await getTransactions.trigger();

Pro tip: Add Yodlee's 'issuedAt' timestamp from the token response to calculate exact token age: const issuedAt = new Date(tokenData.issuedAt); const expiresAt = new Date(issuedAt.getTime() + 30 * 60 * 1000). Display this as 'Session expires in X minutes' in your dashboard so operators know when they need to refresh.

Expected result: The dashboard automatically refreshes Yodlee tokens every 25 minutes and shows session status, preventing mid-session authentication failures.

Common use cases

Build a user financial account health monitor

Create a Retool panel that queries all Yodlee linked accounts for a specific user and displays account status, balance freshness, and provider connection health. Highlight accounts where Yodlee's data refresh has failed or data is older than 24 hours, enabling support teams to identify and assist users with connection issues without accessing the user's actual credentials.

Retool Prompt

Build a Retool dashboard that shows all Yodlee linked accounts for a given user ID — display account name, institution name, account type, current balance, last refresh time, and connection status. Color-code rows red if the last refresh is older than 24 hours or if the account status shows an error.

Copy this prompt to try it in Retool

Build a transaction analysis and categorization review panel

Create a Retool financial analysis panel that queries Yodlee transactions for a user across all linked accounts. Display transactions in a filterable Table with Yodlee's merchant categorization, normalized transaction amounts, and merchant names. Include a date range selector, category filter, and spending totals by category shown in a Pie Chart.

Retool Prompt

Build a Retool panel querying Yodlee transactions for a user ID across all accounts in a date range. Show a Table with merchant name, amount, date, and Yodlee category. Include a Pie Chart of spending by category and a date range picker to filter the transaction window.

Copy this prompt to try it in Retool

Build a portfolio holdings and net worth dashboard

Create a Retool investment dashboard that queries Yodlee holdings data for investment accounts, displaying securities by type, quantity, value, and percentage of total portfolio. Show net worth across all account types (checking, savings, investment, credit) in summary cards, and chart portfolio allocation by asset class.

Retool Prompt

Build a Retool portfolio dashboard pulling Yodlee holdings for investment accounts — show a Table of securities with symbol, quantity, current value, and allocation %. Display total net worth across all account types in Stats components at the top.

Copy this prompt to try it in Retool

Troubleshooting

Admin token request returns 400 Bad Request or 'Invalid clientId/secret'

Cause: Yodlee's token endpoint requires credentials in application/x-www-form-urlencoded format with exact field names 'clientId' and 'secret'. Sending JSON body or using incorrect parameter names (e.g., 'client_id' instead of 'clientId') causes a 400 error. Sandbox and production credentials are separate — using sandbox credentials against the production URL also causes this error.

Solution: Set the query Body Type to x-www-form-urlencoded (not JSON) and verify the field names are exactly 'clientId' and 'secret' (camelCase). Confirm that the YODLEE_API_BASE_URL configuration variable matches your credentials environment: https://sandbox.api.yodlee.com/ysl for sandbox or https://production.api.yodlee.com/ysl for production. Test with the exact URL and body in the query Results panel before referencing in other queries.

Financial data queries return 401 Unauthorized despite having a valid admin token

Cause: Yodlee financial data endpoints (accounts, transactions, holdings) require a USER-level JWT, not the admin token. The admin token only authorizes user management operations. Using the admin token to access financial data will always return 401.

Solution: Create a separate fetchUserToken query that includes the 'loginName' parameter of the specific user in the token request body alongside client credentials. Reference the resulting user-level access token (at data.token.accessToken) in the Authorization header of all financial data queries. Never use the admin token directly for financial data access.

typescript
1// Correct Authorization header for financial data queries
2// Use user token, NOT admin token
3Authorization: Bearer {{ fetchUserToken.data.token.accessToken }}

getAccounts returns empty account array for a user that has linked accounts

Cause: Yodlee's sandbox uses specific test user IDs and test institutions. If the user login name does not match an existing Yodlee user in your environment, or if the user has no linked accounts, the accounts endpoint returns an empty array. Real user accounts also return no data if they have not completed the linking process through Yodlee FastLink.

Solution: Verify the user login name in the Yodlee developer portal under your application's user list. For sandbox testing, use Yodlee's pre-created test users with pre-linked Dag Site bank accounts. Confirm that the user has actually linked accounts by checking the Yodlee developer console or calling the /providers/accounts endpoint to see linked provider accounts before querying /accounts.

Transaction query returns data but amounts appear as positive for both debits and credits

Cause: Yodlee transaction amounts are always returned as positive numbers. The transaction direction is indicated by the 'baseType' field: 'DEBIT' for money leaving the account and 'CREDIT' for money entering. Without checking baseType, all amounts appear positive regardless of whether they are expenses or income.

Solution: Apply baseType-based sign logic in your transformer: amount = t.baseType === 'DEBIT' ? -Math.abs(t.amount.amount) : Math.abs(t.amount.amount). Display debits in red and credits in green using conditional table column formatting in Retool.

typescript
1// Apply correct sign to Yodlee transaction amounts
2const signedAmount = t.baseType === 'DEBIT'
3 ? -Math.abs(t.amount.amount)
4 : Math.abs(t.amount.amount);

Best practices

  • Store Yodlee Client ID and Client Secret in Retool Configuration Variables marked as secret — these credentials provide admin-level access to all user financial data in your Yodlee environment and must be treated with the same security as database root credentials
  • Never cache Yodlee financial data for more than 30 minutes — Yodlee tokens expire at 30 minutes, so cached data beyond this window may have been fetched with an already-expired token; refresh on every session start
  • Implement token expiry detection in all financial data queries: check for 401 responses and automatically trigger fetchUserToken before retrying — do not rely solely on the 30-minute refresh timer
  • Use Yodlee's refresh status codes to communicate account health to end users: code 0 means data is current, codes in the 400-800 range indicate connection issues requiring user action (MFA challenge, credential re-entry)
  • Always display Yodlee's 'lastRefreshed' timestamp alongside balance data — financial data ages quickly and users must understand that Retool displays the last synced balance from Yodlee, not necessarily the current account balance
  • For production Retool apps accessing real user financial data, implement Retool's user-level access controls so operators only see data for users assigned to their support queues — financial data carries significant privacy obligations
  • Use Retool Workflows rather than in-app JavaScript for token refresh logic in production — Workflows provide centralized token management, retry handling, and audit logging that is harder to implement reliably in app-level queries

Alternatives

Frequently asked questions

What is the difference between Yodlee and Plaid for a Retool integration?

Yodlee is an enterprise-grade financial aggregation platform with coverage of 17,000+ global institutions and a complex two-tier authentication model, making it suitable for larger fintech operations requiring broad international coverage. Plaid is more developer-friendly with simpler single-token authentication, better documentation, and faster onboarding — preferred for startups and US-focused financial applications. Yodlee's API requires significantly more setup in Retool but provides broader institutional coverage and enterprise-level SLAs.

How do I access Yodlee sandbox for testing the Retool integration?

Register at developer.yodlee.com to receive sandbox API credentials. Yodlee's sandbox includes pre-built test users with linked accounts at simulated 'Dag Site' financial institutions that respond with test data. Log in to your developer portal to find test user login names and Dag Site institution credentials. Use the sandbox base URL (https://sandbox.api.yodlee.com/ysl) with your sandbox Client ID and Secret. Create additional test users via the /user/register endpoint using your admin token.

Why does Yodlee require two separate authentication tokens?

Yodlee's two-tier model separates administrative capabilities from data access to enforce the principle of least privilege. The admin token (client credentials grant) authorizes application-level operations like creating users. The user-level JWT is scoped specifically to one user's financial data — it cannot access other users' data, even with the same credentials. This architecture means a compromised user token exposes only that user's data, not the entire platform.

How do I handle Yodlee's MFA and re-authentication challenges in Retool?

When a linked bank account requires MFA or credential re-entry (indicated by refresh status codes in the 400-range), Yodlee expects users to go through their FastLink widget — a hosted UI for re-authentication that you cannot replicate in a Retool query. In your Retool dashboard, detect these status codes in the accounts transformer and display a message directing the user to your FastLink integration URL to re-authenticate their account. Retool is not the right interface for Yodlee's interactive re-authentication flows.

Can I use Yodlee to display real-time account balances in Retool?

Yodlee's balance data reflects the last time Yodlee synced with the financial institution — it is not real-time. Refresh intervals depend on your Yodlee plan and the institution's API capabilities: typically every few hours for most banks. You can trigger an on-demand refresh via the /providerAccounts/{id} PUT endpoint with action=REFRESH, but Yodlee processes this asynchronously. Check the refreshInfo.lastRefreshed timestamp in the accounts response to show users when balance data was last updated, and display this prominently in your Retool dashboard.

RapidDev

Talk to an Expert

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

Book a free consultation

Integrations are where projects stall

We wire Retool integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

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.