Daily OHLCV price history, stored declared cash dividends, the latest close and volume for up to 25 tickers at once, technical indicators computed from 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/{ticker}/prices

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`.

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/prices?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/stocks/{ticker}/dividends

Stored declared cash dividends newest ex-dividend date first. Each row includes the amount per share in USD and its capture source. Future ex-dates may appear once a dividend has been declared. Dividend records are issuer-level, so this endpoint accepts only the company's current primary ticker; it never assumes a secondary listing or share class shares the dividend.

**Parameters:** `{ticker}` (current primary ticker, e.g. `AAPL`); optional `startDate` / `endDate` (`yyyy-MM-dd` ex-date window); `limit` (default 20, max 500); `offset`.

```bash
curl "https://api.equibles.com/v1/stocks/AAPL/dividends?limit=3" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/AAPL/dividends?limit=3",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
```

```javascript
const res = await fetch("https://api.equibles.com/v1/stocks/AAPL/dividends?limit=3", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
```

```json
{
  "data": [
    { "exDate": "2026-08-10", "amountPerShare": 0.27, "currency": "USD", "source": "Yahoo" },
    { "exDate": "2026-05-11", "amountPerShare": 0.27, "currency": "USD", "source": "Yahoo" },
    { "exDate": "2026-02-09", "amountPerShare": 0.26, "currency": "USD", "source": "Yahoo" }
  ],
  "meta": { "limit": 3, "offset": 0, "count": 3, "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`).

```bash
curl "https://api.equibles.com/v1/prices/latest?tickers=NVDA,AMD,MSFT" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/{ticker}/quote

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`).

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/quote" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/quote",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
```

```javascript
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/quote", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
```

```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.

```bash
curl "https://api.equibles.com/v1/quotes?tickers=NVDA,AAPL" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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.

```bash
wscat -c "wss://api.equibles.com/v1/stream?api_key=eq_your_api_key" \
  -x '{"action":"subscribe","tickers":["NVDA","AAPL"]}'
```

```python
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())
```

```javascript
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:

```json
{ "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:

```json
{ "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/{ticker}/technicals/bollinger-bands

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).

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/bollinger-bands?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/{ticker}/technicals/stochastic

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).

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/stochastic?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/{ticker}/technicals/atr

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).

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/atr?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/{ticker}/technicals/obv

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.

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/technicals/obv?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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/{ticker}/correlated

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).

```bash
curl "https://api.equibles.com/v1/stocks/NVDA/correlated?limit=3" \
  -H "Authorization: Bearer eq_your_api_key"
```

```python
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())
```

```javascript
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());
```

```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 }
  ]
}
```