Chain
Open interest and volume.
Call and put totals per symbol, then one symbol’s counts split by expiry.
chain/activity takes an optional symbols list; without it every symbol is returned, by total volume (call plus put) descending. chain/expiry-distribution requires one symbol. Counts are not scaled for a synthetic. A missing count is 0; a count that is not finite or does not fit a signed 64-bit integer is null. A call/put ratio is at most 4 decimals, and null when the put side is 0 or a count it uses is null. oi_share_pct and volume_share_pct are rounded to 4 decimal places, and null when the symbol total is 0 or a count it uses is null. volume_is_prior_day is true on a weekday before 09:30 ET, except SPX, XSP, ES, and MES.
On the distribution, standalone is that expiry. cumulative is every expiry through that date. The last cumulative block matches chain activity. Share percents use the symbol total.
Lists call and put open interest and volume. Optional symbols filters the list; unknown symbols are omitted. Order is total volume descending, then symbol ascending. The MCP tool is list_chain_activity. The arguments are this same JSON body. The bearer token stays on the HTTP header.
Parameters · Chain activity
| Name | Type | Required | Values |
|---|---|---|---|
symbols | array of strings | No | Up to 300 tickers. Unknown names are left out. Omit it for every symbol. Order is total volume descending, then symbol ascending. |
cursor | string | No | Previous meta.next_cursor. Omit it on the first page. |
Page size is fixed at 400 rows. The caller does not set it. The response cache refreshes in 180 seconds (rc_ttl).
Valid bodies, from the minimal to the one the sample answers:
{}{"symbols":["SPX"]}
curl --compressed \ --request POST \ --url "${TANUKI_BASE_URL}/api/v1/chain/activity" \ --header "Authorization: Bearer 12345.YOUR_API_KEY" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data '{"symbols":["SPX"]}'
Live builder output for the request in this file. The row list was short enough to keep. built_at is the builder health clock of this capture.
{ "ok": true, "data": { "items": [ { "call_oi": 9129300, "put_oi": 13341203, "call_volume": 589751, "put_volume": 893118, "call_put_oi_ratio": 0.6843, "call_put_volume_ratio": 0.6603, "symbol": "SPX", "is_synthetic": false, "mapped_from": null, "volume_is_prior_day": false } ] }, "meta": { "request": { "symbols": [ "SPX" ] }, "count": 1, "total": 1, "page": 1, "page_count": 1, "next_cursor": null, "generation": "dd5e362e22d5", "as_of": {}, "built_at": "2026-10-23T01:08:02-04:00", "omitted": [], "docs": { "reference": "https://tanukitrade.com/docs/api/chain#list_chain_activity", "glossary": "https://tanukitrade.com/docs/api/glossary" } } }
Response fields · Chain activity
| Field | Type | Meaning |
|---|---|---|
symbol | string | Canonical ticker. Copy it from list_symbols. Letter case folds to uppercase. |
is_synthetic | boolean | True when the ticker is mapped from another symbol. False is a listed underlying. |
mapped_from | string or null | The symbol a synthetic is mapped from. Null on a listed underlying. A micro names the optionable base, not its parent future. |
call_oi | integer or null | Call open interest. 0 when none is stored; a measured zero stays 0. Null when the stored value is not a finite number or is an integer outside signed 64-bit. |
put_oi | integer or null | Put open interest. 0 when none is stored; a measured zero stays 0. Null when the stored value is not a finite number or is an integer outside signed 64-bit. |
call_volume | integer or null | Call volume. 0 when none is stored; a measured zero stays 0. Null when the stored value is not a finite number or is an integer outside signed 64-bit. |
put_volume | integer or null | Put volume. 0 when none is stored; a measured zero stays 0. Null when the stored value is not a finite number or is an integer outside signed 64-bit. |
call_put_oi_ratio | number or null | call_oi / put_oi, rounded to 4 decimal places. Null when put open interest is 0 or either open-interest count is null. |
call_put_volume_ratio | number or null | call_volume / put_volume, rounded to 4 decimal places. Null when put volume is 0 or either volume count is null. |
volume_is_prior_day | boolean | True on a weekday before 09:30 ET, except SPX, XSP, ES, and MES. |
Errors on this route · Chain activity
| HTTP | Code | When |
|---|---|---|
422 | VALIDATION_ERROR | Unknown field, nested value, repeated key, bad JSON, a bad alias, or a cursor that does not match this request. |
413 | PAYLOAD_TOO_LARGE | The JSON body is larger than 4 KiB. |
503 | DATA_WARMING | The datapoint is not built yet. Wait Retry-After seconds (1). |
422 | RESULT_TOO_LARGE | The uncompressed JSON would exceed 512 KiB. Narrow the filter. |
Auth, rate limit, and the other shared failures are on Errors.
Lists per-expiry open interest and volume for one symbol. standalone is that expiry. cumulative is every expiry through that date. The MCP tool is list_chain_expiry_distribution. The arguments are this same JSON body. The bearer token stays on the HTTP header.
Parameters · Expiry distribution
| Name | Type | Required | Values |
|---|---|---|---|
symbol | string | Yes | One ticker. Letter case folds to uppercase. |
cursor | string | No | Previous meta.next_cursor. Omit it on the first page. |
Page size is fixed at 400 rows. The caller does not set it. The response cache refreshes in 180 seconds (rc_ttl).
curl --compressed \ --request POST \ --url "${TANUKI_BASE_URL}/api/v1/chain/expiry-distribution" \ --header "Authorization: Bearer 12345.YOUR_API_KEY" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data '{"symbol":"SPX"}'
Live builder output for the request in this file. The first 3 rows of the page are shown; "..." is not a row. meta.count is the untrimmed page length (54) and meta.total is the filtered total (54). built_at is the builder health clock of this capture.
{ "ok": true, "data": { "items": [ { "symbol": "SPX", "is_synthetic": false, "mapped_from": null, "expiration_date": "2026-10-23", "dte": 0, "aliases": [ "0", "w1" ], "is_monthly": false, "volume_is_prior_day": false, "standalone": { "call_oi": 141462, "put_oi": 507282, "call_volume": 72062, "put_volume": 120484, "call_put_oi_ratio": 0.2789, "call_put_volume_ratio": 0.5981, "oi_share_pct": 2.8871, "volume_share_pct": 12.9847 }, "cumulative": { "call_oi": 141462, "put_oi": 507282, "call_volume": 72062, "put_volume": 120484, "call_put_oi_ratio": 0.2789, "call_put_volume_ratio": 0.5981, "oi_share_pct": 2.8871, "volume_share_pct": 12.9847 } }, { "symbol": "SPX", "is_synthetic": false, "mapped_from": null, "expiration_date": "2026-10-26", "dte": 3, "aliases": [ "1" ], "is_monthly": false, "volume_is_prior_day": false, "standalone": { "call_oi": 37293, "put_oi": 83392, "call_volume": 21867, "put_volume": 34606, "call_put_oi_ratio": 0.4472, "call_put_volume_ratio": 0.6319, "oi_share_pct": 0.5371, "volume_share_pct": 3.8084 }, "cumulative": { "call_oi": 178755, "put_oi": 590674, "call_volume": 93929, "put_volume": 155090, "call_put_oi_ratio": 0.3026, "call_put_volume_ratio": 0.6056, "oi_share_pct": 3.4242, "volume_share_pct": 16.7931 } }, { "symbol": "SPX", "is_synthetic": false, "mapped_from": null, "expiration_date": "2026-10-27", "dte": 4, "aliases": [], "is_monthly": false, "volume_is_prior_day": false, "standalone": { "call_oi": 60799, "put_oi": 74703, "call_volume": 53493, "put_volume": 19956, "call_put_oi_ratio": 0.8139, "call_put_volume_ratio": 2.6805, "oi_share_pct": 0.603, "volume_share_pct": 4.9532 }, "cumulative": { "call_oi": 239554, "put_oi": 665377, "call_volume": 147422, "put_volume": 175046, "call_put_oi_ratio": 0.36, "call_put_volume_ratio": 0.8422, "oi_share_pct": 4.0272, "volume_share_pct": 21.7462 } }, "..." ] }, "meta": { "request": { "symbol": "SPX" }, "count": 54, "total": 54, "page": 1, "page_count": 1, "next_cursor": null, "generation": "dd5e362e22d5", "as_of": {}, "built_at": "2026-10-23T01:08:02-04:00", "omitted": [], "docs": { "reference": "https://tanukitrade.com/docs/api/chain#list_chain_expiry_distribution", "glossary": "https://tanukitrade.com/docs/api/glossary" } } }
Response fields · Expiry distribution
| Field | Type | Meaning |
|---|---|---|
symbol | string | Canonical ticker. Copy it from list_symbols. Letter case folds to uppercase. |
is_synthetic | boolean | True when the ticker is mapped from another symbol. False is a listed underlying. |
mapped_from | string or null | The symbol a synthetic is mapped from. Null on a listed underlying. A micro names the optionable base, not its parent future. |
expiration_date | date | Calendar expiry, YYYY-MM-DD, ET. |
dte | integer | Days to that expiry, as stored for the row. |
aliases | array of strings | 0, 1, w1–w4, M1–M3, ALL. Weekly aliases use a lowercase w. Monthly aliases and ALL stay uppercase. |
is_monthly | boolean | True on the monthly expiry date. Same rule as discovery expiries. |
volume_is_prior_day | boolean | True on a weekday before 09:30 ET, when volume is still the previous session's. SPX, XSP, ES, and MES are always false. |
standalone | object | That expiry’s counts, ratios, oi_share_pct, and volume_share_pct. |
cumulative | object | Every expiry through this date. The last block matches chain activity. |
oi_share_pct | number or null | Inside standalone and cumulative. Share of the symbol's total open interest on this expiry, in percent, rounded to 4 decimal places. volume_share_pct is the same for volume. Null when the symbol total is 0 or a count in that share is null. |
Errors on this route · Expiry distribution
| HTTP | Code | When |
|---|---|---|
422 | VALIDATION_ERROR | Unknown field, nested value, repeated key, bad JSON, a bad alias, or a cursor that does not match this request. |
413 | PAYLOAD_TOO_LARGE | The JSON body is larger than 4 KiB. |
503 | DATA_WARMING | The datapoint is not built yet. Wait Retry-After seconds (1). |
422 | RESULT_TOO_LARGE | The uncompressed JSON would exceed 512 KiB. Narrow the filter. |
422 | UNKNOWN_SYMBOL | Required symbol is not in the universe. |
Auth, rate limit, and the other shared failures are on Errors.
TanukiTrade API and MCP. Derived options analytics for your code and for agents. Not investment advice. tanukitrade.com