Massive's feeds handle a canceled trade by keeping it and marking it, never by deleting it, and only REST and the flat files can show you the mark. A cancellation arrives from the exchange or reporting facility as a separate message, often long after the trade, and Massive records it as a second row next to the original. The WebSocket trade stream has no field to carry that, so a system built only on the live stream never learns a trade was canceled.
Applies to
- Plans: any Stocks subscription with access to trades. Cancellations and corrections are rare events in US equities, reported mostly for off-exchange prints.
- Endpoints: /v3/trades/{ticker} and the flat-file trade datasets carry a correction value. The T channel on the /stocks WebSocket cluster does not, and neither does the options T channel.
- Asset classes: US stocks. Options REST trades document the same correction field.
What a canceled trade looks like in REST
A canceled trade looks like two rows in REST, not one. The original stays at the moment it printed and is marked afterwards, and the cancellation is a row of its own, disseminated later, with the same trade id, sequence number, price and size. This is one AAPL trade from 4 September 2026:
curl -X GET "https://api.massive.com/v3/trades/AAPL?timestamp.gte=1788549871493000000×tamp.lte=1788549877493000000&limit=10000&order=asc&sort=timestamp&apiKey=YOUR_API_KEY"
Response (the original, trimmed; the cancel record comes from the same call made around its own time, 1788554563433711037)
{
"results": [
{ "id": "454690", "exchange": 4, "trf_id": 202, "price": 321.915, "size": 100,
"sequence_number": 9454652, "correction": 8,
"participant_timestamp": 1788549872493000000, "sip_timestamp": 1788549872495404947 },
{ "id": "454690", "exchange": 4, "trf_id": 202, "price": 321.915, "size": 100,
"sequence_number": 9454652, "correction": 10,
"participant_timestamp": 1788549872493000000, "sip_timestamp": 1788554563433711037 }
]
}
The first row printed at 15:24:32 ET and now carries correction: 8, meaning an original trade that was later canceled. The second is the cancel record itself, correction: 10, disseminated at 16:42:43 ET, 78 minutes later. Both keep the original participant_timestamp, which is how you can tell a late cancel record from a trade that happened at that time.
When the marks appear
The marks appear days after the session, not as it happens. Across every AAPL session from 4 to 18 September the cancel records were there, three to nine a day, while the sessions of 21 and 22 September carried none when checked on the 23rd. A trade pulled from REST for a recent session can therefore gain a correction value later, and a REST bar for that session can still change when it does. For settled history, check again a few days after the session.
What the correction values mean
What the correction values mean comes in pairs, one for the original and one for the record that changed it. These are the values seen across full sessions of AAPL and TSLA:
| Value | Row | Meaning |
|---|---|---|
| (absent) | Normal trade | Nothing changed. The field is missing rather than zero |
| 8 | Original | The trade was later canceled |
| 10 | Cancel record | The cancellation, disseminated later |
| 1 | Original | The trade was later corrected |
| 12 | Correction record | The corrected version, disseminated later |
A correction does not always change the price or size. In the TSLA pair on 4 September the record arrived 39 minutes after the trade with the same price and size, and what changed was one of the conditions.
To reproduce Massive's own aggregate bars from trades, leave out every row that carries a correction value. Recomputing five minute bars that between them held all four values, the bar volume matched the unmarked trades exactly every time, and none of the marked rows was counted, including the cancel and correction records.
Where each feed stands
Where each feed stands on cancellations comes down to whether it has a field to carry them:
| Feed | Shows the correction? | What you get |
|---|---|---|
| REST /v3/trades | Yes, the correction value | Both rows, marked |
| Flat files | Yes, a correction column | Both rows, marked, in the daily file |
| WebSocket T channel, stocks and options | No such field | The trade as it printed, with no later mark |
The WebSocket carries a trade the moment it prints, before anyone could know it will be canceled, and its message has no field that could carry the change afterwards. So a system that builds its own history from the stream keeps trades the exchange later canceled. If that matters, reconcile against REST or the flat file once the session is a few days old; before the marks arrive, REST agrees with the stream.
How aggregate bars are affected
Aggregate bars are affected differently on REST and on the stream. REST bars leave canceled and corrected rows out once the marks have arrived, so the REST bar is the one to trust for any session more than a few days old. Live bars on the WebSocket are held for 15 minutes so that late trades can be added and the bar rebroadcast, but that window is for late trades, and cancellations usually arrive well after it: the AAPL cancel above came 78 minutes after its trade, another AAPL cancel that session came 33 minutes after, and the TSLA correction came 39 minutes after. A live bar that included a trade canceled later is not corrected on the stream, which is why it can disagree with the REST bar for the same minute.
How rare they are
How rare they are is easy to overstate from one page of results, because the trades endpoint returns the newest rows first and a single page covers only the end of the day. Across whole sessions that had settled, meaning the marks had arrived:
| Session | Trades | Canceled | Corrected |
|---|---|---|---|
| AAPL, 4 Sep 2026 | 908,134 | 4 | 0 |
| AAPL, 11 Sep 2026 | 1,002,631 | 9 | 0 |
| AAPL, 15 Sep 2026 | 688,366 | 3 | 0 |
| AAPL, 16 Sep 2026 | 638,266 | 3 | 1 |
| AAPL, 17 Sep 2026 | 669,462 | 3 | 0 |
| AAPL, 18 Sep 2026 | 682,055 | 4 | 1 |
| TSLA, 4 Sep 2026 | 1,528,643 | 3 | 1 |
That is roughly one in 100,000 to 400,000 trades, and every settled session checked had at least one. Page through the whole day with next_url, and use a session that is a few days old, before concluding anything about a ticker: a recent session shows none because the marks have not arrived yet, not because nothing was canceled.
Cancellations are not condition codes
Cancellations are not condition codes, so filtering conditions will not find a canceled trade. The stocks conditions reference returns 94 codes and none marks a trade as canceled. One, 38, Corrected Consolidated Close, is easy to mistake for one: it is the listing market's print that sets the official closing price, not a flag on a trade that was corrected.
If you see an error
A trade you expected to be missing is not a bug. A canceled trade stays in REST and the flat files with correction: 8, next to a cancel record with correction: 10.
A row whose sip_timestamp is long after its participant_timestamp and which carries correction: 10 or 12 is a cancel or correction record, not a trade that happened late.
A minute bar from REST that disagrees with the one you stored from the WebSocket usually means a trade arrived after the 15-minute window or was canceled later. In both cases take the REST value, but a cancellation reaches REST only a few days after the session, so a comparison made the next morning can still agree with the live bar.

