Skip to content

From Polygon.io — Option Snapshots

Looking for a second source of option Greeks alongside Polygon.io, or an alternative option snapshot API with dividend-aware, early-exercise-aware pricing and extended Greeks? Lavender delivers independently computed Greeks through Polygon.io's own wire format — no code changes required.

Already fetching option snapshots from Polygon.io? Swap the host — everything else stays the same.

Differences from Polygon.io

Lavender matches Polygon.io's JSON wire format with two specific differences worth knowing when migrating:

  • Market-data fields are zeroed. last_quote, last_trade, open_interest, and day come back populated with 0 values. Lavender computes Greeks; it does not redistribute OPRA quotes. Downstream consumers reading these fields (spread monitors, OI trend jobs) will receive zeros.
  • No rho in greeks. Matches Polygon's own omission. Rho is available via the Lavender API.

For the modeling differences (American exercise, discrete dividends, calibrated borrow), see How Lavender's Greeks Differ below.

What Changes

curl -H "Authorization: Bearer YOUR_POLYGON_KEY" \
     "https://api.polygon.io/v3/snapshot/options/AAPL"
#      ^^^^^^^^^^^^^^^^^^
curl "http://localhost:2112/v3/snapshot/options/AAPL"
#     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Swap the host. Your existing auth header is accepted and ignored. Same path, same response shape.

Try it in your browser

http://localhost:2112/v3/snapshot/options/SPY?format=html

Paste this into any browser to see Polygon.io-format Greeks rendered as an HTML table. No code needed.

Same Response Format

The JSON you get back has the same structure — a results array of option snapshots:

{
  "request_id": "a1b2c3d4e5f6",
  "status": "OK",
  "results": [
    {
      "break_even_price": 237.42,
      "details": {
        "contract_type": "call",
        "exercise_style": "american",
        "expiration_date": "2026-12-18",
        "shares_per_contract": 100,
        "strike_price": 230.0,
        "ticker": "O:AAPL261218C00230000"
      },
      "greeks": {
        "delta": 0.5834,
        "gamma": 0.0198,
        "theta": -0.1425,
        "vega": 0.312
      },
      "implied_volatility": 0.245,
      "fmv": 7.42,
      "underlying_asset": {
        "ticker": "AAPL",
        "price": 233.15,
        "value": 233.15,
        "last_updated": 1710435045123000000,
        "timeframe": "REAL-TIME"
      },
      "last_quote": {
        "ask": 0,
        "bid": 0,
        "midpoint": 0,
        "last_updated": 1710435045123000000,
        "timeframe": "REAL-TIME"
      },
      "last_trade": {
        "price": 0,
        "sip_timestamp": 1710435045123000000,
        "timeframe": "REAL-TIME"
      },
      "open_interest": 0,
      "day": {
        "last_updated": 1710435045123000000
      }
    }
  ]
}

Market data fields are zeroed

The last_quote, last_trade, open_interest, and day fields are returned with zeroed values. The greeks, implied_volatility, and fmv fields contain Lavender's computed values.


Endpoint

GET /v3/snapshot/options/{underlyingAsset}

The underlying symbol is part of the URL path (e.g., /v3/snapshot/options/SPY). Case-insensitive.

Query Parameters

All parameters are optional:

Parameter Type Description
contract_type string call or put
strike_price number Exact strike match
strike_price.gte number Strike >= value
strike_price.gt number Strike > value
strike_price.lte number Strike <= value
strike_price.lt number Strike < value
expiration_date string Exact expiration (YYYY-MM-DD)
expiration_date.gte string Expiration >= date (YYYY-MM-DD)
expiration_date.gt string Expiration > date
expiration_date.lte string Expiration <= date
expiration_date.lt string Expiration < date
order string Sort direction (asc or desc)
sort string Sort field (strike_price, expiration_date, ticker)
limit integer Max results returned (default 10, max 250)
cursor string Opaque pagination token from next_url. Round-trip only.
format string json (default), csv, ndjson, html — Lavender extension, not in real Polygon API

Pagination

Responses include next_url when more contracts remain. Follow it as-is -- the embedded cursor is opaque, not meant to be parsed or synthesized. When next_url is absent, you've reached the last page.

import requests

url = "http://localhost:2112/v3/snapshot/options/SPY?limit=250"
while url:
    r = requests.get(url).json()
    for snap in r["results"]:
        ...  # process snap
    url = r.get("next_url")

If the cursor references a contract that no longer exists (the chain refreshed between calls), results start from page 1 with HTTP 200.

Response Fields

Top Level

Field Type Description
request_id string Unique request identifier
status string "OK" on success
results array Array of option snapshots

Per-Contract Snapshot

Details

Field Type Description
contract_type string "call" or "put"
exercise_style string "american" or "european"
expiration_date string YYYY-MM-DD
shares_per_contract integer Typically 100
strike_price number Strike price
ticker string OCC symbol with O: prefix (e.g., O:AAPL261218C00230000)

Greeks

Field Type Description
delta number \(\partial V / \partial S\)
gamma number \(\partial^2 V / \partial S^2\)
theta number \(\partial V / \partial t\) — per calendar day
vega number \(\partial V / \partial \sigma\)

No rho

Following Polygon.io's convention, rho is not included in the Greeks object.

Other Computed Fields

Field Type Description
implied_volatility number Annualized implied volatility (decimal, e.g., 0.245 = 24.5%)
fmv number Fair market value (theoretical option price)
break_even_price number Strike + theo (calls) or strike - theo (puts). Null if theo <= 0

Underlying Asset

Field Type Description
ticker string Underlying symbol
price number Current spot price
value number Same as price
last_updated number Timestamp (nanoseconds since epoch)
timeframe string "REAL-TIME"

Greek Scaling

Theta is returned per calendar day. All other Greeks pass through without rescaling. All output values are rounded to 4 decimal places.

How Lavender's Greeks Differ

Polygon.io computes Greeks using a Black-Scholes model with European-style assumptions. Running Lavender alongside Polygon.io gives you a second perspective that accounts for:

  • Early exercise — Lavender prices American options, which matters for equity options near ex-dividend dates where European models undervalue early exercise
  • Discrete dividends — Lavender uses the actual dividend schedule rather than a continuous yield approximation
  • Implied borrow rates — Lavender solves for the borrow rate per expiry to enforce put-call parity, producing consistent call/put Greeks even in hard-to-borrow names
  • Rho — Lavender computes rho internally, though this endpoint omits it to match Polygon.io's format. Access rho via the Lavender API
  • Two views of time decay — conventional theta (\(\partial V / \partial t\)) on this endpoint, plus a separate decay metric (expected change to next trading day, accounting for weekends and holidays) on the Lavender API
  • Extended Greeks — access vanna, charm, volga, speed, and more via the Lavender API

Migrating to the Lavender Native API

Polygon.io Lavender API
/{underlyingAsset} in path underlying= query param
details.strike_price strike
details.expiration_date expiry
implied_volatility vol
greeks.delta delta (flat)
fmv theo

Error Responses

Status Condition
200 Success
400 Missing underlying symbol in path, invalid parameter values
502 Upstream data unavailable

Error response body

Errors return a JSON envelope:

{
  "status": "ERROR",
  "request_id": "a1b2c3d4e5f6...",
  "error": "Missing underlying symbol in path",
  "message": "Missing underlying symbol in path",
  "results": []
}

See also

  • Field Reference — every L1 field with units, source, and example values
  • Greek Conventions — sign conventions, units, and the full extended Greeks catalog
  • Verify the Greeks — derive each Greek from first principles and check against the API