Requires an Options plan. Buy it on its own or on top of a Starter or Advanced stocks plan — it uses the same API key, and stocks and options expire and renew independently. With both active, daily calls and monthly traffic quotas add up; QPS and concurrency are counted separately. Options history goes back 5+ years.
Symbol format: O: + underlying + expiration (YYMMDD) + C/P + strike × 1000 padded to 8 digits. O:QQQ261016C00600000 is the QQQ 600 call expiring 2026-10-16. Write the colon as-is or encode it as %3A.
/v3/reference/options/contractsList contracts to find the symbols you need. Common parameters: underlying_ticker, expiration_date (supports .gte/.lte), contract_type (call/put), strike_price.gte/strike_price.lte, limit (max 1000). Add expired=true for historical contracts — otherwise only unexpired contracts are returned. as_of=YYYY-MM-DD returns contracts listed on that day.
curl "https://marilux.dev/v3/reference/options/contracts?underlying_ticker=QQQ&expiration_date=2025-06-20&expired=true&contract_type=call&strike_price.gte=520&strike_price.lte=530&apiKey=mh_live_your_key"
Upstream parameter reference →
/v3/reference/options/contracts/{optionsTicker}One contract's details: underlying, expiration, strike, exercise style and shares per contract.
/v3/snapshot/options/{underlying}Option chain snapshot: latest quote, trade and day bar for every contract, with greeks (delta, gamma, theta, vega), implied_volatility and open_interest. Filter by contract_type, expiration_date and strike_price (all support .gte/.lte); limit max 250, paginate with next_url. For one contract use /v3/snapshot/options/{underlying}/{optionsTicker}. Snapshots are latest-only: as_of / date return 400. For historical chains, list contracts with as_of and fetch each contract's bars. Historical Greeks, IV and open interest aren't available.
curl "https://marilux.dev/v3/snapshot/options/QQQ?contract_type=put&expiration_date.gte=2026-10-20&limit=50&apiKey=mh_live_your_key"
Upstream parameter reference →
/v2/aggs/ticker/{optionsTicker}/range/{multiplier}/{timespan}/{from}/{to}Options bars, used exactly like stock bars. /v2/aggs/ticker/{optionsTicker}/prev and /v1/open-close/{optionsTicker}/{date} work too.
/v3/trades/{optionsTicker}/v3/quotes/{optionsTicker}Tick-level trades and quotes. Use timestamp=YYYY-MM-DD for one day, or timestamp.gte/timestamp.lt for a range; limit max 50,000, follow next_url until it's gone.
Bulk downloads:
- Options ticks bypass the cache (
X-Cache: BYPASS); every request fetches fresh data and counts toward traffic. - A page of 50,000 quotes is about 11 MB and takes 10+ seconds. If nothing returns within 60 seconds you get a 504 — retry with a smaller
limitsuch as 10,000. - Stay within your plan's concurrency (5); extra requests queue.
Python example: find contracts expiring on a day, then page through every quote for each.
import requests
BASE = "https://marilux.dev"
H = {"Authorization": "Bearer mh_live_your_key"}
# 1. Find contracts (historical contracts need expired=true)
r = requests.get(f"{BASE}/v3/reference/options/contracts", headers=H, params={
"underlying_ticker": "QQQ", "expiration_date": "2025-06-20", "expired": "true",
"strike_price.gte": 520, "strike_price.lte": 530, "limit": 1000,
})
contracts = [c["ticker"] for c in r.json()["results"]]
# 2. Page through each contract's quotes for the day
for ticker in contracts:
url, params = f"{BASE}/v3/quotes/{ticker}", {"timestamp": "2025-06-20", "limit": 50000}
while url:
page = requests.get(url, headers=H, params=params, timeout=90).json()
rows = page.get("results", [])
print(ticker, len(rows)) # save rows here
url, params = page.get("next_url"), None