Market data · active

Massive

A market-data platform for stocks, options, futures, indices, forex, crypto, economic, and alternative datasets.

What it covers

Massive offers REST request/response APIs, WebSocket streams, and bulk flat files across multiple asset classes. The REST quickstart uses dividends to demonstrate the common JSON response shape with status, results, and request_id fields.

Request shape

curl "https://api.massive.com/v3/reference/dividends" \
  -H "Authorization: Bearer $MASSIVE_API_KEY"

The query-string apiKey form also works, but authorization headers reduce accidental key leakage through logs and copied URLs.

Key endpoints

Endpoint Description
GET /v2/aggs/ticker/{ticker}/range/{mult}/{ts}/{from}/{to} OHLCV aggregates
GET /v2/aggs/grouped/locale/us/market/stocks/{date} Grouped daily bars
GET /v1/open-close/{ticker}/{date} Daily open/close
GET /v3/reference/tickers Ticker reference data
GET /v3/reference/tickers/{ticker} Ticker details
GET /v3/reference/dividends Dividend data
GET /v3/reference/splits Stock splits
GET /v2/last/trade/{ticker} Last trade

Decision notes

Compare Massive plans on four axes: asset class, historical depth, feed latency, and usage rights. “Unlimited calls” does not by itself answer whether the data may be displayed or redistributed in a commercial product.

Python example: aggregates and ticker details

The aggregate helper below reads only the first results page. For a long range, use the response’s next_url or the SDK iterator and check the base-aggregate limit; see the Massive missing minute bars case before treating absent minutes as a data defect.

import httpx
from decimal import Decimal
from datetime import date

API_KEY = "your_massive_api_key"
BASE = "https://api.massive.com"

def get_aggs(ticker: str, from_: str, to: str, timespan: str = "day") -> list[dict]:
    """Get OHLCV aggregates. Response nests under 'results'."""
    resp = httpx.get(
        f"{BASE}/v2/aggs/ticker/{ticker}/range/1/{timespan}/{from_}/{to}",
        params={"apiKey": API_KEY},
        timeout=30,
    )
    resp.raise_for_status()
    data = resp.json()
    if data.get("status") != "OK":
        raise RuntimeError(f"Massive error: {data.get('status')}")
    return [
        {
            "date": date.fromtimestamp(r["t"] / 1000),
            "open": Decimal(str(r["o"])),
            "close": Decimal(str(r["c"])),
            "volume": r["v"],
        }
        for r in data.get("results", [])
    ]

def get_ticker_details(ticker: str) -> dict:
    resp = httpx.get(f"{BASE}/v3/reference/tickers/{ticker}", params={"apiKey": API_KEY}, timeout=30)
    resp.raise_for_status()
    return resp.json()["results"]

for bar in get_aggs("AAPL", "2024-01-02", "2024-01-05"):
    print(bar["date"], bar["close"])

Notes:

  • Timestamps are milliseconds since epoch — divide by 1000
  • Free tier is delayed 15 min and limited to 5 calls/min; paid plans unlock real-time
  • The company rebranded from Polygon.io to Massive in 2025; old polygon.io hosts still work
  • Dividends live under /v3/reference/dividends; splits under /v3/reference/splits

Integration surface

Versioning
Resource paths use endpoint-family versions such as v1, v2, and v3.
Resource groups
Stocks, Options, Futures, Indices, Forex and crypto, Economy
Pagination
Endpoint-specific cursor fields and next_url links are used for multi-page result sets.
Errors
Structured JSON responses include status and request_id fields for diagnostics.
Webhooks
No general webhook product was confirmed in the reviewed REST quickstart.
Official SDKs
Python, Go, Kotlin, JavaScript

Practical integration cases