Overview
The Unusual Options API returns flattened option contract records flagged for unusual volume relative to open interest. Each response includes trade metadata, unusuality scoring, and implied volatility — suitable for dashboards, alerts, and research pipelines.
Authentication
Every request must include your API key in the Authorization header using the Bearer scheme:
Authorization: Bearer fnch_your_api_key_hereKeys are prefixed with fnch_ and shown only once at creation. Store them securely — treat them like passwords. Revoke compromised keys immediately from your account settings.
Quick start
- Subscribe to Financhle Pro if you aren't already.
- Go to Account → API Access and create a named API key.
- Copy the key when it's displayed — it won't be shown again.
- Send a GET request to the endpoint with your key in the Authorization header.
Endpoint
https://financhle.com/api/v1/unusual-optionsReturns a JSON object with data (array of contracts) and meta (query summary).
Query parameters
All parameters are optional and passed as URL query strings.
| Parameter | Type | Default | Description |
|---|---|---|---|
day | string | null | Trading day to filter by, in YYYY-MM-DD format. Omit to use the latest valid US equity trading day. Historical days are supported; day=All is not available via the API. |
ticker | string | null | Comma-separated list of underlying tickers (e.g. AAPL,MSFT,NVDA). Filters results to the specified symbols for the requested day. |
is_etf | boolean | false | When true, reads from the ETF options flow dataset instead of individual equities. |
limit | integer | 100 | Maximum number of contracts to return. Min 1, max 200. |
Response
Successful responses return HTTP 200 with the following shape:
{
"data": [
{
"day": "2025-06-28",
"underlying_ticker": "LITE",
"contract_ticker": "O:LITE260710P00950000",
"contract_type": "put",
"contract_url": "https://financhle.com/company/LITE/options/O:LITE260710P00950000?day=2025-06-28",
"strike_price": 950,
"expiration_date": "2026-07-10",
"days_to_expiration": 377,
"breakeven_price": 802.26,
"volume": 1250,
"open_interest": 12,
"volume_to_open_interest_ratio": 41.67,
"unusuality_score": 4.2,
"implied_volatility": 0.8292,
"dollars_out_of_the_money": 1.25,
"percentage_out_of_the_money": 0.58,
"moneyness": "OTM",
"direction": "buy",
"sentiment": "bullish",
"size": 500,
"trade_price": 147.74,
"trade_size": 500,
"notional_value": 7387000,
"notional_exposure": 47500000,
"trade_timestamp": "2025-06-28T14:32:00.000Z",
"exchange": 313,
"trade_id": "abc123",
"bid_volume": 120,
"ask_volume": 500,
"mid_volume": 30
}
],
"meta": {
"count": 1,
"limit": 100,
"day": "2025-06-28",
"is_etf": false,
"ticker": "LITE"
}
}Meta object
count— number of contracts indatalimit— limit applied to this requestday— day filter usedis_etf— whether ETF flow was queriedticker— ticker filter used, ornull
Field reference
Each object in the data array contains:
| Field | Type | Description |
|---|---|---|
day | string | Trading session date for the detected flow (YYYY-MM-DD). |
underlying_ticker | string | Stock or ETF symbol the contract is tied to. |
contract_ticker | string | Full OCC-style options contract identifier. |
contract_type | "call" | "put" | Whether the contract is a call or put. |
contract_url | string | Financhle URL for this contract page on the requested trading day. |
strike_price | number | Strike price of the contract. |
expiration_date | string | Contract expiration date. |
days_to_expiration | number | null | Calendar days until expiration from today. |
breakeven_price | number | null | Price the underlying must reach at expiration for the trade to break even. |
volume | number | Cumulative day volume for the contract up until time of execution of the given trade (does not include the trade itself). |
open_interest | number | Open interest at time of detection. |
volume_to_open_interest_ratio | number | null | Flagged trade size divided by open interest. |
unusuality_score | number | Financhle score indicating how unusual the volume is vs. open interest and history. |
implied_volatility | number | Implied volatility at trade execution, expressed as a decimal rather than a percent. Multiply by 100 to read as a percentage (ex. 0.86 means 86% IV). |
dollars_out_of_the_money | number | Dollar distance from the underlying price to the strike. |
percentage_out_of_the_money | number | Percent distance from the underlying price to the strike. |
moneyness | "ITM" | "OTM" | Whether the trade was in-the-money or out-of-the-money when executed. |
direction | "buy" | "sell" | "mid" | Inferred trade aggressor sentiment, based on execution price compared to the bid/ask spread at trade execution time. |
sentiment | "bullish" | "bearish" | "neutral" | Directional read on the trade: call buy and put sell are bullish; put buy and call sell are bearish; mid and other directions are neutral. |
size | number | Number of contracts transacted in the given trade. |
trade_price | number | null | Per-contract fill price of the flagged trade, in dollars. |
notional_value | number | null | Total premium paid for the trade (size × trade_price × 100), in dollars. |
notional_exposure | number | null | Share-equivalent notional exposure (size × strike_price × 100), in dollars. |
trade_timestamp | string | null | ISO 8601 timestamp of the flagged trade. |
exchange | number | null | Options exchange code for the flagged trade, when available. |
trade_id | string | null | Exchange trade identifier, when available. |
bid_volume | number | null | Contracts attributed to bid-side volume in the flagged activity window. |
ask_volume | number | null | Contracts attributed to ask-side volume in the flagged activity window. |
mid_volume | number | null | Contracts attributed to mid-market volume in the flagged activity window. |
Rate limits
Each API key has an hourly request quota (default 1,000 requests/hour). Rate limit state is returned on every response via headers:
X-RateLimit-Limit— max requests allowed this hourX-RateLimit-Remaining— requests left in the current hourX-RateLimit-Reset— Unix timestamp when the counter resets
When you exceed the limit, the API returns 429 Too Many Requests. Wait until the reset time before retrying.
Errors
Error responses are JSON objects with an error string:
{
"error": "Invalid API key"
}| Status | Meaning |
|---|---|
400 | Invalid day parameter (e.g. day=All, malformed date, or non-trading day). |
401 | Missing, invalid, or revoked API key. |
403 | Valid key but no active Pro subscription on the account. |
429 | Hourly rate limit exceeded for this key. |
500 | Server error while fetching data or checking rate limits. |
Examples
cURL
curl -X GET \
"https://financhle.com/api/v1/unusual-options?day=2025-06-28&ticker=AAPL&limit=100" \
-H "Authorization: Bearer fnch_your_api_key_here"JavaScript (fetch)
const response = await fetch(
'https://financhle.com/api/v1/unusual-options?day=2025-06-28&ticker=AAPL&limit=100',
{
headers: {
Authorization: 'Bearer fnch_your_api_key_here',
},
},
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error ?? 'Request failed');
}
const { data, meta } = await response.json();
console.log(`Returned ${meta.count} contracts`);
console.log(data);Python (requests)
import requests
url = "https://financhle.com/api/v1/unusual-options"
headers = {"Authorization": "Bearer fnch_your_api_key_here"}
params = {"day": "2025-06-28", "ticker": "AAPL", "limit": 100}
response = requests.get(url, headers=headers, params=params, timeout=30)
response.raise_for_status()
payload = response.json()
print(f"Returned {payload['meta']['count']} contracts")
for contract in payload["data"]:
print(contract["underlying_ticker"], contract["unusuality_score"])