Strasmore Research
Learn Matt ConnorBy Matt Connor

Where to Find Options Trade Data (OPRA Prints)

Where to find options trade data: OPRA prints, free broker time and sales, per-contract APIs from Massive, Databento and ThetaData, and what a print carries.

Where to find options trade data comes down to one feed and many copies of it. Every trade in a US listed option prints on OPRA, the consolidated options tape; every other source, from a broker's time and sales tab to a paid tick API to an "unusual activity" alert, is a copy of those prints at some delay and some level of aggregation. This guide walks the sources from free to per-contract, shows what a single print carries, and reads one real session of SPY option prints, May 15, 2025, from a per-contract trades table.

Where do options trades print? OPRA

OPRA, the Options Price Reporting Authority, is the securities information processor for US listed options. Each options exchange reports every trade and its best bid and offer to OPRA, and OPRA redistributes the consolidated stream to data vendors. Listed options have no off-exchange venue: a stock can print on a dark pool and be reported through a trade reporting facility, while a listed option trade executes on an exchange and lands on OPRA, so the trade tape is complete by construction. It is also a small fraction of the quote tape. Quotes refresh on every strike of every expiry each time the underlying ticks; a trade prints only when two orders match. The options quote feed size guide puts numbers on that gap.

Where can I get options trade data for free?

Three free routes exist, each with a catch.

  • Broker time and sales. Any options-enabled brokerage platform shows per-contract time and sales for the contract on screen, live for account holders. Scope is the catch: one contract at a time, a short lookback, usually no exchange id, and no bulk export.
  • Daily volume statistics. The Options Clearing Corporation and the exchanges publish daily contract volume by exchange and by underlying at no charge. These are counts of contracts with no price and no time attached.
  • Vendor free tiers and samples. As of September 2026, Massive (the vendor formerly known as Polygon.io) lists an Options Basic plan at $0 a month and Options Starter at $29 a month, both 15-minute delayed and both without trades; on that price list, trades unlock only at the Advanced tier. Cboe DataShop sells historical option trade files by date range and posts free samples of the layout.

Free means bars or end-of-day summaries; per-contract prints sit behind a paid tier, on the options side as on the equity side covered in the free stock market data API guide.

Which APIs sell per-contract options trades?

Three vendors sell the prints themselves as tick-level records. Prices are the published individual, non-professional rates as of September 2026.

  • Massive. The REST endpoint is GET /v3/trades/{optionsTicker}, one call per contract. Each record carries price, size, exchange, conditions, correction, a SIP timestamp, a participant timestamp and a sequence number. Options Advanced is $199 a month with real-time data and five-plus years of history; the $79 Developer tier stops at aggregates.
  • Databento. The dataset is OPRA.PILLAR. Its Trades schema is the raw prints, and its TCBBO schema pairs each trade with the consolidated best bid and offer at the moment it printed. History starts April 1, 2013. Historical data is priced by usage with no subscription, new accounts receive $125 of credit, and the live Standard plan is $199 a month.
  • ThetaData. Options Value is $40 a month at one-minute intervals with no ticks. Options Standard at $80 a month and Options Pro at $160 a month both include tick-level trades, with eight and twelve years of history respectively.

A second layer is built on these prints rather than sold as prints: ORATS computes implied volatility surfaces and greeks from the tape, and flow scanners rank the day's largest fills. A record with no exchange id, no condition code and no participant timestamp summarizes prints rather than delivering them.

What is in an options trade record?

A print has a fixed anatomy, and the same fields appear whichever vendor delivers it.

  • Contract symbol. The OCC symbol packs the underlying, the expiration date, the call or put flag and the strike into one string. SPY 250620P00590000 is the SPY put expiring June 20, 2025 at a $590 strike: the root padded to six characters, the date as yymmdd, P or C, then the strike times 1,000 in eight digits. Vendors add a prefix such as O: or drop the padding.
  • Two timestamps. The participant timestamp is when the exchange matched the trade; the SIP timestamp is when OPRA stamped it on the consolidated feed. The gap between them is reporting latency.
  • Price and size. Price is per share; a standard contract covers 100 shares, so the premium that changed hands is price times size times 100.
  • Exchange id, condition codes, correction. The exchange id names the venue. Condition codes describe how the trade executed: a plain electronic fill, a multi-leg spread, a floor trade, an intermarket sweep. The trade condition codes guide walks the decoding. The correction flag marks a print that was later amended.
  • Sequence number. OPRA numbers each message; vendors expose it to order prints that share a timestamp.

Here is that anatomy on real records: the largest single trade in each of the ten SPY contracts with the biggest prints of the May 15, 2025 session.

QueryThe ten largest single SPY option prints of May 15, 2025, one per contract
contractprinted_at_etprint_priceprint_sizenotional_usdexchange_idcondition_codes
O:SPY250919P0053000011:23:087.9510900086.66 million57234
O:SPY251031P0055000011:23:0813.99109000152.49 million57234
O:SPY250919P0049000012:19:444.16216289.00 million56233
O:SPY250530C0058500012:04:1210.671500016.00 million44234
O:SPY250530P0058500012:04:125.47150008.21 million44234
O:SPY250630P0057000012:19:446.7108147.25 million56233
O:SPY250530C0059500010:42:413.7193193.46 million56233
O:SPY250530C0060500010:42:411.2293191.14 million56233
O:SPY250516P0058600009:35:012.6188812.32 million45232
O:SPY250516P0058700009:35:013.0588812.71 million45232
The exact SQL behind every number
SELECT
    ticker                                                                                        AS contract,
    formatDateTime(toTimeZone(argMax(sip_timestamp, (size, sip_timestamp)), 'America/New_York'), '%H:%i:%S') AS printed_at_et,
    round(toFloat64(argMax(price, (size, sip_timestamp))), 2)                                    AS print_price,
    max(size)                                                                                     AS print_size,
    formatReadableQuantity(toFloat64(argMax(price, (size, sip_timestamp))) * toFloat64(max(size)) * 100) AS notional_usd,
    toString(argMax(exchange, (size, sip_timestamp)))                                            AS exchange_id,
    replaceAll(replaceAll(toString(argMax(conditions, (size, sip_timestamp))), '[', ''), ']', '') AS condition_codes
FROM global_markets.options_trades
WHERE underlying_symbol = 'SPY'
  AND sip_timestamp >= '2025-05-15 00:00:00'
  AND sip_timestamp <  '2025-05-16 00:00:00'
GROUP BY ticker
ORDER BY print_size DESC, contract
LIMIT 10
Run this yourself

Read the first row as one print. 109000 contracts of O:SPY250919P00530000 traded at $7.95 per share, stamped 11:23:08 ET on exchange id 57 (the venue panel below maps ids to names), with condition codes 234. Price times size times the 100-share multiplier puts the premium at about $86.66 million. Every field a flow scanner uses to call a trade a "block" or a "sweep" is in that row; the scanner adds the label.

What does one session of options prints look like?

The same table, counted in half-hour buckets of Eastern time, draws the shape of a session.

QuerySPY option prints per half hour, May 15, 2025 (ET)
et_timeprint_countprints_labelcumulative_printscumulative_label
09:30148974148.97 thousand148974148.97 thousand
10:00119359119.36 thousand268333268.33 thousand
10:308104281.04 thousand349375349.38 thousand
11:00133628133.63 thousand483003483.00 thousand
11:308585585.86 thousand568858568.86 thousand
12:007851278.51 thousand647370647.37 thousand
12:305873158.73 thousand706101706.10 thousand
13:007601676.02 thousand782117782.12 thousand
13:305650756.51 thousand838624838.62 thousand
14:006924969.25 thousand907873907.87 thousand
14:305429654.30 thousand962169962.17 thousand
15:006423164.23 thousand10264001.03 million
15:307699076.99 thousand11033901.10 million
16:002208822.09 thousand11254781.13 million
The exact SQL behind every number
SELECT
    et_time,
    print_count,
    formatReadableQuantity(print_count)       AS prints_label,
    cumulative_prints,
    formatReadableQuantity(cumulative_prints) AS cumulative_label
FROM
(
    SELECT
        et_time,
        print_count,
        sum(print_count) OVER (ORDER BY et_time) AS cumulative_prints
    FROM
    (
        SELECT
            formatDateTime(toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), INTERVAL 30 MINUTE), '%H:%i') AS et_time,
            count()                                                                                                          AS print_count
        FROM global_markets.options_trades
        WHERE underlying_symbol = 'SPY'
          AND sip_timestamp >= '2025-05-15 00:00:00'
          AND sip_timestamp <  '2025-05-16 00:00:00'
        GROUP BY et_time
    )
)
ORDER BY et_time
Run this yourself

The first bucket, 09:30 ET, printed 148.97 thousand SPY option trades on its own, and the cumulative line ends at 1.13 million prints for the session. An options tape typically draws the same U shape as the stock tape, heavy at the open and the close and lighter through midday; the bars show how closely this session followed it. SPY options trade until 4:15 p.m. ET, fifteen minutes past the stock close, so a bucket appears after 4:00 p.m.

Which exchanges print the most options trades?

QuerySPY option prints by exchange, May 15, 2025
venueexchange_idprint_countprints_labelshare_pct
exchange 5656161932161.93 thousand14.4
exchange 4848125094125.09 thousand11.1
exchange 46469935699.36 thousand8.8
exchange 57578928289.28 thousand7.9
exchange 51518834888.35 thousand7.8
exchange 47477468274.68 thousand6.6
exchange 45457072070.72 thousand6.3
exchange 52526240162.40 thousand5.5
exchange 44445977059.77 thousand5.3
exchange 62624710747.11 thousand4.2
exchange 60604583445.83 thousand4.1
exchange 53534318343.18 thousand3.8
exchange 64643545335.45 thousand3.2
exchange 69692887028.87 thousand2.6
exchange 66662777527.77 thousand2.5
exchange 67672467424.67 thousand2.2
exchange 63632399023.99 thousand2.1
exchange 59591700717.01 thousand1.5
The exact SQL behind every number
SELECT
    coalesce(nullIf(e.venue, ''), concat('exchange ', toString(t.exchange_id))) AS venue,
    toString(t.exchange_id)                                                     AS exchange_id,
    t.print_count                                                               AS print_count,
    formatReadableQuantity(t.print_count)                                       AS prints_label,
    round(100 * t.print_count / sum(t.print_count) OVER (), 1)                  AS share_pct
FROM
(
    SELECT
        toUInt32(exchange) AS exchange_id,
        count()            AS print_count
    FROM global_markets.options_trades
    WHERE underlying_symbol = 'SPY'
      AND sip_timestamp >= '2025-05-15 00:00:00'
      AND sip_timestamp <  '2025-05-16 00:00:00'
    GROUP BY exchange_id
) AS t
LEFT JOIN
(
    SELECT
        toUInt32(id) AS exchange_id,
        any(name)    AS venue
    FROM global_markets.stocks_exchanges
    WHERE asset_class = 'options'
    GROUP BY exchange_id
) AS e ON t.exchange_id = e.exchange_id
ORDER BY print_count DESC
Run this yourself

On this session exchange 56 printed the most SPY option trades, 161.93 thousand of them, or 14.4% of the day, with 18 venues printing in total. A broker's time and sales window shows this consolidated tape but rarely the exchange id, and without the exchange id a print cannot be tied to a venue's fee schedule or its floor.

Is options trade data the same as implied volatility data?

No. Implied volatility is not on the tape. IV is computed: a vendor takes a contract's price (usually the quote midpoint or the day's close), the underlying price, the strike, the time to expiry and an interest rate, and solves a pricing model backwards for the volatility that reproduces the price. Change the input or the model and the IV changes; the print does not. A trades table has many rows per contract per day and no IV column; a greeks table has one row per contract per day and no prints.

The data behind this page holds both, as separate tables: per-contract options trades (every OPRA print with its condition codes, retained since 2014) and a daily per-contract implied volatility and greeks table (since August 2021, with a flag marking whether the solver converged). The panel below reads the greeks table for the same underlying and the same day as the prints above, one expiry, strikes within 3% of the SPY close.

QuerySPY implied volatility by strike, June 20, 2025 expiry, as of May 15, 2025
29 rows (showing 20)
strikeput_iv_pctcall_iv_pctcontracts_volume
5731815.6430
57418.214.9487
57517.71717465
57617.615.6940
57717.215.8378
57817.316.8868
57917.215.61696
58016.916.16640
58117.115.2574
58216.614.7450
58316.815.2909
58416.515.1475
58516.315.47892
58616.214.52163
5871614.42827
58815.8152069
58915.814.81670
59015.714.67707
59115.614.71059
59216.214.42371
The exact SQL behind every number
SELECT
    toString(toFloat64(strike_price))                                                    AS strike,
    round(maxIf(implied_volatility, lower(toString(option_type)) LIKE 'p%') * 100, 1)   AS put_iv_pct,
    round(maxIf(implied_volatility, lower(toString(option_type)) LIKE 'c%') * 100, 1)   AS call_iv_pct,
    sum(volume)                                                                          AS contracts_volume
FROM global_markets.options_greeks
WHERE underlying_symbol = 'SPY'
  AND date = '2025-05-15'
  AND expiration_date = '2025-06-20'
  AND iv_converged = 1
  AND volume > 0
  AND abs(toFloat64(strike_price) / toFloat64(underlying_close) - 1) < 0.03
GROUP BY strike_price
HAVING countIf(lower(toString(option_type)) LIKE 'p%') > 0
   AND countIf(lower(toString(option_type)) LIKE 'c%') > 0
ORDER BY strike_price
Run this yourself

Each row is one strike on one day, 29 strikes in view, with put IV, call IV and the contracts that traded across both. The lowest strike shown, 573, carries a put IV of 18%; the highest, 605, carries 15.5%. Index options typically show higher IV at lower strikes, the put skew, and the line traces it. None of those values came from a print. For sourcing IV history itself, see the historical implied volatility data guide.

Where do unusual options activity alerts come from?

From the prints, one step downstream. A flow scanner subscribes to the trade stream and applies rules: a print larger than the contract's open interest, a burst of fills across several exchanges within milliseconds (a sweep), a large trade at the ask, premium above a dollar threshold. The alert is a label on a row shaped like the one above, and it inherits every limit of the feed: a spread's legs print separately, and a print says nothing about whether the buyer opened or closed a position. The unusual options activity guide covers what the labels can and cannot tell you. With the raw prints in hand an alert can be rebuilt and checked; without them it is taken on faith.

FAQ

Is options trade data free?

Per-contract prints are not free from any API vendor as of September 2026; free tiers stop at delayed bars or end-of-day summaries. Brokerage platforms show time and sales for one contract at a time to account holders, and tick-level history starts near $80 a month.

What is OPRA?

OPRA is the Options Price Reporting Authority, the consolidated feed for US listed options. Every options exchange reports its trades and best bids and offers to it, and every vendor's listed option trade data traces back to it.

What is the difference between options trades and options quotes?

A trade is a print: two orders matched at a price and size on an exchange. A quote is an exchange's standing best bid and offer on a contract, republished each time it changes. Quotes outnumber trades many times over, and vendors sell them as separate products.

Does options trade data include implied volatility?

No. A print carries a contract, two timestamps, a price, a size, an exchange and condition codes. Implied volatility is computed afterwards from a price and a pricing model, and lives in a separate dataset with one row per contract per day.


Every panel on this page carries its SQL underneath. To pull the prints for another underlying or another session, ask the same questions on the Strasmore terminal.

#options-data#opra#time-and-sales#data-sources#trade-prints