# Yahoo Finance Options Chain Scraper (`automation-lab/yahoo-finance-options-chain-scraper`) Actor

Export Yahoo Finance calls and puts with expiration, strike, bid/ask, volume, open interest, moneyness, and implied volatility for supplied tickers.

- **URL**: https://apify.com/automation-lab/yahoo-finance-options-chain-scraper.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Business
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Yahoo Finance Options Chain Scraper

Export Yahoo Finance option chains as analysis-ready finance data. Supply stock or ETF tickers and receive one typed row per call or put contract, including expiration, strike, last price, bid, ask, volume, open interest, implied volatility, and moneyness.

The Actor is designed for repeatable options research. Run it once from Apify Console, schedule snapshots, call it through the API, or connect its dataset to spreadsheets, notebooks, databases, and automation tools.

### What does Yahoo Finance Options Chain Scraper do?

The Actor retrieves public option-chain data for up to 50 Yahoo Finance ticker symbols per run.

It can:

- export calls, puts, or both contract types;
- discover the nearest available expiration dates automatically;
- retrieve up to 20 expirations per ticker;
- target exact Yahoo-listed expiration dates;
- filter by strike, volume, open interest, and implied volatility;
- combine multiple tickers into one consistent dataset;
- cap output with `maxItems` for predictable runs;
- produce CSV, Excel, JSON, XML, RSS, or Parquet through Apify datasets.

Each saved row is one option contract. This flat shape is convenient for SQL, pandas, Google Sheets, Excel, BI tools, and scheduled comparisons.

### Who is this Yahoo finance scraper for?

**Options researchers** can download calls and puts without manually copying tables.

**Quantitative analysts** can create regular snapshots for volatility, liquidity, and strike-distribution studies.

**Portfolio teams** can compare option activity across stocks and ETFs in one run.

**Data engineers** can feed a typed options dataset into a warehouse or research pipeline.

**Automation builders** can schedule recurring exports and trigger downstream workflows when a run finishes.

This Actor focuses specifically on option contracts. For stock prices and historical candles, use the related [Yahoo Finance Scraper](https://apify.com/automation-lab/yahoo-finance-scraper).

### Why use this Actor?

Yahoo Finance presents useful option data, but manual exports become repetitive when you track several symbols or expirations.

This Actor adds:

1. one normalized schema across calls and puts;
2. exact expiration selection without fragile table clicking;
3. output filters applied before records are saved and charged;
4. a global item limit across tickers and expirations;
5. bounded session refresh when Yahoo returns a temporary block;
6. non-zero failure status when extraction fails instead of a misleading empty success.

It uses Yahoo's structured options response with a coherent cookie, crumb, and datacenter proxy session. It does not download images, video, fonts, or browser assets.

### What option contract data can I extract?

| Field | Meaning |
| --- | --- |
| `ticker` | Underlying Yahoo Finance symbol |
| `companyName` | Company or fund name when reported |
| `underlyingPrice` | Reported regular-market underlying price |
| `expirationDate` | Contract expiration as `YYYY-MM-DD` |
| `contractType` | `call` or `put` |
| `contractSymbol` | Yahoo option contract identifier |
| `strike` | Contract strike price |
| `lastPrice` | Last reported contract trade price |
| `bid` / `ask` | Reported quote prices |
| `change` / `percentChange` | Reported contract price movement |
| `volume` | Reported trading volume |
| `openInterest` | Reported open interest |
| `impliedVolatility` | Decimal IV; `0.25` means 25% |
| `inTheMoney` | Yahoo's moneyness flag |
| `lastTradeDate` | Last reported trade timestamp |
| `currency` | Quote currency |
| `contractSize` | Contract-size classification |
| `sourceUrl` | Yahoo Finance options page |
| `scrapedAt` | Extraction timestamp |

Yahoo may omit market fields for inactive contracts. Those fields are returned as `null`, not invented as zero. Filter evaluation treats missing volume and open interest as zero.

### How to scrape Yahoo Finance options chains

1. Open the Actor in Apify Console.
2. Add one or more symbols to **Ticker symbols**.
3. Leave **Exact expiration dates** empty to use the nearest expiration.
4. Choose calls, puts, or both.
5. Add optional liquidity, volatility, or strike filters.
6. Set **Maximum contracts** for the output size you need.
7. Click **Start**.
8. Open the **Options contracts** dataset view.
9. Download the results or connect them to another tool.

A useful first input is:

```json
{
  "tickers": ["AAPL"],
  "maxExpirationsPerTicker": 1,
  "contractType": "both",
  "maxItems": 100
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `tickers` | string array | required | 1–50 Yahoo symbols such as `AAPL`, `SPY`, or `MSFT` |
| `expirationDates` | string array | `[]` | Up to 20 exact dates in `YYYY-MM-DD` format |
| `maxExpirationsPerTicker` | integer | `1` | Number of nearest expirations when exact dates are absent |
| `contractType` | string | `both` | `both`, `calls`, or `puts` |
| `minStrike` | number | none | Inclusive minimum strike |
| `maxStrike` | number | none | Inclusive maximum strike |
| `minVolume` | number | none | Minimum reported volume |
| `minOpenInterest` | number | none | Minimum reported open interest |
| `minImpliedVolatility` | number | none | Minimum decimal implied volatility |
| `maxItems` | integer | `1000` | 1–10,000 saved contracts across the run |

Exact dates must exist in Yahoo's current expiration list for each ticker. Unavailable dates are logged and skipped. If no requested chain exists at all, the run fails clearly.

### Filter active calls or puts

For a focused SPY calls export:

```json
{
  "tickers": ["SPY"],
  "maxExpirationsPerTicker": 1,
  "contractType": "calls",
  "minVolume": 10,
  "minOpenInterest": 10,
  "maxItems": 100
}
```

Filters are inclusive. A contract with volume `10` passes `minVolume: 10`.

Use `minStrike` and `maxStrike` together to inspect a strike window around the underlying price.

### Output example

A current dataset row has this shape:

```json
{
  "ticker": "AAPL",
  "companyName": "Apple Inc.",
  "underlyingPrice": 307.41,
  "expirationDate": "2026-08-10",
  "contractType": "call",
  "contractSymbol": "AAPL260810C00235000",
  "strike": 235,
  "lastPrice": 72.15,
  "bid": 71.25,
  "ask": 73.05,
  "change": 1.2000046,
  "percentChange": 1.7018929,
  "volume": 318,
  "openInterest": 0,
  "impliedVolatility": 0.000010000000000000003,
  "inTheMoney": true,
  "lastTradeDate": "2026-08-10T19:43:28.000Z",
  "currency": "USD",
  "contractSize": "REGULAR",
  "sourceUrl": "https://finance.yahoo.com/quote/AAPL/options/?date=1786320000",
  "scrapedAt": "2026-08-10T20:08:00.000Z"
}
```

Prices and activity values change with the source. The sample illustrates field structure, not a live quote guarantee.

### How much does it cost to export Yahoo Finance option contracts?

Pay-per-event pricing consists of a **$0.00005 start fee** and one item event per saved contract.

The per-contract price depends on your Apify subscription tier:

| Tier | Price per saved contract |
| --- | ---: |
| Free | $0.001932 |
| Bronze | $0.00168 |
| Silver | $0.0013104 |
| Gold | $0.001008 |
| Platinum | $0.000672 |
| Diamond | $0.0004704 |

At the Bronze tier, approximate Actor charges are:

- 100 contracts: **$0.16805**;
- 500 contracts: **$0.84005**;
- 1,000 contracts: **$1.68005**.

Only rows that pass your filters and are selected for output receive an item charge. Yahoo requests that return no accepted contracts do not create item charges. Apify platform usage can be shown separately by your account.

### Schedule options-chain exports for trading research

Create an Apify Task with a stable input such as:

```json
{
  "tickers": ["AAPL", "MSFT", "NVDA"],
  "maxExpirationsPerTicker": 2,
  "contractType": "both",
  "maxItems": 800
}
```

Then add a daily or weekly schedule. Each run creates a separate dataset, so downstream systems can compare snapshots by run time.

Useful workflows include:

- monitoring changes in open interest;
- tracking liquidity near selected strikes;
- building implied-volatility snapshots;
- comparing calls and puts across a watchlist;
- loading recurring datasets into a warehouse.

The Actor reports source snapshots. It does not calculate trade signals, Greeks, max pain, or investment recommendations.

### Export to Excel, CSV, JSON, or Parquet

Open the run's dataset and choose a download format.

For a CSV API response, append `?format=csv&clean=true` to the dataset-items endpoint.

For JSON, use the default items link shown under Actor output.

For large scheduled pipelines, store the dataset ID from each run and consume it with the Apify API client.

### API usage

Use the synchronous endpoint for small interactive exports or the standard run endpoint for scheduled and asynchronous jobs. The following cURL, JavaScript, and Python examples all use the same typed input contract.

### Use the Actor with cURL

Start a run and wait for completion:

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~yahoo-finance-options-chain-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tickers": ["AAPL"],
    "maxExpirationsPerTicker": 1,
    "contractType": "both",
    "maxItems": 100
  }'
```

Keep API tokens in environment variables or a secret manager. Do not commit them to source code.

### Use the Actor with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor(
  'automation-lab/yahoo-finance-options-chain-scraper'
).call({
  tickers: ['SPY'],
  contractType: 'calls',
  minVolume: 10,
  maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Use the Actor with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor(
    "automation-lab/yahoo-finance-options-chain-scraper"
).call(run_input={
    "tickers": ["AAPL", "MSFT"],
    "maxExpirationsPerTicker": 1,
    "contractType": "both",
    "maxItems": 250,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

### Connect through MCP

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/yahoo-finance-options-chain-scraper"
```

For **Claude Desktop**, **Cursor**, and **VS Code**, add this MCP JSON configuration in the client's MCP settings:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/yahoo-finance-options-chain-scraper"
    }
  }
}
```

Example prompts:

- “Run the Yahoo Finance Options Chain Scraper for AAPL and return the nearest calls and puts.”
- “Export high-volume SPY calls with at least 10 open-interest contracts.”
- “Create a two-expiration options dataset for AAPL, MSFT, and NVDA.”

### Reliability and retry behavior

The Actor keeps Yahoo cookies, crumb, and proxy identity together.

It refreshes the complete session after HTTP 401, 429, or a temporary server error. Retries are bounded to three attempts.

If all attempts fail, the run ends with a non-zero status. It does not turn an upstream block into an empty successful dataset.

The current implementation uses Apify's datacenter proxy. It does not enable an automatic residential fallback, which keeps proxy cost and behavior predictable.

### Limits and data freshness

- Yahoo decides which ticker symbols and expirations are available.
- Delayed or stale quotes may be present depending on the instrument and exchange.
- Inactive contracts can have missing volume, open interest, bid, or ask values.
- `maxItems` stops the run globally, so early tickers can fill the limit before later tickers.
- The Actor supports current chains, not historical option-chain reconstruction.
- It does not require or accept Yahoo account credentials.
- Corporate actions and symbol changes can affect option availability.

For repeatable research, keep the same input and schedule and record the run timestamp with each dataset.

### Responsible use and legality

This Actor extracts publicly accessible market information. You are responsible for following Yahoo's terms, Apify's terms, exchange requirements, and laws that apply to your use.

Do not treat scraped data as guaranteed real-time market data. Do not use it as the sole basis for trading, execution, risk, tax, or legal decisions.

Avoid excessive schedules and request only the tickers and expirations needed for your workflow.

### Troubleshooting

#### The run says a ticker has no option chain

Confirm that Yahoo Finance recognizes the exact symbol and that the security currently has listed options. Symbols are normalized to uppercase, but exchange-specific Yahoo suffixes must still be correct.

#### My exact expiration date was skipped

Yahoo must list the date for that ticker. Remove `expirationDates` to retrieve the nearest available date, inspect the output, and then supply a current listed date.

#### The dataset has fewer rows than expected

Check `maxItems` and your filters. Missing volume or open interest is treated as zero for minimum filters. A tight strike range can also exclude most contracts.

#### The run failed after three retries

Yahoo may be temporarily rate limiting the datacenter route. Retry later. The Actor fails explicitly so scheduled systems can alert instead of ingesting an unexplained empty dataset.

### Frequently asked questions

#### Can I retrieve calls only?

Yes. Set `contractType` to `calls`. Use `puts` for puts only or `both` for the complete chain.

#### Can I request every expiration?

Set `maxExpirationsPerTicker` up to 20, or provide up to 20 exact dates. Use a suitable `maxItems` value because a ticker can have many contracts.

#### Can I schedule the Actor?

Yes. Save the input as an Apify Task and add a schedule. Every scheduled run produces a distinct default dataset.

#### Does it calculate option Greeks?

No. The Actor returns Yahoo's contract fields, including implied volatility, but does not calculate delta, gamma, theta, vega, or rho.

#### Does it include historical options data?

No. It extracts current option chains exposed by Yahoo Finance at run time.

#### Are zero values always real zeros?

Output preserves reported numeric values. Missing values are `null`. Only filter evaluation treats missing volume or open interest as zero.

### Related Automation Lab Actors

- [Yahoo Finance Scraper](https://apify.com/automation-lab/yahoo-finance-scraper) — current stock metadata and historical price candles.

Use the stock Actor when you need underlying-price history. Use this options-chain Actor when each dataset row must represent an individual call or put contract.

# Actor input Schema

## `tickers` (type: `array`):

Yahoo Finance symbols to retrieve, such as AAPL, SPY, or MSFT. Maximum 50 unique symbols per run.

## `expirationDates` (type: `array`):

Optional Yahoo-listed expiration dates in YYYY-MM-DD format. Leave empty to retrieve the nearest expirations.

## `maxExpirationsPerTicker` (type: `integer`):

Number of nearest expirations to retrieve when exact expiration dates are not supplied.

## `contractType` (type: `string`):

Return calls, puts, or both sides of each option chain.

## `minStrike` (type: `number`):

Optional inclusive minimum strike price.

## `maxStrike` (type: `number`):

Optional inclusive maximum strike price.

## `minVolume` (type: `number`):

Keep contracts whose reported trading volume is at least this value. Missing volume is treated as zero.

## `minOpenInterest` (type: `number`):

Keep contracts whose reported open interest is at least this value. Missing open interest is treated as zero.

## `minImpliedVolatility` (type: `number`):

Keep contracts at or above this decimal implied volatility; for example, 0.25 means 25%.

## `maxItems` (type: `integer`):

Maximum total option-contract rows saved across all tickers and expirations.

## Actor input object example

```json
{
  "tickers": [
    "AAPL"
  ],
  "expirationDates": [],
  "maxExpirationsPerTicker": 1,
  "contractType": "both",
  "maxItems": 20
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset containing all extracted option contracts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tickers": [
        "AAPL"
    ],
    "maxExpirationsPerTicker": 1,
    "contractType": "both",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/yahoo-finance-options-chain-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "tickers": ["AAPL"],
    "maxExpirationsPerTicker": 1,
    "contractType": "both",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/yahoo-finance-options-chain-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tickers": [
    "AAPL"
  ],
  "maxExpirationsPerTicker": 1,
  "contractType": "both",
  "maxItems": 20
}' |
apify call automation-lab/yahoo-finance-options-chain-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/yahoo-finance-options-chain-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4JsfOCRDLHsWbfHkj/builds/eoZX4Xdj1DNWTHyeJ/openapi.json
