Knowledge Base/How do you read an options symbol?

How do you read an options symbol?

A Massive options ticker is four parts joined together: O: then the underlying, the expiry as YYMMDD, C or P, and the strike in thousandths padded to eight digits. So O:SPY260918C00650000 is a SPY call expiring 18 September 2026 at a strike of 650.

A Massive options ticker follows the OCC standard with an O: prefix, and it is four fields joined with no separators. Reading O:SPY260918C00650000 left to right: the underlying is SPY, the expiry is 260918 for 18 September 2026, C means call, and 00650000 is the strike in thousandths of a dollar, so 650. The two things that catch people are that the strike is multiplied by 1,000 and that both the date and the strike are zero-padded to a fixed width.

Applies to

  • Plans: an Options subscription for the data; the symbol format itself applies everywhere.
  • Endpoints: every options endpoint takes this ticker, including /v3/trades, /v3/quotes, /v2/aggs and the snapshots.
  • Asset classes: US-listed options, on both equities and indices.

The four parts

The four parts run left to right with no separators between them:

PartWidthExampleMeaning
Underlying1 to 6 charactersSPYThe root symbol, left-aligned and not padded
Expiry6 digits260918Year, month, day
Type1 characterCC for a call, P for a put
Strike8 digits00650000The strike times 1,000, zero-padded

To get the strike back, divide the last eight digits by 1,000. 00650000 is 650, 00003000 is 3, and 07600000 is 7,600.

How to build one

curl -X GET "https://api.massive.com/v3/reference/options/contracts/O:SPY260911C00500000?as_of=2026-09-11&apiKey=YOUR_API_KEY"

Response

{
  "results": {
    "contract_type": "call",
    "exercise_style": "american",
    "expiration_date": "2026-09-11",
    "primary_exchange": "BATO",
    "shares_per_contract": 100,
    "strike_price": 500,
    "ticker": "O:SPY260911C00500000",
    "underlying_ticker": "SPY"
  },
  "status": "OK"
}

Reading that one back: SPY, expiring 260911, a C for call, and 00500000 for a strike of 500. That contract has since expired, which is why the request passes as_of=2026-09-11, its expiration date: without as_of the contract overview endpoint looks the contract up as of today, and an expired contract comes back as HTTP 404 with Option Ticker not found. rather than its details.

Build the ticker from the reference endpoint rather than assembling the string yourself. Padding mistakes are silent on the data endpoints: a wrongly padded strike is a well-formed ticker for a contract that does not exist, so the trades and aggregates endpoints return an empty result rather than an error. The contract overview endpoint above answers the same ticker with HTTP 404 and Option Ticker not found., so it can check a ticker you built by hand, with as_of set to a date on or before the expiration.

Index options and adjusted contracts

Two variations are worth recognizing. An index option uses the index root without a prefix inside the ticker, so an S&P 500 weekly is O:SPXW260915C07600000, where SPXW is the root rather than SPX with something appended. And a contract adjusted after a corporate action often carries a digit after the underlying, as in O:GME1261016C00003000, which marks it as a different series from the standard O:GME... contracts.

Why the strike is in thousandths

The strike is an integer in thousandths because the format is fixed width and has to hold strikes from cents to tens of thousands without a decimal point or a variable length. Storing 650 as 00650000 lets one eight-character field carry 00003000 for a three-dollar strike and 07600000 for a 7,600-point index strike, and it means tickers sort correctly as plain text.

If you see an error

An empty results array for a ticker you built by hand is almost always the padding. Count the digits: six for the date, eight for the strike.

Option Ticker not found. with HTTP 404 from the contract overview endpoint means the same padding mistake, or a contract that had already expired on the as_of date, which is today unless you set it.

A contract that exists on another vendor but not here may be an adjusted series. Look for the same expiry and strike with a digit after the underlying.

A strike that comes back a thousand times too large or too small is the multiplier. The ticker carries thousandths; the strike_price field carries the real number.

Related


Was this article helpful?

Modernizing Wall St.

Reimagining financial market data for the 21st century.

Schedule a demo

Talk with our market data experts

Recommended

Can't find the answer you're looking for? Contact our team.
  • Title
    Are all indices available through the basic subscription tier?
    Data Coverage Category

    Data Coverage

    Indices Category

    Indices

    Description
    No, and the ones it withholds are the famous ones: SPX, DJI, RUT and VIX all need a paid Indices tier. Basic still reaches more than 10,000 of the 13,000-odd indices Massive publishes, and NDX and the Nasdaq Composite are among them.
  • Title
    Does Massive offer dark pool data?
    Data Coverage Category

    Data Coverage

    Stocks Category

    Stocks

    Description
    Yes. Off-exchange prints, which include dark pool executions, arrive on the ordinary trades feed and are identified by an exchange ID of 4. There is no separate dark pool endpoint, and no way to tell which individual venue a print came from.
  • Title
    Does Massive offer pre-market and after-hours data?
    FAQ Category

    FAQ

    Stocks Category

    Stocks

    Description
    Yes. Every extended-hours trade and quote is published, from 04:00 to 20:00 Eastern. There is no session parameter, so you select a session with timestamps, and expect far fewer aggregate bars outside regular hours because many extended-hours trades are odd lots that cannot set a price.