Daily OHLCV price history for a stock, the latest close and volume for up to 25 tickers at once, technical indicators computed from those same daily bars, and the stocks most correlated with one stock's daily returns. The stored prices are in US dollars and newest-first. Zero-volume carry-forward candles are excluded from every customer-facing daily-price calculation because they do not establish a traded market price. open, high, low, and close are as traded. adjustedClose is the provider's stored adjusted value; captured splits and cash dividends trigger a full-history refresh, but the returned rows do not certify one consistent split basis or total-return series. Class shares use a dash (BRK-B); the dot form (BRK.B) is also accepted. Those endpoints serve end-of-day bars; /v1/stocks/{ticker}/quote and /v1/quotes serve the latest available intraday reading instead.
Every authoritative US-listed symbol has its own price identity. GOOG and GOOGL, or BRK-A and BRK-B, return independent daily bars, latest prices, live quotes, technical indicators, and correlation inputs. Active exchange-traded products are classified from the market-data reference directory and attached to their exact SEC filer identity; ticker or name patterns never decide coverage. A newly discovered ETF can answer the live-quote endpoints immediately, while its stored daily history appears as the grouped daily feed seeds current bars and the historical fetch completes. If the requested listing has no reading yet, the API reports that listing as unavailable; it never substitutes a sibling share class or another series from the same filer.
/v1/stocks/
Daily open, high, low, close, adjusted close, and positive share volume for one stock, newest first. Zero-volume carry-forward candles are omitted.
Parameters: {ticker} (exact listed symbol — e.g. NVDA, GOOG, GOOGL, or BRK-A); startDate / endDate (yyyy-MM-dd); limit (default 260, max 500); offset.
curl "https://api.equibles.com/v1/stocks/NVDA/prices?limit=2" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/prices?limit=2",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/prices?limit=2", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"data": [
{ "date": "2026-07-10", "open": 202.0, "high": 211.0, "low": 201.92, "close": 210.96, "adjustedClose": 210.96, "volume": 148124000 },
{ "date": "2026-07-09", "open": 204.46, "high": 204.59, "low": 198.96, "close": 202.78, "adjustedClose": 202.78, "volume": 132037400 }
],
"meta": { "limit": 2, "offset": 0, "count": 2, "hasMore": true }
}
/v1/prices/latest
The latest close, volume, and trailing 52-week range for up to 25 tickers in one call — pass a comma-separated tickers list. Each row is that ticker's newest settled bar with positive volume; zero-volume carry-forward candles cannot become the latest row or enter the range. Shortly after a US close some tickers may still show the prior session while the fresh bar settles, so anchor on each row's date, not the wall clock. high52Week/low52Week are the highest and lowest daily closes in the 365 days ending on the row's date — closing extremes only, never intraday highs and lows, and not dividend-adjusted. An intraday high can exceed the closing high, an intraday low can fall below the closing low, and dividend adjustments can lower historical endpoints without either source being wrong. If that year crosses a captured split for the exact listing, the comparison begins at the latest split because stored raw bars do not identify their basis; range52WeekIsPartial is true and range52WeekNote explains the boundary. A recent listing with less than a year of stored history is also partial. range52WeekStartDate always identifies the oldest close actually compared, and all three range metadata fields are absent or null when no range exists. previousClose, change and changePercent carry the one-session move so you do not have to fetch each ticker's history separately; all three are absent rather than wrong when the stored series skips the immediately prior session or a captured split separates it from the latest bar. A symbol that doesn't resolve doesn't fail the call — it comes back in the top-level notFound array while the rest of the batch still returns rows.
Parameters: tickers (required — comma-separated exact listed symbols, up to 25, e.g. GOOG,GOOGL,BRK-A,BRK-B).
curl "https://api.equibles.com/v1/prices/latest?tickers=NVDA,AMD,MSFT" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/prices/latest",
params={"tickers": "NVDA,AMD,MSFT"},
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/prices/latest?tickers=NVDA,AMD,MSFT", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"data": [
{ "ticker": "NVDA", "date": "2026-08-07", "close": 223.96, "adjustedClose": 223.96, "volume": 105473700,
"previousClose": 218.99, "change": 4.97, "changePercent": 2.2695,
"high52Week": 235.74, "low52Week": 165.17, "changeFrom52WeekHighPercent": -5.0,
"changeFrom52WeekLowPercent": 35.59, "range52WeekIsPartial": false,
"range52WeekStartDate": "2025-08-07" },
{ "ticker": "AMD", "date": "2026-08-10", "close": 469.56, "adjustedClose": 469.56, "volume": 19283602,
"previousClose": 483.36, "change": -13.8, "changePercent": -2.855,
"high52Week": 580.91, "low52Week": 151.14, "changeFrom52WeekHighPercent": -19.17,
"changeFrom52WeekLowPercent": 210.68, "range52WeekIsPartial": false,
"range52WeekStartDate": "2025-08-11" }
],
"notFound": []
}
/v1/stocks/
The latest available intraday quote for one active US listing — including exchange-traded products — rather than a daily bar. source is WebSocket for a real-time reading or Rest for a 15-minute-delayed one, and delayed says the same thing as a boolean; asOf is when the reading was produced. sessionDate is the US market session containing that trade, while expectedSessionDate is the session a current reading should belong to at response time. stale is true when the trade predates that expected session; never present such a row as the current price. ageSeconds gives its wall-clock age for callers with a stricter policy. bidPrice/askPrice are null unless the feed carries quotes. A listing with no live reading returns 404 rather than a placeholder price, so use /v1/stocks/{ticker}/prices for the most recent traded close when available.
Parameters: {ticker} (path — e.g. NVDA).
curl "https://api.equibles.com/v1/stocks/NVDA/quote" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/quote",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/quote", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"price": 205.1,
"bidPrice": null,
"askPrice": null,
"asOf": "2026-07-24T19:10:00.2758742Z",
"sessionDate": "2026-07-24",
"expectedSessionDate": "2026-07-24",
"stale": false,
"ageSeconds": 900,
"source": "Rest",
"delayed": true
}
/v1/quotes
The latest available intraday quote for up to 25 active US listings in one call — pass a comma-separated tickers list. Same reading and explicit session-staleness fields as /v1/stocks/{ticker}/quote. Every member must be a valid 1–32 character ticker made from letters, numbers, dots, or dashes; one invalid member rejects the whole request. Tickers with no live reading are omitted from data rather than returned with a placeholder price, so compare the returned tickers against the ones you asked for.
Parameters: tickers (required) — comma-separated list of up to 25 symbols.
curl "https://api.equibles.com/v1/quotes?tickers=NVDA,AAPL" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/quotes",
params={"tickers": "NVDA,AAPL"},
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/quotes?tickers=NVDA,AAPL", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"data": [
{ "ticker": "NVDA", "price": 205.1, "bidPrice": null, "askPrice": null, "asOf": "2026-07-24T19:10:00.2758742Z", "sessionDate": "2026-07-24", "expectedSessionDate": "2026-07-24", "stale": false, "ageSeconds": 900, "source": "Rest", "delayed": true },
{ "ticker": "AAPL", "price": 332.595, "bidPrice": null, "askPrice": null, "asOf": "2026-07-24T19:10:01.6630785Z", "sessionDate": "2026-07-24", "expectedSessionDate": "2026-07-24", "stale": false, "ageSeconds": 899, "source": "Rest", "delayed": true }
]
}
/v1/stream
A WebSocket that pushes a live quote every time one of your subscribed tickers ticks, instead of you polling /v1/quotes. Connect with wss://, authenticate the handshake exactly like any other request, then send {"action":"subscribe","tickers":["NVDA"]}. Subscribing replays the latest reading for each ticker immediately, so you get a value at once rather than waiting for the next trade. Send {"action":"unsubscribe","tickers":["NVDA"]} to stop one.
The handshake is a normal /v1 GET, so it costs one request against your daily limit; the frames it then streams are free. Each frame carries the same sessionDate, expectedSessionDate, stale, and ageSeconds fields as the request/response endpoints, evaluated when that frame is delivered. Readings carry delayed: true when they come from the 15-minute delayed feed.
Parameters: api_key (query string, unless you send the Authorization header). Control messages take action (subscribe or unsubscribe) and tickers (up to 100 per message). You may hold 5 tickers at once; a sixth is rejected and the others still succeed.
wscat -c "wss://api.equibles.com/v1/stream?api_key=eq_your_api_key" \
-x '{"action":"subscribe","tickers":["NVDA","AAPL"]}'import asyncio, json, websockets
async def main():
url = "wss://api.equibles.com/v1/stream?api_key=eq_your_api_key"
async with websockets.connect(url) as ws:
await ws.send(json.dumps({"action": "subscribe", "tickers": ["NVDA", "AAPL"]}))
async for frame in ws:
print(json.loads(frame))
asyncio.run(main())const ws = new WebSocket("wss://api.equibles.com/v1/stream?api_key=eq_your_api_key");
ws.onopen = () => ws.send(JSON.stringify({ action: "subscribe", tickers: ["NVDA", "AAPL"] }));
ws.onmessage = (event) => console.log(JSON.parse(event.data));Each quote arrives as its own frame:
{ "ticker": "NVDA", "price": 219.16, "bidPrice": null, "askPrice": null, "asOf": "2026-08-10T20:21:17.3612319Z", "sessionDate": "2026-08-10", "expectedSessionDate": "2026-08-10", "stale": false, "ageSeconds": 900, "source": "Rest", "delayed": true }
{ "ticker": "AAPL", "price": 308.17, "bidPrice": null, "askPrice": null, "asOf": "2026-08-10T19:59:55.3292893Z", "sessionDate": "2026-08-10", "expectedSessionDate": "2026-08-10", "stale": false, "ageSeconds": 900, "source": "Rest", "delayed": true }
Problems arrive as an error frame naming the ticker it applies to, and never close the connection — the tickers that did succeed keep streaming:
{ "type": "error", "ticker": "GOOGL", "message": "You can watch at most 5 live tickers at once. Remove one first." }
{ "type": "error", "message": "Malformed message. Send {\"action\":\"subscribe\",\"tickers\":[\"AAPL\"]}." }
/v1/stocks/
Bollinger Bands over one stock's daily closes, newest first — middle is the simple moving average across period days, with upper and lower set stdDev standard deviations either side of it, next to that day's close. The bands widen as volatility rises and contract as it falls, so a close pressing against one of them is the usual overbought/oversold cue. Extra look-back bars are read before the requested window so the earliest in-range points are fully computed; a band is null only when the stock's own history is shorter than the period. meta.windowPoints is how many computable points the window holds and meta.truncated is true when limit cut the series short — raise limit or narrow the dates to reach the older points.
Parameters: {ticker} (path — exact listed symbol, e.g. NVDA); startDate / endDate (yyyy-MM-dd, default the last 6 months through today); period (moving-average period, default 20, minimum 2); stdDev (band width in standard deviations, default 2, must be greater than 0); limit (most recent points, default 60, max 500).
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/bollinger-bands?limit=2" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/technicals/bollinger-bands?limit=2",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/technicals/bollinger-bands?limit=2", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"companyName": "Nvidia Corp",
"period": 20,
"stdDev": 2.0,
"data": [
{ "date": "2026-08-07", "close": 223.96, "lower": 190.0188, "middle": 206.817, "upper": 223.6152 },
{ "date": "2026-08-06", "close": 218.99, "lower": 191.1622, "middle": 206.167, "upper": 221.1718 }
],
"meta": { "returned": 2, "windowPoints": 123, "truncated": true }
}
/v1/stocks/
The stochastic oscillator over one stock's daily bars, newest first — percentK locates each close inside the high/low range of the kPeriod lookback, and percentD is its dPeriod moving average, the smoothed signal line. Readings above 80 are the conventional overbought zone and below 20 oversold, and percentK crossing percentD is a common momentum signal. Extra look-back bars are read before the requested window, so a value is null only when the stock's own history is shorter than the lookback.
Parameters: {ticker} (path — exact listed symbol, e.g. NVDA); startDate / endDate (yyyy-MM-dd, default the last 6 months through today); kPeriod (%K lookback, default 14, minimum 2); dPeriod (%D smoothing, default 3, minimum 1); limit (most recent points, default 60, max 500).
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/stochastic?limit=2" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/technicals/stochastic?limit=2",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/technicals/stochastic?limit=2", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"companyName": "Nvidia Corp",
"kPeriod": 14,
"dPeriod": 3,
"data": [
{ "date": "2026-08-07", "close": 223.96, "percentK": 97.6978, "percentD": 91.5275 },
{ "date": "2026-08-06", "close": 218.99, "percentK": 86.1987, "percentD": 88.9452 }
],
"meta": { "returned": 2, "windowPoints": 123, "truncated": true }
}
/v1/stocks/
Wilder's Average True Range over one stock's daily bars, newest first — the true range (the greatest of the day's high-to-low span, the move from the previous close up to the high, and the move from the previous close down to the low) smoothed recursively across period days, next to that day's close. ATR is denominated in dollars rather than percent, so it is the usual input for sizing a position or placing a stop a fixed number of average ranges away. Twice the period of warm-up bars is read before the requested window so the in-range values are converged; atr is null only when the stock's own history is shorter than the lookback.
Parameters: {ticker} (path — exact listed symbol, e.g. NVDA); startDate / endDate (yyyy-MM-dd, default the last 6 months through today); period (lookback, default 14, minimum 2); limit (most recent points, default 60, max 500).
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/atr?limit=2" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/technicals/atr?limit=2",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/technicals/atr?limit=2", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"companyName": "Nvidia Corp",
"period": 14,
"data": [
{ "date": "2026-08-07", "close": 223.96, "atr": 7.6435 },
{ "date": "2026-08-06", "close": 218.99, "atr": 7.7876 }
],
"meta": { "returned": 2, "windowPoints": 123, "truncated": true }
}
/v1/stocks/
On-Balance Volume over one stock's daily bars, newest first — a running total that adds the day's volume when the close rises, subtracts it when the close falls, and holds flat on an unchanged close, shown next to that day's close and volume. Rising OBV confirms the volume behind an uptrend, while OBV and price pulling apart can flag a weakening move before the price turns. Unlike the other indicators here OBV takes no warm-up look-back: it is seeded at zero on the window's first bar, so the level is only comparable inside one requested window — across different date ranges compare the slope, not the absolute number.
Parameters: {ticker} (path — exact listed symbol, e.g. NVDA); startDate / endDate (yyyy-MM-dd, default the last 6 months through today); limit (most recent points, default 60, max 500). There is no period — OBV has no lookback.
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/obv?limit=2" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/technicals/obv?limit=2",
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/technicals/obv?limit=2", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"companyName": "Nvidia Corp",
"data": [
{ "date": "2026-08-07", "close": 223.96, "volume": 105473700, "obv": 1071290900 },
{ "date": "2026-08-06", "close": 218.99, "volume": 113940600, "obv": 965817200 }
],
"meta": { "returned": 2, "windowPoints": 123, "truncated": true }
}
/v1/stocks/
The stocks whose daily returns are most (or least) correlated with one stock — Pearson correlation of daily log returns on raw closes within each exact listing's comparable post-split interval, computed over the trading days both stocks priced. Dividends are excluded. scope picks the candidate universe (Industry default, Sector, or Market — the ~1,500 largest listed names, the scope that surfaces cross-industry links like suppliers); direction=Negative returns the strongest inverse movers instead. Every row carries the observation count behind its coefficient.
Parameters: {ticker} (path — e.g. NVDA); scope (Industry / Sector / Market); days (default 180, clamped 30-730); direction (Positive / Negative); limit (default 10, max 50).
curl "https://api.equibles.com/v1/stocks/NVDA/correlated?limit=3" \
-H "Authorization: Bearer eq_your_api_key"import requests
r = requests.get(
"https://api.equibles.com/v1/stocks/NVDA/correlated",
params={"limit": 3},
headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/correlated?limit=3", {
headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());{
"ticker": "NVDA",
"companyName": "Nvidia Corp",
"scope": "Industry",
"direction": "Positive",
"windowDays": 180,
"method": "pearson-log-raw-close-returns-daily",
"universeSize": 63,
"subjectObservations": 121,
"note": null,
"data": [
{ "ticker": "TSM", "name": "Taiwan Semiconductor Manufacturing Co Ltd", "industry": "Semiconductors", "sector": "Technology", "correlation": 0.6571, "observations": 121, "marketCap": 2104308137984.0 },
{ "ticker": "AVGO", "name": "Broadcom Inc.", "industry": "Semiconductors", "sector": "Technology", "correlation": 0.5009, "observations": 121, "marketCap": 1781475966976.0 },
{ "ticker": "AMD", "name": "Advanced Micro Devices Inc", "industry": "Semiconductors", "sector": "Technology", "correlation": 0.4987, "observations": 121, "marketCap": 807081410560.0 }
]
}