Options screener API with Python: a complete request
Written and reviewed by ConvexValue · Updated July 24, 2026
cvforge’s /screen endpoint applies constrained filters and sorts across the
current U.S. options snapshot. It is useful when your Python program needs a
shortlist, not a full-market data transfer.
External API-key access is included with Go and Research. Inside a cvforge app,
use window.cvApi.screen() instead; cvforge injects the key outside the page.
The Python request
Create a personal key in your cvforge account, put it in the
CVFORGE_API_KEY environment variable, and install requests. Do not paste a
real key into source control.
import os
import requests
api_key = os.environ["CVFORGE_API_KEY"]
request_body = {
"columns": [
"underlying_ticker",
"ticker",
"contract_type",
"expiration_date",
"strike_price",
"fair_market_value",
"day_volume",
"open_interest",
"implied_volatility",
],
"filters": [
{
"field": "day_volume",
"op": "gt_field",
"field_ref": "open_interest",
},
{"field": "open_interest", "op": "gte", "value": 100},
{"field": "day_volume", "op": "gte", "value": 100},
],
"sort": [{"field": "day_volume", "direction": "desc"}],
"limit": 100,
}
response = requests.post(
"https://tap.convexvalue.com/api/data/screen",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json=request_body,
timeout=30,
)
response.raise_for_status()
payload = response.json()
columns = payload["columns"]
records = [dict(zip(columns, row, strict=True)) for row in payload["rows"]]
for record in records[:10]:
oi = record.get("open_interest") or 0
record["volume_oi"] = record["day_volume"] / oi if oi > 0 else None
print(record)
if payload.get("truncated"):
print("More contracts matched than the requested row limit.")
gt_field performs the volume/open-interest comparison on each contract before
rows are returned. Literal comparisons use operators such as gt, gte,
lt, and lte with a value instead.
fair_market_value is Massive’s proprietary valuation estimate. cvforge does
not provide option bids, asks, midpoint, quote sizes, NBBO, or last trades, so
FMV must not be presented as an executable quote or used to infer a quoted
spread.
Response shape
The response contains an ordered columns list and compact row arrays in that
same order, plus row_count, truncated, and elapsed_ms. Zipping the two
arrays produces dictionaries without hard-coding column positions.
The API allows 1–32 columns, up to 16 filters, up to 4 sort keys, and at most
500 returned rows. If truncated is true, tighten the filters or split the
research question; do not assume the visible rows are the entire match set.
Cadence and errors
The serving snapshot refreshes about once a minute. Session volume changes intraday; open interest updates daily after the close. Common responses are:
400for an unknown field, invalid operator, or malformed request;401for a missing or revoked key;429when the plan’s hourly request limit is exhausted.
The Free plan includes the screener inside cvforge but not a personal key for external Python. Go adds the personal API key and 1,000 requests per hour; Research adds historical options bars and a higher request limit. Confirm the current package on plans and limits.
For the full operator contract, see Options Screener API — Filter Every U.S. Contract. For agent access, use the Stock Market Data MCP Server for Options & Fundamentals. For a no-code build, start at the custom options screener.
The returned data is for research and education, not investment advice or order execution.