Skip to main content
Skip to main content

Finnhub Connector

Building multi-asset charts (US stocks, forex, crypto) with institutional-grade market data? The Finnhub connector wraps the Finnhub API and implements the same DataAdapter contract as Twelve Data and Massive.

Loading chart…

Use the controls above to switch asset class, symbol, and timeframe. This docs demo routes requests through /api/finnhub so your API token stays on the server.

Standalone demo

Full-page version with sample code: Finnhub live demo.

API token required

Finnhub requires an API token in production. Store it in FINNHUB_API_KEY and run the adapter on your server or behind a proxy — never ship the token in a browser bundle. For local docs demos, add the key to apps/docs/.env.local.

Free tier candle access

Finnhub's free plan includes real-time stock quotes (/quote) but not /stock/candle, /forex/candle, or /crypto/candle. The docs proxy falls back to quote-derived demo candles when candle endpoints return access errors. For production OHLCV, subscribe to a Finnhub market data plan.

What you get

FeatureDetails
StocksUS tickers (AAPL, SPY, QQQ)
ForexOANDA symbols (OANDA:EUR_USD; also accepts EUR/USD)
CryptoExchange-prefixed (BINANCE:BTCUSDT)
History*/candle endpoints with parallel OHLCV arrays
Live ticks/quote (stocks) + WebSocket trades (wss://ws.finnhub.io)

Perfect for wealth apps, fintech dashboards, and multi-asset prototypes.

Finnhub vs Twelve Data / Massive

FinnhubTwelve DataMassive
Symbol formatAAPL, OANDA:EUR_USD, BINANCE:BTCUSDTEUR/USD, BTC/USDAAPL, C:EURUSD, X:BTCUSD
Free tierQuotes + fundamentals; candles need paid plandemo key with candlesTrial with candles
WebSocketSingle URL + tokenSingle URL + apikeyPer-market endpoints
Best forFundamentals-rich fintechQuick multi-asset demoUS stocks production

Licensing

TierTypical use
FreeDevelopment, quotes, company data
PaidProduction OHLCV candles and external display

Check Finnhub pricing before shipping to end users.

Install

npm install @efixdata/exeria-chart @efixdata/connector-finnhub

Minimal example (Node.js)

import { createChart } from "@efixdata/exeria-chart";
import { FinnhubAdapter } from "@efixdata/connector-finnhub";

const connector = new FinnhubAdapter({
apiKey: process.env.FINNHUB_API_KEY!,
});

const chart = createChart({
container,
dataAdapter: connector,
});

chart.init();

await chart.loadData("AAPL", {
interval: "1d",
limit: 500,
});

chart.subscribeToUpdates("AAPL", (tick) => {
console.log("Last price:", tick.price ?? tick.c);
});

Step by step

1 — Get an API token

Sign up at finnhub.io, copy your API token, and store it securely:

export FINNHUB_API_KEY=your_token_here

2 — Create the connector

const connector = new FinnhubAdapter({
apiKey: process.env.FINNHUB_API_KEY!,
});

3 — Attach to the chart

const chart = createChart({ container, dataAdapter: connector });
chart.init();

4 — Load history

await chart.loadData("AAPL", {
interval: "1d",
limit: 500,
});
OptionMeaning
interval"1m", "5m", "1h", "1d", "1w", "1M" (mapped to Finnhub resolution)
limitRecent N candles (max 5000)
from / toOptional Date range (converted to Unix seconds)

5 — Go live

chart.subscribeToUpdates("AAPL");

Uses Finnhub WebSocket trade stream. Stocks update during US market hours; crypto (BINANCE:BTCUSDT) trades 24/7.

6 — Clean up

chart.unsubscribeFromUpdates();
await connector.disconnect();

Symbol formats

AssetInput examplesFinnhub symbol
StockAAPL, MSFTAAPL
ForexEUR/USD, EURUSDOANDA:EUR_USD
CryptoBTCUSDT, BINANCE:BTCUSDTBINANCE:BTCUSDT

Next.js API route (browser-safe pattern)

// app/api/market/ohlcv/route.ts
import { FinnhubAdapter } from "@efixdata/connector-finnhub";
import { NextResponse } from "next/server";

const connector = new FinnhubAdapter({
apiKey: process.env.FINNHUB_API_KEY!,
});

export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const symbol = searchParams.get("symbol") ?? "AAPL";
const interval = searchParams.get("interval") ?? "1d";
const limit = Number(searchParams.get("limit") ?? "500");

await connector.initialize({});
const candles = await connector.getHistoricalData(symbol, { interval, limit });

return NextResponse.json({ candles });
}

Configuration

const connector = new FinnhubAdapter({
apiKey: process.env.FINNHUB_API_KEY!,
baseUrl: "https://finnhub.io/api/v1",
defaultForexExchange: "OANDA",
defaultCryptoExchange: "BINANCE",
pollIntervalMs: 3000,
requestTimeout: 10000,
maxRetries: 3,
onError: (error) => console.error("Finnhub error:", error),
});

Limits to know

TopicLimit
Rate limits60 calls/min on free tier
no_dataNarrow the date range; intraday free history is limited
Candle accessRequires paid market data subscription
BrowserUse a backend proxy; do not expose apiKey client-side

What is next?