Fundamentals
Profile, benchmark correlation, and earnings.
Company descriptors, how a name has moved with five benchmarks, and the next earnings print with two expected-move blocks.
No raw price is returned. A synthetic profile copies the mapped symbol and is not scaled. Profile fields are sector_name, industry_group, chief_executive, company_url, market_cap, pe_ratio, eps, dividend_yield_pct, and data_updated_at. Numeric profile fields are null when data_updated_at is missing or older than 7 ET days. A P/E of -99999.99 is null. ETF sector_name, industry_group, chief_executive, and market cap are null. Blank and zero source markers are null. dividend_yield_pct is rounded to 4 decimal places. Earnings distance_pct is rounded to 4 decimal places; distance_pts stays at most 4 decimals, with no tick rounding.
benchmarks is a JSON array of unique names, for example ["SPY","QQQ"]. A comma-separated string is 422. Allowed names are SPY, QQQ, IWM, TLT, and GLD. Letter case folds, and a repeated name counts once. An unknown name is 422 with a message such as Unknown benchmark 'DIA'. Allowed: SPY, QQQ, IWM, TLT, GLD. The filter only drops blocks: best_fit_benchmark and best_fit_corr_63d still compare all five. Blocks keep the order SPY, QQQ, IWM, TLT, GLD. meta.request.benchmarks echoes the normalized names as an array; leaving the field out, or naming all five, echoes null and returns all five blocks. The row date is snapshot_date. The page is 200 rows.
Lists sector_name, industry_group, chief_executive, company_url, market cap, P/E, EPS, dividend yield, and when the fundamentals were updated. The MCP tool is list_fundamentals_profile. The arguments are this same JSON body. The bearer token stays on the HTTP header.
Parameters · Company profile
| Name | Type | Required | Values |
|---|---|---|---|
symbols | array of strings | No | Up to 300 tickers. Unknown names are left out. Order in the response is 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 3600 seconds (rc_ttl).
Valid bodies, from the minimal to the one the sample answers:
{}{"symbols":["AAPL"]}
curl --compressed \ --request POST \ --url "${TANUKI_BASE_URL}/api/v1/fundamentals/profile" \ --header "Authorization: Bearer 12345.YOUR_API_KEY" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data '{"symbols":["AAPL"]}'
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": [ { "symbol": "AAPL", "type": "STOCK", "is_synthetic": false, "mapped_from": null, "sector_name": "Technology", "industry_group": "Consumer Electronics", "chief_executive": "John Ternus", "company_url": "https://www.apple.com", "market_cap": 5012517062800, "pe_ratio": 39.521, "eps": 8.6906, "dividend_yield_pct": 0.32, "data_updated_at": "2026-10-21T16:00:04-04:00" } ] }, "meta": { "request": { "symbols": [ "AAPL" ] }, "count": 1, "total": 1, "page": 1, "page_count": 1, "next_cursor": null, "generation": "b078f9743fbc", "as_of": {}, "built_at": "2026-10-23T01:08:02-04:00", "omitted": [], "docs": { "reference": "https://tanukitrade.com/docs/api/fundamentals#list_fundamentals_profile", "glossary": "https://tanukitrade.com/docs/api/glossary" } } }
Response fields · Company profile
| Field | Type | Meaning |
|---|---|---|
symbol | string | Canonical ticker. Copy it from list_symbols. Letter case folds to uppercase. |
type | string | STOCK, ETF, INDEX, FUTURES, or CFD_CRYPTO. |
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. |
sector_name | string or null | Null for an ETF, and null when the source marker is blank. |
industry_group | string or null | Null for an ETF, and null when the source marker is blank. |
chief_executive | string or null | Null for an ETF, and null when the source marker is blank or zero. |
company_url | string or null | Null when the source marker is blank. An ETF can still have a URL. |
market_cap | number or null | Null for an ETF, and null when the update is stale. Rounded to 4 decimal places. |
pe_ratio | number or null | Null when the source marker is the missing-P/E sentinel, or when the update is older than 7 ET days. Rounded to 4 decimal places. |
eps | number or null | Earnings per share, 4 decimals. Null when the source value is zero, or when the update is older than 7 ET days. |
dividend_yield_pct | number or null | Trailing yield in percent, including special dividends, rounded to 4 decimal places. |
data_updated_at | datetime ET or null | When the fundamentals row was updated, ISO 8601 with an ET offset. |
Errors on this route · Company profile
| 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 correlation and beta versus SPY, QQQ, IWM, TLT, and GLD. Windows are the last 21, 63, and 252 common daily log returns. best_fit_benchmark is the greatest signed 63-day correlation at or above 0.30, skipping the symbol itself. A tie keeps the benchmark order. A missing 63-day window is null. A row against itself is 1.0. Optional benchmarks limits the blocks and does not change the best fit. The MCP tool is list_fundamentals_benchmark_correlation. The arguments are this same JSON body. The bearer token stays on the HTTP header.
Parameters · Benchmark correlation
| Name | Type | Required | Values |
|---|---|---|---|
symbols | array of strings | No | Up to 300 tickers. Unknown names are left out. Order in the response is symbol ascending. |
benchmarks | array of strings | No | JSON array of unique names, for example ["SPY", "QQQ"]. Allowed: SPY, QQQ, IWM, TLT, GLD. Letter case folds. A comma-separated string is 422. |
cursor | string | No | Previous meta.next_cursor. Omit it on the first page. |
Page size is fixed at 200 rows. The caller does not set it. The response cache refreshes in 120 seconds (rc_ttl).
curl --compressed \ --request POST \ --url "${TANUKI_BASE_URL}/api/v1/fundamentals/benchmark-correlation" \ --header "Authorization: Bearer 12345.YOUR_API_KEY" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data '{}'
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 (200) and meta.total is the filtered total (261). built_at is the builder health clock of this capture.
{ "ok": true, "data": { "items": [ { "symbol": "/ES1", "type": "FUTURES", "is_synthetic": true, "mapped_from": "SPX", "snapshot_date": "2026-10-21", "best_fit_benchmark": "SPY", "best_fit_corr_63d": 1, "benchmarks": { "SPY": { "corr_21d": 1, "corr_63d": 1, "corr_252d": 1, "beta_21d": 1.01, "beta_63d": 1.01, "beta_252d": 1 }, "QQQ": { "corr_21d": 0.91, "corr_63d": 0.9, "corr_252d": 0.92, "beta_21d": 0.52, "beta_63d": 0.53, "beta_252d": 0.59 }, "IWM": { "corr_21d": 0.78, "corr_63d": 0.79, "corr_252d": 0.82, "beta_21d": 0.46, "beta_63d": 0.6, "beta_252d": 0.57 }, "TLT": { "corr_21d": 0.11, "corr_63d": 0.37, "corr_252d": 0.3, "beta_21d": 0.09, "beta_63d": 0.37, "beta_252d": 0.39 }, "GLD": { "corr_21d": 0.5, "corr_63d": 0.33, "corr_252d": 0.34, "beta_21d": 0.22, "beta_63d": 0.15, "beta_252d": 0.15 } } }, { "symbol": "/GC1", "type": "FUTURES", "is_synthetic": true, "mapped_from": "GLD", "snapshot_date": "2026-10-21", "best_fit_benchmark": "IWM", "best_fit_corr_63d": 0.41, "benchmarks": { "SPY": { "corr_21d": 0.5, "corr_63d": 0.33, "corr_252d": 0.36, "beta_21d": 1.18, "beta_63d": 0.73, "beta_252d": 0.83 }, "QQQ": { "corr_21d": 0.34, "corr_63d": 0.28, "corr_252d": 0.33, "beta_21d": 0.45, "beta_63d": 0.36, "beta_252d": 0.49 }, "IWM": { "corr_21d": 0.46, "corr_63d": 0.41, "corr_252d": 0.38, "beta_21d": 0.62, "beta_63d": 0.68, "beta_252d": 0.61 }, "TLT": { "corr_21d": 0.47, "corr_63d": 0.32, "corr_252d": 0.13, "beta_21d": 0.84, "beta_63d": 0.69, "beta_252d": 0.39 }, "GLD": { "corr_21d": 1, "corr_63d": 1, "corr_252d": 1, "beta_21d": 1, "beta_63d": 1, "beta_252d": 1 } } }, { "symbol": "/M2K1", "type": "FUTURES", "is_synthetic": true, "mapped_from": "IWM", "snapshot_date": "2026-10-21", "best_fit_benchmark": "SPY", "best_fit_corr_63d": 0.79, "benchmarks": { "SPY": { "corr_21d": 0.77, "corr_63d": 0.79, "corr_252d": 0.82, "beta_21d": 1.34, "beta_63d": 1.05, "beta_252d": 1.18 }, "QQQ": { "corr_21d": 0.65, "corr_63d": 0.72, "corr_252d": 0.73, "beta_21d": 0.63, "beta_63d": 0.56, "beta_252d": 0.67 }, "IWM": { "corr_21d": 1, "corr_63d": 1, "corr_252d": 1, "beta_21d": 1, "beta_63d": 1, "beta_252d": 1 }, "TLT": { "corr_21d": 0.32, "corr_63d": 0.45, "corr_252d": 0.33, "beta_21d": 0.43, "beta_63d": 0.59, "beta_252d": 0.62 }, "GLD": { "corr_21d": 0.46, "corr_63d": 0.41, "corr_252d": 0.38, "beta_21d": 0.34, "beta_63d": 0.25, "beta_252d": 0.23 } } }, "..." ] }, "meta": { "request": { "symbols": null, "benchmarks": null }, "count": 200, "total": 261, "page": 1, "page_count": 2, "next_cursor": "...", "generation": "07cc6709c6cf", "as_of": {}, "built_at": "2026-10-23T01:08:02-04:00", "omitted": [], "docs": { "reference": "https://tanukitrade.com/docs/api/fundamentals#list_fundamentals_benchmark_correlation", "glossary": "https://tanukitrade.com/docs/api/glossary" } } }
Response fields · Benchmark correlation
| Field | Type | Meaning |
|---|---|---|
symbol | string | Canonical ticker. Copy it from list_symbols. Letter case folds to uppercase. |
type | string | STOCK, ETF, INDEX, FUTURES, or CFD_CRYPTO. |
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. |
snapshot_date | date | ET session of this row, YYYY-MM-DD. |
best_fit_benchmark | string or null | Greatest signed 63-day correlation at or above 0.30, skipping the symbol itself. |
best_fit_corr_63d | number or null | That correlation, or null when the 63-day window is missing. Rounded to 2 decimal places. |
benchmarks | object | Object keyed by SPY, QQQ, IWM, TLT, GLD. Each block is corr_21d, corr_63d, corr_252d, beta_21d, beta_63d, beta_252d. |
Errors on this route · Benchmark correlation
| 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 earnings rows. Events whose days_to_earnings is -100 or less are dropped before the symbol filter. Each row also has optimal_expiry_move and implied_move. A missing block is null, not an absent key. Optional period keeps past, future, or both. The MCP tool is list_earnings. The arguments are this same JSON body. The bearer token stays on the HTTP header.
Parameters · Earnings
| Name | Type | Required | Values |
|---|---|---|---|
symbols | array of strings | No | Up to 300 tickers. Unknown names are left out. Order in the response is symbol ascending. |
period | string | No | past, future, or both (default). Case-insensitive. past keeps rows whose has_passed is true, future keeps false; when has_passed is null, a date before today's ET date is past. |
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":["AAPL"]}
curl --compressed \ --request POST \ --url "${TANUKI_BASE_URL}/api/v1/fundamentals/earnings" \ --header "Authorization: Bearer 12345.YOUR_API_KEY" \ --header "Content-Type: application/json" \ --header "Accept: application/json" \ --data '{"symbols":["AAPL"]}'
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": [ { "symbol": "AAPL", "earnings_date": "2026-11-02", "time": "AMC", "days_to_earnings": 10.5, "days_display": 10, "has_passed": false, "is_before_market": false, "optimal_expiry_move": { "expiration_date": "2026-12-18", "dte": 56, "aliases": [ "M2" ], "is_monthly": true, "distance_pts": 24.8451, "distance_pct": 7.2225 }, "implied_move": { "expiration_date": "2026-11-04", "dte": 12, "aliases": [], "is_monthly": false, "distance_pts": 15.5132, "distance_pct": 4.5097 } } ] }, "meta": { "request": { "symbols": [ "AAPL" ], "period": "both" }, "count": 1, "total": 1, "page": 1, "page_count": 1, "next_cursor": null, "generation": "5c246baa69d6", "as_of": {}, "built_at": "2026-10-23T01:08:02-04:00", "omitted": [], "docs": { "reference": "https://tanukitrade.com/docs/api/fundamentals#list_earnings", "glossary": "https://tanukitrade.com/docs/api/glossary" } } }
Response fields · Earnings
| Field | Type | Meaning |
|---|---|---|
symbol | string | Canonical ticker. Copy it from list_symbols. Letter case folds to uppercase. |
earnings_date | date | YYYY-MM-DD. |
time | string | Session tag such as AMC. |
days_to_earnings | number | Signed days until the event. |
days_display | integer | Whole days shown beside the event. |
has_passed | boolean | True once the event time has passed. |
is_before_market | boolean or null | True when the event is before the open. |
optimal_expiry_move | object or null | Binary expected move nearest the 35 to 70 day monthly window, or null. The block is distance_pts and distance_pct. |
implied_move | object or null | First opex expiry strictly after the earnings date, or null when that print is before today or the move is missing. The block is distance_pts and distance_pct. |
Errors on this route · Earnings
| 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. |
422 | VALIDATION_ERROR | period is not past, future, or both: period must be past, future, or both. |
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.
TanukiTrade API and MCP. Derived options analytics for your code and for agents. Not investment advice. tanukitrade.com