Connect Retool to the Binance API using a REST API Resource. Binance requires HMAC-SHA256 request signing for private endpoints — use a Retool JavaScript query to generate the signature, then pass it as a query parameter. Build crypto portfolio monitoring dashboards with account balances, order history, and live price data.
| Fact | Value |
|---|---|
| Tool | Binance API |
| Category | Payment |
| Method | REST API Resource |
| Difficulty | Advanced |
| Time required | 45 minutes |
| Last updated | April 2026 |
Build a Binance Trading Dashboard in Retool
Binance's API is one of the most feature-rich in the cryptocurrency space, but its HMAC signing requirement makes it more complex to integrate than APIs with simple bearer tokens. The signing requirement exists because unauthorized access to a Binance trading account could result in financial loss — the signature proves each request was generated by someone who possesses the API secret key without transmitting the secret itself.
Retool handles this in two layers: a REST API Resource configured with your API key handles the base URL and API key header (needed even for public endpoints), while a JavaScript query generates the required HMAC-SHA256 signature for private endpoints using Retool's built-in CryptoJS library. This architecture keeps the API secret secure in Retool's configuration variables while generating valid signed requests at query time.
Binance distinguishes between market data endpoints (public, no signing required) and account/trading endpoints (private, signing required). Public endpoints cover price data, order books, and candlestick charts. Private endpoints cover account balances, open orders, trade history, and order placement. This tutorial covers both types with appropriate security for each.
Integration method
Binance's API has two endpoint types: public endpoints (market data) require only an API key header, while private endpoints (account, orders) require HMAC-SHA256 signature generation. Retool handles public endpoints with a standard REST API Resource. Private endpoints require a JavaScript query that generates the HMAC signature before calling the API. All requests are proxied server-side through Retool.
Prerequisites
- A Binance account with API access enabled (available on all account types)
- A Binance API key and secret key generated in Binance account settings
- API key permissions configured for 'Read Info' at minimum (Enable Trading for order management)
- IP restrictions configured on the API key for security (restrict to your Retool server IP)
- A Retool account with permission to create Resources and write JavaScript queries
Step-by-step guide
Generate Binance API credentials with appropriate permissions
Log into Binance and navigate to your Profile → API Management. Click 'Create API'. Choose 'System generated' for key type. Name the API key descriptively (e.g., 'Retool Portfolio Dashboard'). On the next screen, configure permissions: 'Enable Reading' is required for all dashboard use cases, 'Enable Spot & Margin Trading' is needed only if you want to place or cancel orders from Retool. For security, enable IP access restriction and add your Retool server's IP address — if using Retool Cloud, add Retool's IP ranges (35.90.103.132/30 and 44.208.168.68/30 for US region). Binance displays the API Key and Secret Key once. Copy both immediately — the Secret Key cannot be retrieved after leaving this page. Store them in Retool's configuration variables marked as secrets. For read-only dashboards, never enable withdrawal permissions on API keys used by Retool.
Pro tip: Always restrict Binance API keys to the minimum permissions needed. A dashboard that only reads portfolio data should use a Read-only key with IP restrictions. Never enable withdrawal permissions on Retool integration keys.
Expected result: You have a Binance API Key and Secret Key stored in Retool configuration variables (BINANCE_API_KEY and BINANCE_SECRET_KEY).
Configure the Binance REST API Resource
Create a REST API Resource in Retool for Binance's public market data. Go to Resources → Create New → REST API. Set the Base URL to 'https://api.binance.com'. Under Headers, add: 'X-MBX-APIKEY' with value '{{ retoolContext.configVars.BINANCE_API_KEY }}'. This API key header is required even for market data endpoints. The secret key is NOT added to the resource header — it is only used to generate HMAC signatures in JavaScript queries and should never appear in headers or URLs. Name the resource 'Binance API' and save. Test the connection by creating a temporary GET query to '/api/v3/ping' — a successful response returns an empty JSON object {}. Then test market data with GET '/api/v3/ticker/price?symbol=BTCUSDT' which returns the current BTC price.
1{2 "Base URL": "https://api.binance.com",3 "Headers": {4 "X-MBX-APIKEY": "{{ retoolContext.configVars.BINANCE_API_KEY }}"5 }6}Pro tip: Binance has multiple API base URLs for different regions and testnet. Use api.binance.com for production. For testing, use testnet.binance.vision with testnet credentials obtained from testnet.binance.vision.
Expected result: The Binance Resource is saved. A test query to /api/v3/ping returns {} with a 200 status. A query to /api/v3/ticker/price returns current BTC price data.
Create a signed request for private account endpoints
Private Binance endpoints require HMAC-SHA256 signing. The signature is computed by concatenating all query parameters as a string and signing it with your Secret Key using HMAC-SHA256. The timestamp parameter is mandatory and must be within 5000ms of Binance's server time. In Retool, create a new JavaScript query (no resource needed) that builds the signed request. The query uses Retool's built-in utils.hmac() function (available in newer Retool versions) or the CryptoJS library available in JavaScript queries. The signature is appended as a 'signature' query parameter to the request. Then the query calls another Retool resource query with the signed parameters. This two-query pattern (sign → fetch) is the standard approach for Binance private endpoints in Retool.
1// JavaScript query: build signed Binance request2// This query generates the HMAC signature and calls the account endpoint34const apiSecret = retoolContext.configVars.BINANCE_SECRET_KEY;5const timestamp = Date.now();67// Build query string for account balances endpoint8const queryString = `timestamp=${timestamp}&recvWindow=5000`;910// Generate HMAC-SHA256 signature using CryptoJS11// CryptoJS is available in Retool JavaScript queries12const signature = CryptoJS.HmacSHA256(queryString, apiSecret).toString(CryptoJS.enc.Hex);1314// Return the complete signed URL parameters15return {16 queryString: queryString,17 signature: signature,18 timestamp: timestamp19};Pro tip: Binance server time may differ from your client time. If you get 'Timestamp for this request is outside of the recvWindow' errors, add a second query to GET /api/v3/time to get Binance's server timestamp and use that instead of Date.now().
Expected result: The JavaScript query runs successfully and returns an object with queryString, signature, and timestamp values.
Query account balances with the signed request
Create a second query using the Binance Resource to fetch account data, but this query depends on the signature generated in the previous step. Set the method to GET and path to '/api/v3/account'. In the query parameters section, add: 'timestamp' bound to {{ generateSignature.data.timestamp }}, 'recvWindow' set to '5000', and 'signature' bound to {{ generateSignature.data.signature }}. Set this query to run 'Manually' and configure it to trigger after the generateSignature query succeeds. The response contains a 'balances' array where each item has 'asset' (coin symbol), 'free' (available balance), and 'locked' (in open orders). Add a transformer to filter out zero balances and enrich each asset with current USD price by joining with a price ticker query.
1// GET /api/v3/account2// Query parameters:3// timestamp: {{ generateSignature.data.timestamp }}4// recvWindow: 50005// signature: {{ generateSignature.data.signature }}67// Transformer: filter and format account balances8const balances = data.balances || [];9const nonZero = balances.filter(b =>10 parseFloat(b.free) > 0 || parseFloat(b.locked) > 011);1213return nonZero.map(b => ({14 asset: b.asset,15 free: parseFloat(b.free),16 locked: parseFloat(b.locked),17 total: parseFloat(b.free) + parseFloat(b.locked)18})).sort((a, b) => b.total - a.total);Pro tip: Stablecoins (USDT, BUSD, USDC) have a total in USD equal to their quantity. For other assets, you need to multiply by the current price. Fetch all prices in one call using GET /api/v3/ticker/price (no signature required) and join the results.
Expected result: The account query returns all non-zero balances. The Table shows each coin with free and locked quantities sorted by total holdings.
Add market price data and portfolio value chart
Create a public (unsigned) query to fetch all current prices from Binance. Use GET method with path '/api/v3/ticker/price' and no query parameters — this returns prices for all trading pairs. The response is an array of {symbol, price} objects. In a JavaScript query, join the account balances with prices to calculate USD value for each asset. Create a portfolio summary object with total USD value and per-asset allocation percentages. Bind a Pie Chart component to the allocation data and display the total portfolio value as a Statistic component. Add a 24-hour change chart using the /api/v3/ticker/24hr endpoint which includes priceChangePercent for each symbol.
1// JavaScript query: calculate portfolio USD values2// Depends on: getAccountBalances.data and getPrices.data34const balances = getAccountBalances.data || [];5const prices = getPrices.data || [];67// Build price lookup map (only USDT pairs)8const priceMap = {};9prices.forEach(p => {10 if (p.symbol.endsWith('USDT')) {11 const asset = p.symbol.replace('USDT', '');12 priceMap[asset] = parseFloat(p.price);13 }14});15// Stablecoins16['USDT', 'BUSD', 'USDC', 'DAI'].forEach(s => priceMap[s] = 1);1718const portfolio = balances.map(b => ({19 asset: b.asset,20 total: b.total,21 usd_price: priceMap[b.asset] || 0,22 usd_value: b.total * (priceMap[b.asset] || 0)23})).filter(b => b.usd_value > 0.01);2425const totalUSD = portfolio.reduce((sum, b) => sum + b.usd_value, 0);2627return portfolio.map(b => ({28 ...b,29 usd_value: `$${b.usd_value.toFixed(2)}`,30 allocation_pct: totalUSD > 031 ? `${((b.usd_value / totalUSD) * 100).toFixed(1)}%`32 : '0%'33})).sort((a, b) => parseFloat(b.usd_value.slice(1)) - parseFloat(a.usd_value.slice(1)));Pro tip: Cache the price ticker query for 30-60 seconds to avoid hitting Binance's rate limits when the portfolio dashboard refreshes frequently. Public market data endpoints have a generous but finite rate limit (1200 requests per minute weight limit).
Expected result: The portfolio dashboard displays each asset's USD value, a pie chart of portfolio allocation, and total portfolio value. Data refreshes on demand without requiring page reload.
Common use cases
Build a crypto portfolio monitoring dashboard
Display all account balances with current USD values using live Binance price data. Show portfolio allocation as a pie chart and track total portfolio value over time. Include a table of recent trades with PnL calculations for each position, giving traders a comprehensive view of their Binance holdings.
Build a Retool dashboard that queries Binance account balances, fetches current prices for each held asset, calculates USD value, and shows a portfolio breakdown pie chart plus total portfolio value with 24-hour change.
Copy this prompt to try it in Retool
Create an open orders management panel
Display all open orders across trading pairs with current market price comparison. Show filled percentage for partial fills, average fill price, and time since order placement. Build an operations panel where traders can cancel specific orders or bulk-cancel all orders for a trading pair from Retool.
Create a Retool order management panel showing all open Binance orders with order type, placed price, current market price, and a cancel button that calls the DELETE /api/v3/order endpoint for the selected order.
Copy this prompt to try it in Retool
Build a trade history and performance analytics panel
Query trade history for specified trading pairs and calculate performance metrics: total volume traded, win/loss ratio, average trade size, and most active trading hours. Display time-series charts of trade frequency and cumulative PnL to identify trading patterns.
Build a Retool trade analytics panel that queries the last 500 trades for BTC/USDT, calculates win rate by comparing buy price to next sell price, shows a histogram of trade sizes, and displays cumulative PnL over time.
Copy this prompt to try it in Retool
Troubleshooting
Private endpoint returns -1022 error: 'Signature for this request is not valid'
Cause: The HMAC-SHA256 signature does not match Binance's expected value. Common causes: the query string parameters are in a different order than expected, extra whitespace in the secret key, or the timestamp used for signing differs from the timestamp in the request.
Solution: Verify the query string used for signing exactly matches the URL parameters sent in the request — parameter order matters. Check the BINANCE_SECRET_KEY configuration variable for leading or trailing whitespace. Log the queryString and signature in the JavaScript query to verify the values match what is being sent in the API call.
1// Debug: log the exact query string being signed2console.log('Query string:', queryString);3console.log('Signature:', signature);4console.log('Timestamp:', timestamp);Private endpoint returns -1021 error: 'Timestamp for this request is outside of the recvWindow'
Cause: Your system clock differs from Binance's server time by more than the recvWindow value (default 5000ms). This is common when Retool runs in cloud environments where the system clock drifts.
Solution: First, query GET /api/v3/time to get Binance's server timestamp. Use that value instead of Date.now() in the signature generation. Set recvWindow to a larger value (up to 60000ms = 1 minute) to allow for more clock skew, though larger windows reduce security.
1// Get Binance server time instead of local Date.now()2// Add a query: GET /api/v3/time3// Then in signature generation:4const timestamp = getBinanceTime.data.serverTime;Retool gets 403 Forbidden even with correct API key and signature
Cause: The Binance API key has IP restrictions enabled and the request is coming from an IP address not on the allowlist. Retool Cloud uses specific IP ranges that may not be on your key's allowlist.
Solution: Add Retool Cloud's IP ranges to your Binance API key's IP restriction allowlist: 35.90.103.132/30 and 44.208.168.68/30 for US West region. Alternatively, temporarily remove IP restrictions to confirm this is the cause, then re-add with the correct IPs. For self-hosted Retool, add your server's public IP.
Account query returns empty balances array
Cause: The account has no holdings, or the API key does not have 'Enable Reading' permission enabled. Also possible: the signature was generated for one endpoint but sent to a different endpoint.
Solution: Verify in Binance API Management that the key has 'Enable Reading' enabled. Check that the API key used in the resource header matches the one generating the signature — using different keys for these two steps causes authentication failures. Temporarily test with GET /api/v3/account directly in Postman with the same credentials.
Best practices
- Store BINANCE_SECRET_KEY in Retool configuration variables as a secret — it must never appear in resource headers, query URLs, or be logged anywhere
- Use read-only API keys (Enable Reading only) for monitoring dashboards — only enable trading permissions if your Retool app actually places orders
- Always set IP restrictions on Binance API keys to Retool's IP ranges or your server's IP — an unrestricted key with account access is a significant security risk
- Never enable withdrawal permissions on API keys used in Retool — dashboard functionality does not require it, and enabling it creates unnecessary financial risk
- Cache public market data endpoints (ticker prices, candlestick data) for 30-60 seconds — these change rapidly but Binance's rate limits apply per second across all requests
- Handle signature generation failures gracefully — if the JavaScript signature query fails, the downstream account query should show an informative error rather than a raw API error
- Use Binance's testnet (testnet.binance.vision) with separate test credentials during Retool app development to avoid any risk to production account data
Alternatives
Coinbase uses simpler OAuth 2.0 or API key authentication without HMAC signing, making it faster to integrate for teams building portfolio tracking tools for retail users.
Robinhood's API is simpler but less officially documented, making it better suited for personal portfolio tracking than enterprise-grade trading dashboards.
Plaid provides a unified financial data API that aggregates balances across multiple exchanges and bank accounts, better suited for holistic portfolio views beyond a single exchange.
Frequently asked questions
Can I place trades on Binance from Retool?
Yes, but this requires enabling 'Enable Spot & Margin Trading' on your API key and implementing order placement queries using POST /api/v3/order with HMAC signing. Be extremely careful building trading functionality in Retool — unintended button clicks or query auto-runs could place real orders. Always add confirmation modals and disable the trading key's withdrawal permissions.
Why does Binance require HMAC signing instead of just an API key?
HMAC signing provides request integrity — each request contains a timestamp and signature that proves it was created by someone with the secret key at a specific time. This prevents replay attacks where an intercepted request could be re-submitted. A plain API key in a header provides authentication but not integrity, which is insufficient security for financial APIs.
How do I get historical price data (candlestick charts) from Binance?
Use GET /api/v3/klines with parameters: symbol (e.g., BTCUSDT), interval (1m, 5m, 1h, 1d, etc.), and optionally startTime and endTime as Unix timestamps in milliseconds. This is a public endpoint requiring no HMAC signature. The response is a 2D array where each element represents a candlestick with open time, open, high, low, close, and volume values.
What are Binance's API rate limits?
Binance uses a weight-based rate limiting system. Each endpoint has a 'weight' value, and you are limited to 1200 weight units per minute for most endpoints. Account queries have higher weights (10-40) than market data queries (1-5). Check the X-MBX-USED-WEIGHT-1M response header to monitor your current usage. Exceeding limits returns a 429 status, and repeated violations result in IP bans.
Can I access Binance Futures data from Retool?
Yes. Binance Futures has a separate API at fapi.binance.com (USDT-margined) or dapi.binance.com (coin-margined). Create a separate Retool Resource with the futures base URL. Futures private endpoints use the same HMAC signing pattern as spot endpoints, but you need separate API key permissions for futures access enabled in Binance API settings.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation