Options Expiration Dates API: List All Available Expirations for Any Ticker | FlashAlpha Research

Options Expiration Dates API: List All Available Expirations for Any Ticker

Different tickers have different expiration cycles — weeklies, monthlies, quarterlies, LEAPs — and hardcoding dates is a recipe for broken pipelines. The FlashAlpha options expiration dates API gives you a dynamic list of every available expiry for any ticker in a single call, so you can build calendars, filter chains, and feed exposure analytics without ever maintaining a static schedule.


Tomasz Dobrowolski - Quant Engineer

  • #OptionsAPI #Expirations #Tutorial #MarketData

The Problem

If you've ever tried to build an options trading system, you've hit this wall: every ticker has a different expiration schedule. SPY has Monday, Wednesday, and Friday weeklies. AAPL has standard monthlies plus select weeklies. Index options have quarterlies and end-of-month expirations. LEAPs extend two or more years out.

Why hardcoding fails: Exchanges add and remove weekly expirations without notice. New quarterly cycles appear as the calendar rolls. Any static list you maintain will silently break — and you'll only find out when your orders fail or your data pipeline returns empty results.

Before you can pull chain data, calculate Greeks, or run exposure analytics, you need one thing first: the list of valid expiration dates. That's exactly what the options() endpoint provides.

Get All Expirations — One Call

The fa.options() method hits GET /v1/options/{ticker} and returns chain metadata including every available expiration date and strike price for the given symbol.

pip install flashalpha

(GitHub · PyPI)

from flashalpha import FlashAlpha

fa = FlashAlpha("YOUR_API_KEY")

# Fetch all options metadata for AAPL
chain = fa.options("AAPL")
print(chain["expirations"])

A typical response includes the full set of available expirations:

# Output:
[
    "2026-03-20",
    "2026-03-27",
    "2026-04-03",
    "2026-04-10",
    "2026-04-17",
    "2026-05-15",
    "2026-06-19",
    "2026-09-18",
    "2026-12-18",
    "2027-01-15",
    "2027-06-18",
    "2028-01-21"
]

Weeklies, monthlies, quarterlies, and LEAPs — all in one response. Each call counts against your daily quota (50 requests/day on the free tier), so cache the result if you're querying the same ticker repeatedly.

Filter by Date Range

Spread builders and short-term traders rarely care about expirations six months out. Pull the full list, then filter to your target window:

from flashalpha import FlashAlpha
from datetime import datetime, timedelta

fa = FlashAlpha("YOUR_API_KEY")

chain = fa.options("SPY")
today = datetime.now().date()

# Keep only expirations between 7 and 45 DTE
filtered = [
    exp for exp in chain["expirations"]
    if timedelta(days=7) <= (datetime.strptime(exp, "%Y-%m-%d").date() - today) <= timedelta(days=45)
]

print(f"Expirations in 7-45 DTE window: {filtered}")
# Output:
Expirations in 7-45 DTE window: ['2026-03-20', '2026-03-27', '2026-04-03', '2026-04-10', '2026-04-17']

This is the standard pattern for iron condor and vertical spread screeners — you only want near-term expirations where theta decay is meaningful.

Working Example: Find the Nearest Monthly Expiration

Monthly expirations (the third Friday of each month) carry the most open interest and liquidity. Here's how to isolate the nearest one programmatically:

from flashalpha import FlashAlpha
from datetime import datetime
import calendar

fa = FlashAlpha("YOUR_API_KEY")

chain = fa.options("AAPL")
today = datetime.now().date()

def is_third_friday(date_str):
    """Check if a date is the third Friday of its month."""
    d = datetime.strptime(date_str, "%Y-%m-%d").date()
    cal = calendar.monthcalendar(d.year, d.month)
    # Third Friday: find the 3rd week's Friday (index 4)
    third_friday = [week[4] for week in cal if week[4] != 0][2]
    return d.day == third_friday

monthlies = [exp for exp in chain["expirations"] if is_third_friday(exp)]
future_monthlies = [exp for exp in monthlies if datetime.strptime(exp, "%Y-%m-%d").date() >= today]
nearest = future_monthlies[0] if future_monthlies else None

dte = (datetime.strptime(nearest, "%Y-%m-%d").date() - today).days
print(f"Nearest monthly: {nearest} ({dte} DTE)")
# Output:
Nearest monthly: 2026-03-20 (5 DTE)
Key Insight

Monthly expirations concentrate the bulk of open interest and dealer hedging activity. Pinning effects, max pain gravity, and gamma exposure spikes are all strongest at monthly OpEx.

Working Example: Expiration Calendar for Your Watchlist

If you're tracking multiple names, build a unified expiration calendar in one script:

from flashalpha import FlashAlpha
from datetime import datetime, timedelta
from collections import defaultdict

fa = FlashAlpha("YOUR_API_KEY")

watchlist = ["SPY", "QQQ", "AAPL", "TSLA", "NVDA", "AMZN", "META"]
today = datetime.now().date()
cutoff = today + timedelta(days=30)

# Build a calendar: date -> list of tickers expiring
calendar_map = defaultdict(list)

for ticker in watchlist:
    chain = fa.options(ticker)
    for exp in chain["expirations"]:
        exp_date = datetime.strptime(exp, "%Y-%m-%d").date()
        if today <= exp_date <= cutoff:
            calendar_map[exp].append(ticker)

# Print sorted calendar
print(f"{'Date':<14} {'DTE':>4}   Tickers")
print("-" * 50)
for date_str in sorted(calendar_map.keys()):
    dte = (datetime.strptime(date_str, "%Y-%m-%d").date() - today).days
    tickers = ", ".join(sorted(calendar_map[date_str]))
    print(f"{date_str:<14} {dte:>4}   {tickers}")
# Output:
Date             DTE   Tickers
--------------------------------------------------
2026-03-17          2   SPY, QQQ
2026-03-18          3   SPY
2026-03-20          5   SPY, QQQ, AAPL, TSLA, NVDA, AMZN, META
2026-03-25          10  SPY, QQQ, AAPL
2026-03-27          12  SPY, QQQ, AAPL, TSLA, NVDA
2026-04-01          17  SPY, QQQ
2026-04-03          19  SPY, QQQ, AAPL, TSLA, NVDA, AMZN
2026-04-10          26  SPY, QQQ, AAPL, TSLA, NVDA, AMZN, META

Notice how SPY and QQQ have far more expiration dates than individual equities — a quick visual check that confirms the weekly schedule differences across products. Full source code for these examples and more on GitHub.

Pair with Exposure Analytics

Once you have the expiration date, you can filter your full chain data or exposure analysis to that specific date. This is especially powerful for isolating near-term gamma exposure ahead of OpEx:

from flashalpha import FlashAlpha
from datetime import datetime

fa = FlashAlpha("YOUR_API_KEY")

chain = fa.options("SPY")
today = datetime.now().date()

# Find nearest expiration
nearest_exp = next(
    exp for exp in chain["expirations"]
    if datetime.strptime(exp, "%Y-%m-%d").date() >= today
)

# Pull GEX filtered to that expiration
gex = fa.gex("SPY", expiration=nearest_exp)
print(f"GEX for {nearest_exp}: {gex}")

For deeper analysis, pull Greeks for specific contracts using the expiration and strike you've identified. The complete API guide covers every endpoint in detail.

1 call
All expirations for a ticker
50/day
Free tier request quota
2+ years
LEAPS coverage depth
All cycles
Weeklies, monthlies, quarterlies

Frequently Asked Questions

Yes. The options() endpoint returns every expiration date listed by the exchange for that ticker, including Monday, Wednesday, and Friday weeklies where available. SPY and QQQ typically have the most weekly expirations, while individual equities may only have select weeks. The response always reflects the current exchange-listed schedule.
The API returns all exchange-listed expirations, which typically extend two or more years into the future for tickers with LEAPS contracts. For highly liquid names like AAPL, SPY, and QQQ, you'll see expirations stretching out to January 2028 and beyond. Less liquid tickers may only have monthlies out to 6-9 months.
Yes. The options() endpoint is available on the free tier with a limit of 50 requests per day. Each call for a different ticker counts as one request. If you need higher volume, paid plans increase the daily quota significantly. See the pricing page for current limits.

Live Market Pulse

Get tick-by-tick visibility into market shifts with full-chain analytics streaming in real time.

Intelligent Screening

Screen millions of option pairs per second using your custom EV rules, filters, and setups.

Execution-Ready

Instantly send structured orders to Interactive Brokers right from your scan results.

Join the Community

Discord

Engage in real time conversations with us!

Twitter / X

Follow us for real-time updates and insights!

GitHub

Explore our open-source SDK, examples, and analytics resources!