Yes, and by two routes. Massive streams per-second aggregate bars live on every WebSocket cluster, not only Stocks: the channel is A on the stocks, options, indices and futures clusters, XAS on crypto and CAS on forex. For history, the REST aggregates endpoint builds one-second bars directly, because second is a timespan like any other.
Applies to
- Plans: every paid subscription that includes the WebSocket feed for that asset class.
- Endpoints: A on /stocks, /options, /indices and /futures; XAS on /crypto; CAS on /forex; and /v2/aggs/ticker/{ticker}/range/1/second/{from}/{to} for history.
- Asset classes: stocks, options, indices, futures, forex and crypto.
How to stream per-second bars
Subscribe on the cluster for your asset class, using that cluster's channel name.
{"action":"subscribe","params":"A.AAPL"}
Response
[{"ev":"status","status":"success","message":"subscribed to: A.AAPL"}]
For crypto and forex the channel differs, so the same request looks like this:
{"action":"subscribe","params":"XAS.X:BTC-USD"}
Two things differ there and both fail quietly. Using A on the crypto or forex cluster is refused with "not authorized", which reads like a plan problem and is not one. And the pair must be hyphenated on the WebSocket: XAS.X:BTCUSD is acknowledged with "subscribed to: XAS.X:BTCUSD" and then sends nothing, while XAS.X:BTC-USD streams. REST takes the unhyphenated form, which is why the habit carries over.
How to get historical per-second bars
Ask the aggregates endpoint for a second timespan. Set limit generously, because it counts base units scanned rather than bars returned:
curl -X GET "https://api.massive.com/v2/aggs/ticker/AAPL/range/1/second/2026-09-04/2026-09-04?limit=5000&apiKey=YOUR_API_KEY"
Response
{
"ticker": "AAPL",
"results": [
{ "t": 1788508800000, "o": 326.5, "c": 327.16, "v": 596.715824, "n": 51 },
{ "t": 1788508803000, "o": 327.01, "c": 327.81, "v": 223.609276, "n": 70 }
],
"status": "OK"
}
The gap between the first two bars is the point: seconds with no eligible trade produce no bar, so a per-second series is sparse even on a busy ticker.
Building your own from /v3/trades is still an option when you need control over which conditions count, but it is no longer necessary just to get the bars.
What a per-second bar contains
Every per-second bar carries the open, high, low and close for that second, and after that the fields differ by asset class:
| Cluster | Also carries |
|---|---|
| Stocks and options | Volume and the volume-weighted average price |
| Crypto | Volume and the volume-weighted average price |
| Futures | Volume, but no VWAP |
| Forex | A v that counts quotes rather than shares, and no VWAP |
| Indices | Values only: no volume and no VWAP, because an index does not trade |
A second with no trades produces no bar rather than an empty one, so gaps in the stream are normal and are not missing data.
If you see an error
{"ev":"status","status":"error","message":"not authorized"} after subscribing to A means either your plan does not include that cluster's WebSocket feed or you used A where the cluster expects XAS or CAS.
An empty results array from /v3/trades for a recent timestamp usually means the date is outside the history your plan includes rather than a gap in the data.

