§1The two CSV files
One file for the board, one for a company’s history. Each opens from a CSV button on the page that shows the same figures.
| File | One row per | Where the button is |
|---|---|---|
/export/board.csv | Company reporting in the next 14 days, with its priced move, ranks and markers. 38 columns. | CSV ↓ in the board’s title bar. |
/export/t/NVDA.csv | Report we hold for that company, newest first: what was priced, how far the stock moved, how far the price reading fell, and our forecast. 50 columns. | CSV ↓ in the title bar of the report history, on the company’s page. |
A script can download the same files with your API key, sent the way the API takes it (§3.1). Each download counts against the key’s 60 requests a minute. Downloads from a signed-in browser have their own 60 a minute per account.
curl -H "Authorization: Bearer $VOLMODEL_KEY" \ -o nvda.csv https://volmodel.com/export/t/NVDA.csv
§2Reading a file
Plain comma-separated text with one header row. Numbers are written raw so a spreadsheet can do arithmetic on them.
A move of 0.0841 means 8.41% of the share price, and a rank runs from 0 to 100; §4 gives the unit of every column. An empty cell means there is no value. We never write 0 or NULL in place of a missing number, because a zero would read as a measurement.
quality_flags holds the markers on that row, separated by semicolons, for example cover_mark_settled;iv_rank_noisy. Each one is explained under Markers, and a figure we left out says why in this column.
A text cell that would start with =, +, - or @ is written with a leading ', so a spreadsheet shows it rather than running it as a formula. Numbers are never changed this way.
The last two lines start with #. They carry the data notice and the method versions present in the file. Most tools can skip them when told to; in a spreadsheet they show as two rows at the bottom, which you can delete.
import pandas as pd
df = pd.read_csv("nvda.csv", comment="#")
df["expected_move_pct"] = df["expected_move"] * 100Column names do not change. New columns can be added between existing ones, so read columns by name rather than by position.
§3The API
Three read-only endpoints that return JSON. Each request needs a key from an account on a paid plan.
§3.1Your key
On your account page, under API, press Create a key. The key is shown once, so copy it then: we keep only its first eight characters, which is how the page lists it afterwards. You can hold up to 3 keys and revoke any of them, and a revoked key stops working at once. Signing out of every device does not revoke keys.
Send the key in the Authorization header. The API does not read a key from the address, because addresses end up in logs and browser history.
curl -H "Authorization: Bearer $VOLMODEL_KEY" \ https://volmodel.com/api/v1/board
import os, requests
r = requests.get(
"https://volmodel.com/api/v1/tickers/NVDA/prints",
headers={"Authorization": f"Bearer {os.environ['VOLMODEL_KEY']}"},
)
r.raise_for_status()
prints = r.json()["data"]Each key may make 60 requests in each calendar minute. Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the minute ends). The plan is checked on every request, so if a subscription ends, its keys stop working on the next call.
§3.2Endpoints
| Endpoint | Returns | Parameters |
|---|---|---|
GET /api/v1/board | Every company reporting in the next 14 days, with its priced move, ranks, forecast and markers. | None. |
GET /api/v1/tickers/{SYM}/prints | A company’s reports, newest first: priced move, actual moves, the collapse in the price reading, our forecast and its error. | limit: how many reports, newest first. Without it, every report we hold (at most 100). |
GET /api/v1/tickers/{SYM}/snapshots | A company’s daily readings, newest first: volatility, ranks, slope, tilt and priced move. | from and to, as YYYY-MM-DD. Without them, the year up to today. At most 400 rows. A date in any other form is refused. |
§3.3Responses and errors
Every response is an object with four fields. data holds the rows. methodology_versions lists every method version among those rows (see Method versions); when it has more than one entry, rows computed under different versions are not strictly comparable, and each row carries its own methodology_version so you can tell them apart. attribution and terms_url carry the data notice.
{
"data": [
{
"methodology_version": 3,
"report_date": "2026-08-26",
"session": "AMC",
"expected_move": 0.05868320610687022,
"em_decomp": 0.05589207148524317,
"rm_cc": 0.08737956691786697,
"rm_intra": 0.07109518635645107,
"crush": -0.34680822531355954,
"crush_atm_intra": -0.3378151378301292,
"crush_pred": -0.3500566047904069,
"pred_is_backfilled": false,
"pred_session_unconfirmed": false,
"crush_pred_naive": -0.36255849622892683,
"crush_cal_set": "2026Q3",
"crush_error": 0.003248379476847363,
"quality_flags": [
"cover_mark_settled",
"crush_expiry_substituted",
"decomp_macro_window",
"open_crush_gap_otm"
],
"publishable": true
}
],
"attribution": "Options data licensed from third-party providers. Delayed and derived; not investment advice.",
"terms_url": "https://volmodel.com/terms/",
"methodology_versions": [3]
}A request that fails returns a status and a JSON body such as {"error": "rate_limited"}, including an unexpected failure on our side (500, internal_error):
| Status | error | What it means |
|---|---|---|
| 400 | invalid_date | from or to is not a real YYYY-MM-DD date. |
| 400 | invalid_range | from is later than to. |
| 401 | missing_api_key | No Authorization header. |
| 401 | invalid_api_key | The key is wrong or has been revoked. |
| 403 | plan_required | The key is valid, but its account is not on a paid plan. |
| 404 | unknown_symbol | We do not cover that symbol. |
| 429 | rate_limited | More than 60 requests in this calendar minute on this key. Wait the number of seconds in Retry-After, then retry. |
§4Units
The CSV files and the API use the same names and the same units.
| Unit | Example | Fields |
|---|---|---|
| Share of the stock price | 0.0841 is 8.41% | expected_move, em_decomp and its range, the actual moves rm_*, the buy-back prices mark_* |
| Share of the option’s price | 0.0309 is 3.09% | straddle_spread_pct |
| Yearly volatility | 0.539 is 53.9% | iv_front, iv30, clean_vol, iv_t1 and its two expiries |
| Rank, 0 to 100 | 92 | richness_pctile, iv_rank, iv_percentile, clean_iv_rank, clean_iv_pctile |
| Rank points | 4.2 is 4.2 points of rank | iv_rank_noise. It can exceed 100 on a name whose readings barely move. |
| Volatility points | 6.6 is 6.6 points | ts_slope, skew_25d, skew_t1, skew_t1_post |
| Change in the price reading | -0.37 is a 37% fall | crush and its variants, crush_pred; crush_error is actual minus forecast, in the same unit |
| Count | 212 | iv_rank_n, clean_iv_rank_n (days in the rank’s window), near_oi (contracts), t1_tdays (trading days) |
| Date and session | 2026-10-19, AMC | Dates are YYYY-MM-DD. session is BMO (before the open), AMC (after the close) or UNKNOWN. |
§5Every field
Grouped as the pages group them. The grey line under each says which files and endpoints carry it.
The report
symbol- Ticker.board.csv · /board
name- Company name.board.csv
report_datesession- The day of the report, and whether it comes before the open or after the close.board.csv · SYM.csv · /board · /prints
event_statusconfirmedonce the company has announced the date,estimatedbefore then.board.csv · /boardas_of- The session the row’s figures were read on, at 15:46 ET. A name whose options went unread keeps its last reading, so this can be older than today.board.csv · /board
publishabletruewhen the company has a public page on this site. Names with too few clean reports have none, and are still covered here./prints · /snapshotsdate- The session of that day’s reading./snapshots
The priced move
expected_move- The move the at-the-money straddle prices, before it is split (§2.1).every file and endpoint
em_decomp- The report’s own part of that move, our headline figure (§3).every file and endpoint
em_decomp_loem_decomp_hi- Its error bars (§3.2).board.csv · SYM.csv · /board
em_decomp_se- Its standard error.board.csv
straddle_spread_pct- The bid–ask spread of that straddle, as a share of its middle price.board.csv · SYM.csv · /board · /snapshots
near_oi- Open interest in the contracts nearest the money.board.csv
The contract
event_expiry- The expiry the priced move is read from: the first one after the report.board.csv · SYM.csv · /board
event_strike- The listed strike nearest the price at that expiry, where the straddle is priced. Empty on readings before 23 October 2026.board.csv · /board
iv_e1- The implied volatility of that expiry, the report included.board.csv · /board
spot_capture- The share price the straddle is priced over, read at 15:46 ET.board.csv · /board
straddle_mid_usdstraddle_sellable_usd- The straddle in dollars per share: the middle of the quote, and what a seller is paid at the bid.board.csv · /board
breakeven_lobreakeven_hi- The strike minus and plus what a seller is paid: where a short straddle held to expiry starts to lose.board.csv · /board
Ordinary days
clean_vol- Volatility with the report taken out: the ordinary movement priced around it.board.csv · /board · /snapshots
iv_front- Price reading of the nearest expiry.board.csv · /snapshots
iv30- Price reading at 30 days.board.csv · /board · /snapshots
iv_rankiv_percentile- Where the 30-day reading sits in its past year (§6).board.csv · /board · /snapshots
iv_rank_n- Days in that window.board.csv · /snapshots
iv_rank_noise- How many rank points the width of the quote alone could move the rank.board.csv
clean_iv_rank- The same rank, for
clean_vol. Empty until a name has 120 days of our own readings, so most rows have none yet.board.csv · /snapshots clean_iv_pctileclean_iv_rank_n- Its percentile, and the days in its window.board.csv
ts_slopeskew_25d- The slope (price reading of the report’s expiry minus the 30-day reading) and the tilt (25-delta put reading minus call reading; positive is the usual case).board.csv · /snapshots
Richness and the forecast
richness_pctile- Where the report move sits among this company’s own past reports, 0 to 100 (§5).board.csv · /board
crush_pred- Our forecast of the collapse, written the evening before and never changed (§7).board.csv · SYM.csv · /board · /prints
crush_pred_naive- The textbook forecast, before the correction
crush_predapplies. It never changes. Empty (ornull) when there is no forecast.board.csv · SYM.csv · /board · /prints crush_cal_set- The quarter whose correction
crush_predused (2026Q4). Each quarter’s correction is fitted only on reports graded before that quarter began; a quarter with no correction leaves the two forecasts equal. Empty (ornull) when there is no forecast.SYM.csv · /prints pred_is_backfilled1(ortrue) when the forecast was reconstructed for a past report rather than published before it. Keep the two apart when you grade us. Empty (ornull) when there is no forecast.SYM.csv · /printspred_session_unconfirmed1(ortrue) when we could not confirm the report came out after the forecast was read. The record keeps these out of its averages and reports them on their own line. Empty (ornull) when there is no forecast.SYM.csv · /prints
After the report
rm_ccrm_intra- How far the stock moved, to the first close after the report and to 10:00 that morning (§4a).SYM.csv · /prints
rm_open- How far it moved to the first open after the report.SYM.csv
rm_cc_signedrm_open_signedrm_intra_signed- The same three moves with their direction kept.SYM.csv
rm_t1_closerm_t2rm_t3- The move to the close one, two and three sessions after.SYM.csv
crushcrush_atm_intra- How far the price reading fell across the report, at the day-after read and at 10:00 (§4).SYM.csv · /prints
crush_assoldcrush_iv30crush_assold_intra- The other ways §4 measures the same fall.SYM.csv
crush_error- Actual collapse minus our forecast.SYM.csv · /prints
crush_error_open- The same, at 10:00.SYM.csv
skew_t1skew_t1_post- The tilt the day before the report and the day after.SYM.csv
Selling and buying back
mark_openmark_intramark_close- The price to buy back the straddle that was sold, at the open, at 10:00 and at the close, as a share of the stock price the day before (§8).SYM.csv
mark_open_askmark_intra_askmark_close_ask- The same, at the asking price: what you would actually pay.SYM.csv
mark_t2mark_t3- The buy-back price at the close two and three sessions after.SYM.csv
mark_expirymark_strikemark_source- Which contract those prices are for, and whether each came from a quote or a trade.SYM.csv
k_star_eventt1_tdays- The strike the priced move was read from, and the trading days its expiry had left.SYM.csv
iv_t1iv_t1_e1iv_t1_e2- The price reading the day before, and of the first two expiries after the report; the split starts from these two and uses later ones where they are listed.SYM.csv
skew_span_t1- How far apart the 25-delta strikes were the day before, as a log ratio.SYM.csv
On every row
§6What you may do with the data
Personal and internal use.
The figures are derived from market data we license. The terms cover personal and internal use. To use the numbers in something you publish or sell, ask us first. Every figure is delayed: we read it at 15:46 ET and publish it overnight.