tn-financial-data 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -26,6 +26,8 @@ This package is the hosted agent-facing surface only. The repo's website, local
26
26
  ## Features
27
27
 
28
28
  - Company facts, financials, prices, news, insider trades, ownership, global rates, and raw SEC filings through one hosted API
29
+ - Multi-ticker resolve and snapshot reads for lower-latency agent workflows
30
+ - Earnings calendar, dividends, and stock splits through the same hosted read contract
29
31
  - Agent-friendly CLI with clean error output, scoped subcommand help, and self-description via `tn-financial-data describe opencli`
30
32
  - Packaged skill bundle for Claude and OpenCode installs
31
33
  - Typed TypeScript client from the root package export
@@ -64,7 +66,12 @@ https://api.truenorth-financial.ai/v1
64
66
 
65
67
  ```bash
66
68
  tn-financial-data query resolve-ticker --query google
69
+ tn-financial-data query resolve-ticker --query google --query meta --query nvda
67
70
  tn-financial-data query available-tickers
71
+ tn-financial-data query snapshot --tickers AAPL,MSFT,NVDA
72
+ tn-financial-data query financial-metrics-snapshot --tickers AAPL,MSFT,NVDA --period annual
73
+ tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16
74
+ tn-financial-data query dividends --ticker AAPL --limit 10
68
75
  tn-financial-data query company --ticker AAPL
69
76
  tn-financial-data query filings --ticker AAPL --filing-type 8-K --limit 5
70
77
  tn-financial-data query general-overview --ticker AAPL --period quarterly --financial-limit 4 --news-limit 5
@@ -89,10 +96,15 @@ Ownership semantics:
89
96
  Common query examples:
90
97
 
91
98
  ```bash
99
+ tn-financial-data query snapshot --tickers AAPL,MSFT,NVDA
100
+ tn-financial-data query financial-metrics-snapshot --tickers AAPL,MSFT,NVDA --period annual
92
101
  tn-financial-data query financials --ticker AAPL --period annual --statement all
93
102
  tn-financial-data query financial-metrics --ticker AAPL --period annual --limit 4
94
103
  tn-financial-data query earnings --ticker AAPL --period quarterly --limit 8
104
+ tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16
95
105
  tn-financial-data query quarterly-highlights --ticker AAPL
106
+ tn-financial-data query dividends --ticker AAPL --limit 10
107
+ tn-financial-data query splits --ticker AAPL --limit 10
96
108
  tn-financial-data query filings --ticker AAPL --filing-type 10-K,10-Q,8-K --limit 10
97
109
  tn-financial-data query filing-items --ticker AAPL --accession-number 0000320193-26-000005 --item 2.02 --include-exhibits
98
110
  tn-financial-data query prices --ticker AAPL --interval day --start-date 2025-01-01 --end-date 2025-01-31
@@ -175,6 +187,17 @@ const client = new TnFinancialData({
175
187
  const resolution = await client.resolveTicker("google");
176
188
  console.log(resolution.status, resolution.resolved_ticker);
177
189
 
190
+ const batchResolution = await client.resolveTickers(["google", "meta", "nvda"]);
191
+ console.log(batchResolution.results.map((row) => `${row.query}:${row.status}`));
192
+
193
+ const calendar = await client.getEarningsCalendar({
194
+ tickers: ["NVDA", "KO"],
195
+ startDate: "2026-04-01",
196
+ endDate: "2026-06-30",
197
+ });
198
+
199
+ console.log(calendar.events.map((row) => `${row.ticker}:${row.event_date_start}`));
200
+
178
201
  const filings = await client.getFilings("AAPL", {
179
202
  filingTypes: ["8-K"],
180
203
  limit: 3,
package/dist/cli.js CHANGED
@@ -135,6 +135,26 @@ var TnFinancialData = class {
135
135
  this.appendReportPeriodParams(params, opts);
136
136
  return params.toString();
137
137
  }
138
+ buildTickerBatchParams(tickers, extra) {
139
+ const params = new URLSearchParams({
140
+ tickers: tickers.join(",")
141
+ });
142
+ if (extra) {
143
+ for (const [key, value] of Object.entries(extra)) {
144
+ if (value !== void 0) {
145
+ params.set(key, value);
146
+ }
147
+ }
148
+ }
149
+ return params.toString();
150
+ }
151
+ buildRepeatedQueryParams(key, values) {
152
+ const params = new URLSearchParams();
153
+ for (const value of values) {
154
+ params.append(key, value);
155
+ }
156
+ return params.toString();
157
+ }
138
158
  buildSegmentedRevenueParams(ticker, opts) {
139
159
  const params = new URLSearchParams({ ticker, period: opts.period });
140
160
  this.appendLimitParam(params, opts.limit);
@@ -147,6 +167,22 @@ var TnFinancialData = class {
147
167
  if (opts?.reportPeriod) params.set("report_period", opts.reportPeriod);
148
168
  return params.toString();
149
169
  }
170
+ buildEarningsCalendarParams(opts) {
171
+ const params = new URLSearchParams();
172
+ if (opts?.ticker && opts?.tickers && opts.tickers.length > 0) {
173
+ throw new Error("Use either ticker or tickers, not both.");
174
+ }
175
+ if (opts?.ticker) {
176
+ params.set("ticker", opts.ticker);
177
+ }
178
+ if (opts?.tickers && opts.tickers.length > 0) {
179
+ params.set("tickers", opts.tickers.join(","));
180
+ }
181
+ this.appendLimitParam(params, opts?.limit);
182
+ if (opts?.startDate) params.set("start_date", opts.startDate);
183
+ if (opts?.endDate) params.set("end_date", opts.endDate);
184
+ return params.toString();
185
+ }
150
186
  buildInsiderTradeParams(ticker, opts) {
151
187
  const params = new URLSearchParams({ ticker });
152
188
  this.appendLimitParam(params, opts?.limit);
@@ -159,6 +195,13 @@ var TnFinancialData = class {
159
195
  if (opts?.securityType) params.set("security_type", opts.securityType);
160
196
  return params.toString();
161
197
  }
198
+ buildCorporateActionsParams(ticker, opts) {
199
+ const params = new URLSearchParams({ ticker });
200
+ this.appendLimitParam(params, opts?.limit);
201
+ if (opts?.startDate) params.set("start_date", opts.startDate);
202
+ if (opts?.endDate) params.set("end_date", opts.endDate);
203
+ return params.toString();
204
+ }
162
205
  buildFilingsParams(ticker, opts) {
163
206
  const params = new URLSearchParams({ ticker });
164
207
  this.appendLimitParam(params, opts?.limit);
@@ -212,11 +255,24 @@ var TnFinancialData = class {
212
255
  `/financial-metrics/snapshot?${this.buildOptionalFinancialParams(ticker, opts)}`
213
256
  );
214
257
  }
258
+ async getBatchFinancialMetricsSnapshots(tickers, opts) {
259
+ return this.request(
260
+ `/financial-metrics/snapshot?${this.buildTickerBatchParams(tickers, {
261
+ period: opts?.period
262
+ })}`
263
+ );
264
+ }
215
265
  async getEarnings(ticker, opts) {
216
266
  return this.request(
217
267
  `/earnings?${this.buildOptionalFinancialParams(ticker, opts)}`
218
268
  );
219
269
  }
270
+ async getEarningsCalendar(opts) {
271
+ const params = this.buildEarningsCalendarParams(opts);
272
+ return this.request(
273
+ params.length > 0 ? `/earnings/calendar?${params}` : "/earnings/calendar"
274
+ );
275
+ }
220
276
  async getGeneralOverview(ticker, opts) {
221
277
  return this.request(
222
278
  `/general-overview?${this.buildGeneralOverviewParams(ticker, opts)}`
@@ -235,6 +291,11 @@ var TnFinancialData = class {
235
291
  `/tickers/resolve?${new URLSearchParams({ q: query })}`
236
292
  );
237
293
  }
294
+ async resolveTickers(queries) {
295
+ return this.request(
296
+ `/tickers/resolve/batch?${this.buildRepeatedQueryParams("query", queries)}`
297
+ );
298
+ }
238
299
  async getPrices(ticker, opts) {
239
300
  const params = new URLSearchParams({
240
301
  ticker,
@@ -249,6 +310,11 @@ var TnFinancialData = class {
249
310
  `/prices/snapshot?${new URLSearchParams({ ticker })}`
250
311
  );
251
312
  }
313
+ async getBatchPriceSnapshots(tickers) {
314
+ return this.request(
315
+ `/prices/snapshot?${this.buildTickerBatchParams(tickers)}`
316
+ );
317
+ }
252
318
  async getNews(ticker, opts) {
253
319
  const params = new URLSearchParams({ ticker });
254
320
  if (opts?.limit !== void 0) params.set("limit", String(opts.limit));
@@ -257,6 +323,16 @@ var TnFinancialData = class {
257
323
  if (opts?.publisher) params.set("publisher", opts.publisher);
258
324
  return this.request(`/news?${params}`);
259
325
  }
326
+ async getDividends(ticker, opts) {
327
+ return this.request(
328
+ `/corporate-actions/dividends?${this.buildCorporateActionsParams(ticker, opts)}`
329
+ );
330
+ }
331
+ async getSplits(ticker, opts) {
332
+ return this.request(
333
+ `/corporate-actions/splits?${this.buildCorporateActionsParams(ticker, opts)}`
334
+ );
335
+ }
260
336
  async getInsiderTrades(ticker, opts) {
261
337
  return this.request(
262
338
  `/insider-trades?${this.buildInsiderTradeParams(ticker, opts)}`
@@ -573,7 +649,7 @@ function rootHelp() {
573
649
  "tn-financial-data",
574
650
  "",
575
651
  "Usage:",
576
- " tn-financial-data query <available-tickers|resolve-ticker|company|filings|filing-items|general-overview|financials|financial-metrics|financial-metrics-snapshot|earnings|quarterly-highlights|analyst-estimates|prices|snapshot|news|insider-trades|institutional-ownership|investor-portfolio|global-rates|segmented-revenues|screen|screen-fields> [options]",
652
+ " tn-financial-data query <available-tickers|resolve-ticker|company|filings|filing-items|general-overview|financials|financial-metrics|financial-metrics-snapshot|earnings|earnings-calendar|quarterly-highlights|analyst-estimates|prices|snapshot|dividends|splits|news|insider-trades|institutional-ownership|investor-portfolio|global-rates|segmented-revenues|screen|screen-fields> [options]",
577
653
  " tn-financial-data skill <install|print|targets> [--tool claude|opencode]",
578
654
  " tn-financial-data describe opencli",
579
655
  " tn-financial-data --version",
@@ -581,16 +657,22 @@ function rootHelp() {
581
657
  "Examples:",
582
658
  " tn-financial-data query available-tickers",
583
659
  ' tn-financial-data query resolve-ticker --query "google"',
660
+ ' tn-financial-data query resolve-ticker --query "google" --query "meta" --query "nvda"',
584
661
  " tn-financial-data query financials --ticker AAPL --period annual --statement all",
585
662
  " tn-financial-data query filings --ticker AAPL --filing-type 8-K --limit 10",
586
663
  " tn-financial-data query filing-items --ticker AAPL --accession-number 0000320193-26-000005 --full-text",
587
664
  " tn-financial-data query general-overview --ticker AAPL --period quarterly --financial-limit 4 --news-limit 5",
588
665
  " tn-financial-data query financials --ticker AAPL --statement key-stats",
589
666
  " tn-financial-data query financial-metrics --ticker AAPL --period annual --limit 4",
667
+ " tn-financial-data query snapshot --tickers AAPL,MSFT,NVDA",
668
+ " tn-financial-data query financial-metrics-snapshot --tickers AAPL,MSFT,NVDA --period annual",
590
669
  " tn-financial-data query earnings --ticker AAPL --period quarterly --limit 8",
670
+ " tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16",
591
671
  " tn-financial-data query quarterly-highlights --ticker AAPL",
592
672
  " tn-financial-data query analyst-estimates --ticker AAPL",
593
673
  " tn-financial-data query prices --ticker AAPL --interval day --start-date 2025-01-01 --end-date 2025-01-31",
674
+ " tn-financial-data query dividends --ticker AAPL --limit 20",
675
+ " tn-financial-data query splits --ticker AAPL --limit 20",
594
676
  " tn-financial-data query insider-trades --ticker AAPL --transaction-code P,S --limit 25",
595
677
  " tn-financial-data query institutional-ownership --ticker AAPL --limit 20",
596
678
  " tn-financial-data query investor-portfolio --investor vanguard --limit 20",
@@ -614,19 +696,22 @@ function queryHelp() {
614
696
  return [
615
697
  "Usage:",
616
698
  " tn-financial-data query available-tickers [--api-key <key>] [--base-url <url>]",
617
- " tn-financial-data query resolve-ticker --query <text> [--api-key <key>] [--base-url <url>]",
699
+ " tn-financial-data query resolve-ticker --query <text> [--query <text>]... [--api-key <key>] [--base-url <url>]",
618
700
  " tn-financial-data query company --ticker <symbol> [--api-key <key>] [--base-url <url>]",
619
701
  " tn-financial-data query filings --ticker <symbol> [--filing-type <csv>] [--start-date <date>] [--end-date <date>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
620
702
  " tn-financial-data query filing-items --ticker <symbol> --accession-number <accession> [--filing-type <10-K|10-Q|8-K>] [--item <csv>] [--full-text] [--include-exhibits] [--api-key <key>] [--base-url <url>]",
621
703
  " tn-financial-data query general-overview --ticker <symbol> [--period <annual|quarterly|ttm>] [--financial-limit <n>] [--news-limit <n>] [--api-key <key>] [--base-url <url>]",
622
704
  " tn-financial-data query financials --ticker <symbol> [--period <annual|quarterly|ttm>] [--statement <all|income|balance|cash-flow|key-stats>] [--limit <n>] [--report-period <date>] [--report-period-gte <date>] [--report-period-lte <date>] [--report-period-gt <date>] [--report-period-lt <date>] [--api-key <key>] [--base-url <url>]",
623
705
  " tn-financial-data query financial-metrics --ticker <symbol> [--period <annual|quarterly|ttm>] [--limit <n>] [--report-period <date>] [--report-period-gte <date>] [--report-period-lte <date>] [--report-period-gt <date>] [--report-period-lt <date>] [--api-key <key>] [--base-url <url>]",
624
- " tn-financial-data query financial-metrics-snapshot --ticker <symbol> [--period <annual|quarterly|ttm>] [--api-key <key>] [--base-url <url>]",
706
+ " tn-financial-data query financial-metrics-snapshot (--ticker <symbol> | --tickers <csv>) [--period <annual|quarterly|ttm>] [--api-key <key>] [--base-url <url>]",
625
707
  " tn-financial-data query earnings --ticker <symbol> [--period <annual|quarterly|ttm>] [--limit <n>] [--report-period <date>] [--report-period-gte <date>] [--report-period-lte <date>] [--report-period-gt <date>] [--report-period-lt <date>] [--api-key <key>] [--base-url <url>]",
708
+ " tn-financial-data query earnings-calendar [--ticker <symbol> | --tickers <csv>] [--start-date <date>] [--end-date <date>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
626
709
  " tn-financial-data query quarterly-highlights --ticker <symbol> [--report-period <date>] [--api-key <key>] [--base-url <url>]",
627
710
  " tn-financial-data query analyst-estimates --ticker <symbol> [--api-key <key>] [--base-url <url>]",
628
711
  " tn-financial-data query prices --ticker <symbol> --interval <day|1h> --start-date <date> --end-date <date> [--api-key <key>] [--base-url <url>]",
629
- " tn-financial-data query snapshot --ticker <symbol> [--api-key <key>] [--base-url <url>]",
712
+ " tn-financial-data query snapshot (--ticker <symbol> | --tickers <csv>) [--api-key <key>] [--base-url <url>]",
713
+ " tn-financial-data query dividends --ticker <symbol> [--start-date <date>] [--end-date <date>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
714
+ " tn-financial-data query splits --ticker <symbol> [--start-date <date>] [--end-date <date>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
630
715
  " tn-financial-data query news --ticker <symbol> [--start-date <date>] [--end-date <date>] [--publisher <name>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
631
716
  " tn-financial-data query insider-trades --ticker <symbol> [--start-date <date>] [--end-date <date>] [--reporting-owner-cik <cik>] [--transaction-code <csv>] [--security-type <all|non_derivative|derivative>] [--limit <n>] [--api-key <key>] [--base-url <url>]",
632
717
  " tn-financial-data query institutional-ownership --ticker <symbol> [--limit <n>] [--api-key <key>] [--base-url <url>]",
@@ -736,16 +821,22 @@ function buildOpenCliDocument() {
736
821
  examples: [
737
822
  "tn-financial-data query available-tickers",
738
823
  'tn-financial-data query resolve-ticker --query "google"',
824
+ 'tn-financial-data query resolve-ticker --query "google" --query "meta" --query "nvda"',
739
825
  "tn-financial-data query filings --ticker AAPL --filing-type 8-K --limit 10",
740
826
  "tn-financial-data query filing-items --ticker AAPL --accession-number 0000320193-26-000005 --full-text",
741
827
  "tn-financial-data query general-overview --ticker AAPL --period quarterly --financial-limit 4 --news-limit 5",
742
828
  "tn-financial-data query financials --ticker AAPL --period annual --statement all",
743
829
  "tn-financial-data query financial-metrics --ticker AAPL --period annual --limit 4",
744
830
  "tn-financial-data query financial-metrics-snapshot --ticker AAPL",
831
+ "tn-financial-data query financial-metrics-snapshot --tickers AAPL,MSFT,NVDA --period annual",
745
832
  "tn-financial-data query earnings --ticker AAPL --period quarterly --limit 8",
833
+ "tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16",
746
834
  "tn-financial-data query quarterly-highlights --ticker AAPL",
747
835
  "tn-financial-data query analyst-estimates --ticker AAPL",
836
+ "tn-financial-data query snapshot --tickers AAPL,MSFT,NVDA",
748
837
  "tn-financial-data query prices --ticker AAPL --interval day --start-date 2025-01-01 --end-date 2025-01-31",
838
+ "tn-financial-data query dividends --ticker AAPL --limit 20",
839
+ "tn-financial-data query splits --ticker AAPL --limit 20",
749
840
  "tn-financial-data query insider-trades --ticker AAPL --transaction-code P,S --limit 25",
750
841
  "tn-financial-data query institutional-ownership --ticker AAPL --limit 20",
751
842
  "tn-financial-data query investor-portfolio --investor vanguard --limit 20",
@@ -807,7 +898,7 @@ function buildOpenCliDocument() {
807
898
  description: "Company name, brand, prompt fragment, or ticker text."
808
899
  }
809
900
  ],
810
- description: "Query text to resolve."
901
+ description: "Query text to resolve. Repeat to resolve multiple inputs in one request."
811
902
  }
812
903
  ]
813
904
  },
@@ -1100,13 +1191,23 @@ function buildOpenCliDocument() {
1100
1191
  },
1101
1192
  {
1102
1193
  name: "financial-metrics-snapshot",
1103
- description: "Fetch the latest derived financial metrics row, latest daily price snapshot, and current key statistics for one ticker.",
1194
+ description: "Fetch the latest derived financial metrics row, latest daily price snapshot, and current key statistics for one ticker or a small ticker batch.",
1104
1195
  options: [
1105
1196
  {
1106
1197
  name: "ticker",
1107
- required: true,
1108
1198
  arguments: [{ name: "ticker", required: true, description: "Ticker symbol." }],
1109
- description: "Ticker to fetch."
1199
+ description: "Single ticker to fetch."
1200
+ },
1201
+ {
1202
+ name: "tickers",
1203
+ arguments: [
1204
+ {
1205
+ name: "tickers",
1206
+ required: true,
1207
+ description: "Comma-separated ticker symbols, max 10."
1208
+ }
1209
+ ],
1210
+ description: "Ticker batch to fetch instead of --ticker."
1110
1211
  },
1111
1212
  {
1112
1213
  name: "period",
@@ -1194,6 +1295,47 @@ function buildOpenCliDocument() {
1194
1295
  }
1195
1296
  ]
1196
1297
  },
1298
+ {
1299
+ name: "earnings-calendar",
1300
+ description: "Fetch stored upcoming earnings calendar events over a date window, optionally filtered to one ticker or a small ticker batch.",
1301
+ options: [
1302
+ {
1303
+ name: "ticker",
1304
+ arguments: [{ name: "ticker", required: true, description: "Ticker symbol." }],
1305
+ description: "Optional single ticker filter."
1306
+ },
1307
+ {
1308
+ name: "tickers",
1309
+ arguments: [
1310
+ {
1311
+ name: "tickers",
1312
+ required: true,
1313
+ description: "Comma-separated ticker symbols, max 10."
1314
+ }
1315
+ ],
1316
+ description: "Optional ticker batch filter instead of --ticker."
1317
+ },
1318
+ {
1319
+ name: "start-date",
1320
+ arguments: [
1321
+ { name: "date", required: true, description: "Inclusive lower bound." }
1322
+ ],
1323
+ description: "Optional inclusive event-date lower bound. Defaults to today."
1324
+ },
1325
+ {
1326
+ name: "end-date",
1327
+ arguments: [
1328
+ { name: "date", required: true, description: "Inclusive upper bound." }
1329
+ ],
1330
+ description: "Optional inclusive event-date upper bound. Defaults to start date + 14 days."
1331
+ },
1332
+ {
1333
+ name: "limit",
1334
+ arguments: [{ name: "limit", required: true, description: "Positive integer." }],
1335
+ description: "Maximum number of events to return."
1336
+ }
1337
+ ]
1338
+ },
1197
1339
  {
1198
1340
  name: "quarterly-highlights",
1199
1341
  description: "Fetch issuer-reported supplemental quarterly highlights from the linked SEC Exhibit 99.1 release for supported companies.",
@@ -1380,13 +1522,85 @@ function buildOpenCliDocument() {
1380
1522
  },
1381
1523
  {
1382
1524
  name: "snapshot",
1383
- description: "Fetch the latest daily price snapshot for a single ticker.",
1525
+ description: "Fetch the latest daily price snapshot for one ticker or a small ticker batch.",
1526
+ options: [
1527
+ {
1528
+ name: "ticker",
1529
+ arguments: [{ name: "ticker", required: true, description: "Ticker symbol." }],
1530
+ description: "Single ticker to fetch."
1531
+ },
1532
+ {
1533
+ name: "tickers",
1534
+ arguments: [
1535
+ {
1536
+ name: "tickers",
1537
+ required: true,
1538
+ description: "Comma-separated ticker symbols, max 10."
1539
+ }
1540
+ ],
1541
+ description: "Ticker batch to fetch instead of --ticker."
1542
+ }
1543
+ ]
1544
+ },
1545
+ {
1546
+ name: "dividends",
1547
+ description: "Fetch stored dividend ex-date rows for a single ticker.",
1384
1548
  options: [
1385
1549
  {
1386
1550
  name: "ticker",
1387
1551
  required: true,
1388
1552
  arguments: [{ name: "ticker", required: true, description: "Ticker symbol." }],
1389
1553
  description: "Ticker to fetch."
1554
+ },
1555
+ {
1556
+ name: "start-date",
1557
+ arguments: [
1558
+ { name: "date", required: true, description: "Inclusive lower bound." }
1559
+ ],
1560
+ description: "Optional inclusive ex-date lower bound."
1561
+ },
1562
+ {
1563
+ name: "end-date",
1564
+ arguments: [
1565
+ { name: "date", required: true, description: "Inclusive upper bound." }
1566
+ ],
1567
+ description: "Optional inclusive ex-date upper bound."
1568
+ },
1569
+ {
1570
+ name: "limit",
1571
+ arguments: [{ name: "limit", required: true, description: "Positive integer." }],
1572
+ description: "Maximum number of dividend rows to return."
1573
+ }
1574
+ ]
1575
+ },
1576
+ {
1577
+ name: "splits",
1578
+ description: "Fetch stored stock-split rows for a single ticker.",
1579
+ options: [
1580
+ {
1581
+ name: "ticker",
1582
+ required: true,
1583
+ arguments: [{ name: "ticker", required: true, description: "Ticker symbol." }],
1584
+ description: "Ticker to fetch."
1585
+ },
1586
+ {
1587
+ name: "start-date",
1588
+ arguments: [
1589
+ { name: "date", required: true, description: "Inclusive lower bound." }
1590
+ ],
1591
+ description: "Optional inclusive split-date lower bound."
1592
+ },
1593
+ {
1594
+ name: "end-date",
1595
+ arguments: [
1596
+ { name: "date", required: true, description: "Inclusive upper bound." }
1597
+ ],
1598
+ description: "Optional inclusive split-date upper bound."
1599
+ },
1600
+ {
1601
+ name: "limit",
1602
+ arguments: [{ name: "limit", required: true, description: "Positive integer." }],
1603
+ description: "Maximum number of split rows to return."
1390
1604
  }
1391
1605
  ]
1392
1606
  },
@@ -1708,10 +1922,11 @@ var QUERY_SUBCOMMAND_HELP = {
1708
1922
  ],
1709
1923
  [
1710
1924
  "--query <text> Required. Company name, brand, prompt fragment, or ticker text.",
1925
+ "--query <text> Repeat to resolve multiple inputs in one request.",
1711
1926
  "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
1712
1927
  "--base-url <url> API base URL override."
1713
1928
  ],
1714
- 'tn-financial-data query resolve-ticker --query "google"'
1929
+ 'tn-financial-data query resolve-ticker --query "google" --query "meta" --query "nvda"'
1715
1930
  ),
1716
1931
  company: renderHelp(
1717
1932
  "company",
@@ -1804,14 +2019,17 @@ var QUERY_SUBCOMMAND_HELP = {
1804
2019
  ),
1805
2020
  "financial-metrics-snapshot": renderHelp(
1806
2021
  "financial-metrics-snapshot",
1807
- ["Fetch the latest metrics bundle, price snapshot, and key statistics for one ticker."],
1808
2022
  [
1809
- "--ticker <symbol> Required. Stock ticker symbol.",
1810
- "--period <period> annual | quarterly | ttm. Default: annual.",
1811
- "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
1812
- "--base-url <url> API base URL override."
2023
+ "Fetch the latest metrics bundle, price snapshot, and key statistics for one ticker or a small ticker batch."
1813
2024
  ],
1814
- "tn-financial-data query financial-metrics-snapshot --ticker AAPL --period quarterly"
2025
+ [
2026
+ "--ticker <symbol> Exact stock ticker symbol.",
2027
+ "--tickers <csv> Comma-separated ticker batch. Use instead of --ticker.",
2028
+ "--period <period> annual | quarterly | ttm. Default: annual.",
2029
+ "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
2030
+ "--base-url <url> API base URL override."
2031
+ ],
2032
+ "tn-financial-data query financial-metrics-snapshot --tickers AAPL,MSFT,NVDA --period quarterly"
1815
2033
  ),
1816
2034
  earnings: renderHelp(
1817
2035
  "earnings",
@@ -1830,6 +2048,22 @@ var QUERY_SUBCOMMAND_HELP = {
1830
2048
  ],
1831
2049
  "tn-financial-data query earnings --ticker AAPL --period quarterly --limit 8"
1832
2050
  ),
2051
+ "earnings-calendar": renderHelp(
2052
+ "earnings-calendar",
2053
+ [
2054
+ "Fetch stored upcoming earnings calendar events over a date window, optionally filtered to one ticker or a small ticker batch."
2055
+ ],
2056
+ [
2057
+ "--ticker <symbol> Optional single ticker filter.",
2058
+ "--tickers <csv> Optional comma-separated ticker batch filter. Use instead of --ticker.",
2059
+ "--start-date <date> Optional inclusive start date (YYYY-MM-DD). Default: today.",
2060
+ "--end-date <date> Optional inclusive end date (YYYY-MM-DD). Default: start date + 14 days.",
2061
+ "--limit <n> Maximum number of events to return.",
2062
+ "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
2063
+ "--base-url <url> API base URL override."
2064
+ ],
2065
+ "tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16"
2066
+ ),
1833
2067
  "quarterly-highlights": renderHelp(
1834
2068
  "quarterly-highlights",
1835
2069
  [
@@ -1868,13 +2102,40 @@ var QUERY_SUBCOMMAND_HELP = {
1868
2102
  ),
1869
2103
  snapshot: renderHelp(
1870
2104
  "snapshot",
1871
- ["Fetch the latest price snapshot for a single ticker."],
2105
+ ["Fetch the latest daily price snapshot for one ticker or a small ticker batch."],
1872
2106
  [
1873
- "--ticker <symbol> Required. Stock ticker symbol.",
1874
- "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
1875
- "--base-url <url> API base URL override."
2107
+ "--ticker <symbol> Exact stock ticker symbol.",
2108
+ "--tickers <csv> Comma-separated ticker batch. Use instead of --ticker.",
2109
+ "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
2110
+ "--base-url <url> API base URL override."
2111
+ ],
2112
+ "tn-financial-data query snapshot --tickers AAPL,MSFT,NVDA"
2113
+ ),
2114
+ dividends: renderHelp(
2115
+ "dividends",
2116
+ ["Fetch stored dividend ex-date rows for a single ticker."],
2117
+ [
2118
+ "--ticker <symbol> Required. Stock ticker symbol.",
2119
+ "--start-date <date> Optional start date (YYYY-MM-DD).",
2120
+ "--end-date <date> Optional end date (YYYY-MM-DD).",
2121
+ "--limit <n> Number of dividend rows to return.",
2122
+ "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
2123
+ "--base-url <url> API base URL override."
2124
+ ],
2125
+ "tn-financial-data query dividends --ticker AAPL --limit 20"
2126
+ ),
2127
+ splits: renderHelp(
2128
+ "splits",
2129
+ ["Fetch stored stock-split rows for a single ticker."],
2130
+ [
2131
+ "--ticker <symbol> Required. Stock ticker symbol.",
2132
+ "--start-date <date> Optional start date (YYYY-MM-DD).",
2133
+ "--end-date <date> Optional end date (YYYY-MM-DD).",
2134
+ "--limit <n> Number of split rows to return.",
2135
+ "--api-key <key> API key. Overrides TN_FINANCIAL_DATA_API_KEY.",
2136
+ "--base-url <url> API base URL override."
1876
2137
  ],
1877
- "tn-financial-data query snapshot --ticker AAPL"
2138
+ "tn-financial-data query splits --ticker AAPL --limit 20"
1878
2139
  ),
1879
2140
  news: renderHelp(
1880
2141
  "news",
@@ -2087,6 +2348,90 @@ function buildFinancialCliOptions(parsed, statement) {
2087
2348
  if (reportPeriodLt) options.reportPeriodLt = reportPeriodLt;
2088
2349
  return options;
2089
2350
  }
2351
+ function parseTickerSelection(parsed) {
2352
+ const ticker = getOption(parsed, "ticker");
2353
+ const tickersValue = getOption(parsed, "tickers");
2354
+ if (ticker && tickersValue) {
2355
+ throw new CliUsageError("Use either --ticker or --tickers, not both.");
2356
+ }
2357
+ if (ticker) {
2358
+ return {
2359
+ kind: "single",
2360
+ ticker
2361
+ };
2362
+ }
2363
+ if (tickersValue) {
2364
+ const tickers = parseCsvValues(tickersValue, "tickers");
2365
+ if (tickers.length > 10) {
2366
+ throw new CliUsageError("--tickers must contain between 1 and 10 values.");
2367
+ }
2368
+ return {
2369
+ kind: "batch",
2370
+ tickers
2371
+ };
2372
+ }
2373
+ throw new CliUsageError("Missing required option --ticker or --tickers.");
2374
+ }
2375
+ function parseQuerySelection(parsed) {
2376
+ const rawQueries = getOptions(parsed, "query");
2377
+ if (rawQueries.length === 0) {
2378
+ throw new CliUsageError("Missing required option --query.");
2379
+ }
2380
+ if (rawQueries.some((value) => value === "true")) {
2381
+ throw new CliUsageError("Missing required value for --query.");
2382
+ }
2383
+ const queries = [...new Set(rawQueries.map((value) => value.trim()))].filter(
2384
+ (value) => value.length > 0
2385
+ );
2386
+ if (queries.length === 0) {
2387
+ throw new CliUsageError("Missing required option --query.");
2388
+ }
2389
+ if (queries.length > 10) {
2390
+ throw new CliUsageError("--query may be provided at most 10 times.");
2391
+ }
2392
+ return queries.length === 1 ? {
2393
+ kind: "single",
2394
+ query: queries[0]
2395
+ } : {
2396
+ kind: "batch",
2397
+ queries
2398
+ };
2399
+ }
2400
+ function buildCorporateActionsCliOptions(parsed) {
2401
+ const options = {
2402
+ startDate: getOption(parsed, "start-date"),
2403
+ endDate: getOption(parsed, "end-date")
2404
+ };
2405
+ const limit = getOption(parsed, "limit");
2406
+ if (limit) {
2407
+ options.limit = parsePositiveInt(limit, "limit");
2408
+ }
2409
+ return options;
2410
+ }
2411
+ function buildEarningsCalendarCliOptions(parsed) {
2412
+ const ticker = getOption(parsed, "ticker");
2413
+ const tickersValue = getOption(parsed, "tickers");
2414
+ if (ticker && tickersValue) {
2415
+ throw new CliUsageError("Use either --ticker or --tickers, not both.");
2416
+ }
2417
+ const options = {
2418
+ ticker,
2419
+ startDate: getOption(parsed, "start-date"),
2420
+ endDate: getOption(parsed, "end-date")
2421
+ };
2422
+ if (tickersValue) {
2423
+ const tickers = parseCsvValues(tickersValue, "tickers");
2424
+ if (tickers.length > 10) {
2425
+ throw new CliUsageError("--tickers must contain between 1 and 10 values.");
2426
+ }
2427
+ options.tickers = tickers;
2428
+ }
2429
+ const limit = getOption(parsed, "limit");
2430
+ if (limit) {
2431
+ options.limit = parsePositiveInt(limit, "limit");
2432
+ }
2433
+ return options;
2434
+ }
2090
2435
  async function handleQuery(parsed, runtime, deps) {
2091
2436
  const resource = parsed.positionals[1];
2092
2437
  if (!resource) {
@@ -2103,8 +2448,11 @@ async function handleQuery(parsed, runtime, deps) {
2103
2448
  printJson(runtime, await client.getAvailableTickers());
2104
2449
  return 0;
2105
2450
  case "resolve-ticker": {
2106
- const query = requireOption(parsed, "query");
2107
- printJson(runtime, await client.resolveTicker(query));
2451
+ const querySelection = parseQuerySelection(parsed);
2452
+ printJson(
2453
+ runtime,
2454
+ querySelection.kind === "single" ? await client.resolveTicker(querySelection.query) : await client.resolveTickers(querySelection.queries)
2455
+ );
2108
2456
  return 0;
2109
2457
  }
2110
2458
  case "company": {
@@ -2219,16 +2567,14 @@ async function handleQuery(parsed, runtime, deps) {
2219
2567
  return 0;
2220
2568
  }
2221
2569
  case "financial-metrics-snapshot": {
2222
- const ticker = requireOption(parsed, "ticker");
2570
+ const tickerSelection = parseTickerSelection(parsed);
2223
2571
  const period = getOption(parsed, "period");
2572
+ const options = period ? {
2573
+ period: assertAcceptedValue(period, "period", FINANCIAL_PERIODS)
2574
+ } : void 0;
2224
2575
  printJson(
2225
2576
  runtime,
2226
- await client.getFinancialMetricsSnapshot(
2227
- ticker,
2228
- period ? {
2229
- period: assertAcceptedValue(period, "period", FINANCIAL_PERIODS)
2230
- } : void 0
2231
- )
2577
+ tickerSelection.kind === "single" ? await client.getFinancialMetricsSnapshot(tickerSelection.ticker, options) : await client.getBatchFinancialMetricsSnapshots(tickerSelection.tickers, options)
2232
2578
  );
2233
2579
  return 0;
2234
2580
  }
@@ -2260,6 +2606,10 @@ async function handleQuery(parsed, runtime, deps) {
2260
2606
  printJson(runtime, await client.getEarnings(ticker, options));
2261
2607
  return 0;
2262
2608
  }
2609
+ case "earnings-calendar": {
2610
+ printJson(runtime, await client.getEarningsCalendar(buildEarningsCalendarCliOptions(parsed)));
2611
+ return 0;
2612
+ }
2263
2613
  case "quarterly-highlights": {
2264
2614
  const ticker = requireOption(parsed, "ticker");
2265
2615
  const options = {};
@@ -2293,8 +2643,24 @@ async function handleQuery(parsed, runtime, deps) {
2293
2643
  return 0;
2294
2644
  }
2295
2645
  case "snapshot": {
2646
+ const tickerSelection = parseTickerSelection(parsed);
2647
+ printJson(
2648
+ runtime,
2649
+ tickerSelection.kind === "single" ? await client.getPriceSnapshot(tickerSelection.ticker) : await client.getBatchPriceSnapshots(tickerSelection.tickers)
2650
+ );
2651
+ return 0;
2652
+ }
2653
+ case "dividends": {
2654
+ const ticker = requireOption(parsed, "ticker");
2655
+ printJson(
2656
+ runtime,
2657
+ await client.getDividends(ticker, buildCorporateActionsCliOptions(parsed))
2658
+ );
2659
+ return 0;
2660
+ }
2661
+ case "splits": {
2296
2662
  const ticker = requireOption(parsed, "ticker");
2297
- printJson(runtime, await client.getPriceSnapshot(ticker));
2663
+ printJson(runtime, await client.getSplits(ticker, buildCorporateActionsCliOptions(parsed)));
2298
2664
  return 0;
2299
2665
  }
2300
2666
  case "news": {
@@ -156,6 +156,20 @@ interface PriceData {
156
156
  close: number;
157
157
  volume: number;
158
158
  }
159
+ interface DividendEventData {
160
+ ticker: string;
161
+ exDate: string;
162
+ amount: number;
163
+ refreshedAt: string;
164
+ }
165
+ interface SplitEventData {
166
+ ticker: string;
167
+ exDate: string;
168
+ numerator: number;
169
+ denominator: number;
170
+ splitRatio: string;
171
+ refreshedAt: string;
172
+ }
159
173
  interface CompanyFactsData {
160
174
  ticker: string;
161
175
  name: string;
@@ -208,6 +222,20 @@ interface KeyStatisticsData {
208
222
  shortPercentOfFloat: number | null;
209
223
  refreshedAt: string;
210
224
  }
225
+ interface EarningsCalendarEventData {
226
+ ticker: string;
227
+ source: string;
228
+ eventDateStart: string;
229
+ eventDateEnd: string | null;
230
+ sourceUrl: string | null;
231
+ epsEstimateAvg: number | null;
232
+ epsEstimateLow: number | null;
233
+ epsEstimateHigh: number | null;
234
+ revenueEstimateAvg: number | null;
235
+ revenueEstimateLow: number | null;
236
+ revenueEstimateHigh: number | null;
237
+ refreshedAt: string;
238
+ }
211
239
  interface AnalystEstimateData {
212
240
  ticker: string;
213
241
  periodLabel: string;
@@ -270,6 +298,8 @@ type CashFlowStatement = SnakeCasedProperties<CashFlowData>;
270
298
  type PriceBar = Omit<SnakeCasedProperties<PriceData>, "ticker">;
271
299
  type CompanyFacts = SnakeCasedProperties<CompanyFactsData>;
272
300
  type KeyStatistics = SnakeCasedProperties<KeyStatisticsData>;
301
+ type DividendEvent = Omit<SnakeCasedProperties<DividendEventData>, "ticker">;
302
+ type SplitEvent = Omit<SnakeCasedProperties<SplitEventData>, "ticker">;
273
303
  type DataAvailability = "ready" | "no_data";
274
304
  type ConsensusSurprise = "BEAT" | "MISS" | "MEET";
275
305
  interface FinancialMetricData {
@@ -393,6 +423,11 @@ interface NewsOpts {
393
423
  endDate?: string;
394
424
  publisher?: string;
395
425
  }
426
+ interface CorporateActionsOpts {
427
+ limit?: number;
428
+ startDate?: string;
429
+ endDate?: string;
430
+ }
396
431
  interface InsiderTradesOpts {
397
432
  limit?: number;
398
433
  startDate?: string;
@@ -422,6 +457,13 @@ interface FinancialMetricsOpts extends OptionalFinancialQueryOpts {
422
457
  }
423
458
  interface EarningsOpts extends OptionalFinancialQueryOpts {
424
459
  }
460
+ interface EarningsCalendarOpts {
461
+ ticker?: string;
462
+ tickers?: readonly string[];
463
+ startDate?: string;
464
+ endDate?: string;
465
+ limit?: number;
466
+ }
425
467
  interface QuarterlyHighlightsOpts {
426
468
  reportPeriod?: string;
427
469
  }
@@ -481,6 +523,20 @@ interface EarningsResponse extends ReadMetadata {
481
523
  period: FinancialPeriod;
482
524
  earnings: EarningsRow[];
483
525
  }
526
+ interface EarningsCalendarEvent extends SnakeCasedProperties<Omit<EarningsCalendarEventData, "refreshedAt">> {
527
+ name: string;
528
+ refreshed_at: string;
529
+ }
530
+ interface EarningsCalendarResponse {
531
+ availability: DataAvailability;
532
+ as_of: string | null;
533
+ count: number;
534
+ limit: number;
535
+ start_date: string;
536
+ end_date: string;
537
+ requested_tickers?: string[];
538
+ events: EarningsCalendarEvent[];
539
+ }
484
540
  interface KeyStatisticsResponse {
485
541
  ticker: string;
486
542
  availability: DataAvailability;
@@ -525,6 +581,33 @@ interface TickerResolutionResponse {
525
581
  resolved_name: string | null;
526
582
  candidates: TickerResolutionCandidate[];
527
583
  }
584
+ interface BatchNotFoundEntry {
585
+ status: "not_found";
586
+ ticker: string;
587
+ error: string;
588
+ details?: {
589
+ ticker_resolution?: TickerResolutionResponse;
590
+ };
591
+ }
592
+ type BatchPriceSnapshotEntry = ({
593
+ status: "ok";
594
+ } & PriceSnapshotResponse) | BatchNotFoundEntry;
595
+ interface BatchPriceSnapshotsResponse {
596
+ requested_tickers: string[];
597
+ results: Record<string, BatchPriceSnapshotEntry>;
598
+ }
599
+ type BatchFinancialMetricsSnapshotEntry = ({
600
+ status: "ok";
601
+ } & FinancialMetricsSnapshotResponse) | BatchNotFoundEntry;
602
+ interface BatchFinancialMetricsSnapshotsResponse {
603
+ period: FinancialPeriod;
604
+ requested_tickers: string[];
605
+ results: Record<string, BatchFinancialMetricsSnapshotEntry>;
606
+ }
607
+ interface BatchTickerResolutionResponse {
608
+ queries: string[];
609
+ results: Record<string, TickerResolutionResponse>;
610
+ }
528
611
  interface PriceHistoryResponse extends ReadMetadata {
529
612
  interval: PriceInterval;
530
613
  prices: PriceBar[];
@@ -532,6 +615,16 @@ interface PriceHistoryResponse extends ReadMetadata {
532
615
  interface NewsResponse extends ReadMetadata {
533
616
  news: NewsArticle[];
534
617
  }
618
+ interface DividendsResponse extends ReadMetadata {
619
+ count: number;
620
+ limit: number;
621
+ dividends: DividendEvent[];
622
+ }
623
+ interface SplitsResponse extends ReadMetadata {
624
+ count: number;
625
+ limit: number;
626
+ splits: SplitEvent[];
627
+ }
535
628
  interface InsiderTrade {
536
629
  filing_accession: string;
537
630
  filing_date: string;
@@ -824,9 +917,13 @@ declare class TnFinancialData {
824
917
  private buildFinancialParams;
825
918
  private buildGeneralOverviewParams;
826
919
  private buildOptionalFinancialParams;
920
+ private buildTickerBatchParams;
921
+ private buildRepeatedQueryParams;
827
922
  private buildSegmentedRevenueParams;
828
923
  private buildQuarterlyHighlightsParams;
924
+ private buildEarningsCalendarParams;
829
925
  private buildInsiderTradeParams;
926
+ private buildCorporateActionsParams;
830
927
  private buildFilingsParams;
831
928
  private buildFilingItemsParams;
832
929
  getIncomeStatements(ticker: string, opts: FinancialOpts): Promise<ApiResponse<IncomeStatementsResponse>>;
@@ -835,14 +932,20 @@ declare class TnFinancialData {
835
932
  getFinancials(ticker: string, opts: FinancialOpts): Promise<ApiResponse<FinancialsResponse>>;
836
933
  getFinancialMetrics(ticker: string, opts?: FinancialMetricsOpts): Promise<ApiResponse<FinancialMetricsResponse>>;
837
934
  getFinancialMetricsSnapshot(ticker: string, opts?: Pick<FinancialMetricsOpts, "period">): Promise<ApiResponse<FinancialMetricsSnapshotResponse>>;
935
+ getBatchFinancialMetricsSnapshots(tickers: readonly string[], opts?: Pick<FinancialMetricsOpts, "period">): Promise<ApiResponse<BatchFinancialMetricsSnapshotsResponse>>;
838
936
  getEarnings(ticker: string, opts?: EarningsOpts): Promise<ApiResponse<EarningsResponse>>;
937
+ getEarningsCalendar(opts?: EarningsCalendarOpts): Promise<ApiResponse<EarningsCalendarResponse>>;
839
938
  getGeneralOverview(ticker: string, opts?: GeneralOverviewOpts): Promise<ApiResponse<GeneralOverviewResponse>>;
840
939
  getKeyStatistics(ticker: string): Promise<ApiResponse<KeyStatisticsResponse>>;
841
940
  getAvailableTickers(): Promise<ApiResponse<AvailableTickersResponse>>;
842
941
  resolveTicker(query: string): Promise<ApiResponse<TickerResolutionResponse>>;
942
+ resolveTickers(queries: readonly string[]): Promise<ApiResponse<BatchTickerResolutionResponse>>;
843
943
  getPrices(ticker: string, opts: PriceOpts): Promise<ApiResponse<PriceHistoryResponse>>;
844
944
  getPriceSnapshot(ticker: string): Promise<ApiResponse<PriceSnapshotResponse>>;
945
+ getBatchPriceSnapshots(tickers: readonly string[]): Promise<ApiResponse<BatchPriceSnapshotsResponse>>;
845
946
  getNews(ticker: string, opts?: NewsOpts): Promise<ApiResponse<NewsResponse>>;
947
+ getDividends(ticker: string, opts?: CorporateActionsOpts): Promise<ApiResponse<DividendsResponse>>;
948
+ getSplits(ticker: string, opts?: CorporateActionsOpts): Promise<ApiResponse<SplitsResponse>>;
846
949
  getInsiderTrades(ticker: string, opts?: InsiderTradesOpts): Promise<ApiResponse<InsiderTradesResponse>>;
847
950
  getFilings(ticker: string, opts?: FilingsOpts): Promise<ApiResponse<FilingsResponse>>;
848
951
  getFilingItems(ticker: string, opts: FilingItemsOpts): Promise<ApiResponse<FilingItemsResponse>>;
@@ -859,4 +962,4 @@ declare class TnFinancialData {
859
962
  screen(request: ScreenerRequest): Promise<ApiResponse<ScreenerResponse>>;
860
963
  }
861
964
 
862
- export { type AnalystEstimate, type AnalystEstimatesResponse, type AnalystPriceTarget, ApiError, type ApiResponse, type AvailableTicker, type AvailableTickersResponse, type BalanceSheet, type BalanceSheetsResponse, type CashFlowStatement, type CashFlowStatementsResponse, type ClientOptions, type CompanyFacts, type ConsensusSurprise, DEFAULT_API_BASE_URL, type DataAvailability, type EarningsOpts, type EarningsResponse, type EarningsRow, type FilingExhibit, type FilingItemSection, type FilingItemsOpts, type FilingItemsResponse, type FilingMetadata, type FilingsOpts, type FilingsResponse, type FinancialMetric, type FinancialMetricsOpts, type FinancialMetricsResponse, type FinancialMetricsSnapshotResponse, type FinancialOpts, type FinancialsResponse, type GeneralOverviewFinancials, type GeneralOverviewNews, type GeneralOverviewOpts, type GeneralOverviewPriceSnapshot, type GeneralOverviewResponse, type GlobalInterestRateObservation, type GlobalInterestRateSeries, type GlobalInterestRatesOpts, type GlobalInterestRatesResponse, type IncomeStatement, type IncomeStatementsResponse, type InsiderTrade, type InsiderTradesOpts, type InsiderTradesResponse, type InstitutionalOwnershipEntry, type InstitutionalOwnershipOpts, type InstitutionalOwnershipResponse, type InvestorPortfolioHolding, type InvestorPortfolioInvestor, type InvestorPortfolioOpts, type InvestorPortfolioResponse, type InvestorPortfolioSummary, type KeyStatistics, type KeyStatisticsResponse, type NewsArticle, type NewsOpts, type NewsResponse, type OptionalFinancialQueryOpts, type PriceBar, type PriceHistoryResponse, type PriceOpts, type PriceSnapshot, type PriceSnapshotResponse, type QuarterlyHighlightsMetric, type QuarterlyHighlightsOpts, type QuarterlyHighlightsPayload, type QuarterlyHighlightsResponse, type RateLimitAnnotatedResponse, type RateLimitInfo, type ReadMetadata, type ReportPeriodFilterOpts, type ScreenerFieldMetadata, type ScreenerFieldsResponse, type ScreenerRequest, type ScreenerResponse, type ScreenerResultRow, type SegmentedRevenueItem, type SegmentedRevenuePeriod, type SegmentedRevenuesOpts, type SegmentedRevenuesResponse, type SnakeCase, type TickerResolutionCandidate, type TickerResolutionConfidence, type TickerResolutionIntent, type TickerResolutionMatchKind, type TickerResolutionRelationship, type TickerResolutionResponse, type TickerResolutionStatus, TnFinancialData };
965
+ export { type AnalystEstimate, type AnalystEstimatesResponse, type AnalystPriceTarget, ApiError, type ApiResponse, type AvailableTicker, type AvailableTickersResponse, type BalanceSheet, type BalanceSheetsResponse, type BatchFinancialMetricsSnapshotEntry, type BatchFinancialMetricsSnapshotsResponse, type BatchNotFoundEntry, type BatchPriceSnapshotEntry, type BatchPriceSnapshotsResponse, type BatchTickerResolutionResponse, type CashFlowStatement, type CashFlowStatementsResponse, type ClientOptions, type CompanyFacts, type ConsensusSurprise, type CorporateActionsOpts, DEFAULT_API_BASE_URL, type DataAvailability, type DividendEvent, type DividendsResponse, type EarningsCalendarEvent, type EarningsCalendarOpts, type EarningsCalendarResponse, type EarningsOpts, type EarningsResponse, type EarningsRow, type FilingExhibit, type FilingItemSection, type FilingItemsOpts, type FilingItemsResponse, type FilingMetadata, type FilingsOpts, type FilingsResponse, type FinancialMetric, type FinancialMetricsOpts, type FinancialMetricsResponse, type FinancialMetricsSnapshotResponse, type FinancialOpts, type FinancialsResponse, type GeneralOverviewFinancials, type GeneralOverviewNews, type GeneralOverviewOpts, type GeneralOverviewPriceSnapshot, type GeneralOverviewResponse, type GlobalInterestRateObservation, type GlobalInterestRateSeries, type GlobalInterestRatesOpts, type GlobalInterestRatesResponse, type IncomeStatement, type IncomeStatementsResponse, type InsiderTrade, type InsiderTradesOpts, type InsiderTradesResponse, type InstitutionalOwnershipEntry, type InstitutionalOwnershipOpts, type InstitutionalOwnershipResponse, type InvestorPortfolioHolding, type InvestorPortfolioInvestor, type InvestorPortfolioOpts, type InvestorPortfolioResponse, type InvestorPortfolioSummary, type KeyStatistics, type KeyStatisticsResponse, type NewsArticle, type NewsOpts, type NewsResponse, type OptionalFinancialQueryOpts, type PriceBar, type PriceHistoryResponse, type PriceOpts, type PriceSnapshot, type PriceSnapshotResponse, type QuarterlyHighlightsMetric, type QuarterlyHighlightsOpts, type QuarterlyHighlightsPayload, type QuarterlyHighlightsResponse, type RateLimitAnnotatedResponse, type RateLimitInfo, type ReadMetadata, type ReportPeriodFilterOpts, type ScreenerFieldMetadata, type ScreenerFieldsResponse, type ScreenerRequest, type ScreenerResponse, type ScreenerResultRow, type SegmentedRevenueItem, type SegmentedRevenuePeriod, type SegmentedRevenuesOpts, type SegmentedRevenuesResponse, type SnakeCase, type SplitEvent, type SplitsResponse, type TickerResolutionCandidate, type TickerResolutionConfidence, type TickerResolutionIntent, type TickerResolutionMatchKind, type TickerResolutionRelationship, type TickerResolutionResponse, type TickerResolutionStatus, TnFinancialData };
@@ -133,6 +133,26 @@ var TnFinancialData = class {
133
133
  this.appendReportPeriodParams(params, opts);
134
134
  return params.toString();
135
135
  }
136
+ buildTickerBatchParams(tickers, extra) {
137
+ const params = new URLSearchParams({
138
+ tickers: tickers.join(",")
139
+ });
140
+ if (extra) {
141
+ for (const [key, value] of Object.entries(extra)) {
142
+ if (value !== void 0) {
143
+ params.set(key, value);
144
+ }
145
+ }
146
+ }
147
+ return params.toString();
148
+ }
149
+ buildRepeatedQueryParams(key, values) {
150
+ const params = new URLSearchParams();
151
+ for (const value of values) {
152
+ params.append(key, value);
153
+ }
154
+ return params.toString();
155
+ }
136
156
  buildSegmentedRevenueParams(ticker, opts) {
137
157
  const params = new URLSearchParams({ ticker, period: opts.period });
138
158
  this.appendLimitParam(params, opts.limit);
@@ -145,6 +165,22 @@ var TnFinancialData = class {
145
165
  if (opts?.reportPeriod) params.set("report_period", opts.reportPeriod);
146
166
  return params.toString();
147
167
  }
168
+ buildEarningsCalendarParams(opts) {
169
+ const params = new URLSearchParams();
170
+ if (opts?.ticker && opts?.tickers && opts.tickers.length > 0) {
171
+ throw new Error("Use either ticker or tickers, not both.");
172
+ }
173
+ if (opts?.ticker) {
174
+ params.set("ticker", opts.ticker);
175
+ }
176
+ if (opts?.tickers && opts.tickers.length > 0) {
177
+ params.set("tickers", opts.tickers.join(","));
178
+ }
179
+ this.appendLimitParam(params, opts?.limit);
180
+ if (opts?.startDate) params.set("start_date", opts.startDate);
181
+ if (opts?.endDate) params.set("end_date", opts.endDate);
182
+ return params.toString();
183
+ }
148
184
  buildInsiderTradeParams(ticker, opts) {
149
185
  const params = new URLSearchParams({ ticker });
150
186
  this.appendLimitParam(params, opts?.limit);
@@ -157,6 +193,13 @@ var TnFinancialData = class {
157
193
  if (opts?.securityType) params.set("security_type", opts.securityType);
158
194
  return params.toString();
159
195
  }
196
+ buildCorporateActionsParams(ticker, opts) {
197
+ const params = new URLSearchParams({ ticker });
198
+ this.appendLimitParam(params, opts?.limit);
199
+ if (opts?.startDate) params.set("start_date", opts.startDate);
200
+ if (opts?.endDate) params.set("end_date", opts.endDate);
201
+ return params.toString();
202
+ }
160
203
  buildFilingsParams(ticker, opts) {
161
204
  const params = new URLSearchParams({ ticker });
162
205
  this.appendLimitParam(params, opts?.limit);
@@ -210,11 +253,24 @@ var TnFinancialData = class {
210
253
  `/financial-metrics/snapshot?${this.buildOptionalFinancialParams(ticker, opts)}`
211
254
  );
212
255
  }
256
+ async getBatchFinancialMetricsSnapshots(tickers, opts) {
257
+ return this.request(
258
+ `/financial-metrics/snapshot?${this.buildTickerBatchParams(tickers, {
259
+ period: opts?.period
260
+ })}`
261
+ );
262
+ }
213
263
  async getEarnings(ticker, opts) {
214
264
  return this.request(
215
265
  `/earnings?${this.buildOptionalFinancialParams(ticker, opts)}`
216
266
  );
217
267
  }
268
+ async getEarningsCalendar(opts) {
269
+ const params = this.buildEarningsCalendarParams(opts);
270
+ return this.request(
271
+ params.length > 0 ? `/earnings/calendar?${params}` : "/earnings/calendar"
272
+ );
273
+ }
218
274
  async getGeneralOverview(ticker, opts) {
219
275
  return this.request(
220
276
  `/general-overview?${this.buildGeneralOverviewParams(ticker, opts)}`
@@ -233,6 +289,11 @@ var TnFinancialData = class {
233
289
  `/tickers/resolve?${new URLSearchParams({ q: query })}`
234
290
  );
235
291
  }
292
+ async resolveTickers(queries) {
293
+ return this.request(
294
+ `/tickers/resolve/batch?${this.buildRepeatedQueryParams("query", queries)}`
295
+ );
296
+ }
236
297
  async getPrices(ticker, opts) {
237
298
  const params = new URLSearchParams({
238
299
  ticker,
@@ -247,6 +308,11 @@ var TnFinancialData = class {
247
308
  `/prices/snapshot?${new URLSearchParams({ ticker })}`
248
309
  );
249
310
  }
311
+ async getBatchPriceSnapshots(tickers) {
312
+ return this.request(
313
+ `/prices/snapshot?${this.buildTickerBatchParams(tickers)}`
314
+ );
315
+ }
250
316
  async getNews(ticker, opts) {
251
317
  const params = new URLSearchParams({ ticker });
252
318
  if (opts?.limit !== void 0) params.set("limit", String(opts.limit));
@@ -255,6 +321,16 @@ var TnFinancialData = class {
255
321
  if (opts?.publisher) params.set("publisher", opts.publisher);
256
322
  return this.request(`/news?${params}`);
257
323
  }
324
+ async getDividends(ticker, opts) {
325
+ return this.request(
326
+ `/corporate-actions/dividends?${this.buildCorporateActionsParams(ticker, opts)}`
327
+ );
328
+ }
329
+ async getSplits(ticker, opts) {
330
+ return this.request(
331
+ `/corporate-actions/splits?${this.buildCorporateActionsParams(ticker, opts)}`
332
+ );
333
+ }
258
334
  async getInsiderTrades(ticker, opts) {
259
335
  return this.request(
260
336
  `/insider-trades?${this.buildInsiderTradeParams(ticker, opts)}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tn-financial-data",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Hosted US equity financial data and SEC filings CLI and client for agents",
5
5
  "keywords": [
6
6
  "agent",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tn-financial-data
3
- description: Use this skill first for covered US equity data questions and covered-universe screens. Query server-backed company facts, general overviews, financials, analyst estimates, segmented revenues, prices, news, insider trades, institutional ownership, investor 13F portfolios, raw SEC filings, and global interest rates through the tn-financial-data CLI.
3
+ description: Use this skill first for covered US equity data questions and covered-universe screens. Query server-backed company facts, general overviews, financials, analyst estimates, segmented revenues, prices, corporate actions, news, insider trades, institutional ownership, investor 13F portfolios, raw SEC filings, and global interest rates through the tn-financial-data CLI.
4
4
  license: MIT
5
5
  ---
6
6
 
@@ -25,7 +25,7 @@ Covered reads include:
25
25
  - financial statements, derived financial metrics, earnings, and analyst estimates
26
26
  - quarterly highlights, including issuer-reported release metrics when available and generic latest-quarter summaries otherwise
27
27
  - segment and geographic revenue mix
28
- - price history, latest price snapshot, and stored company news
28
+ - price history, latest price snapshot, stored dividends and splits, and stored company news
29
29
  - insider trades, issuer-level institutional ownership, and investor `13F` portfolios
30
30
  - SEC filing discovery plus bounded raw filing text for `10-K`, `10-Q`, and `8-K`
31
31
  - covered-universe screening and ranking
@@ -62,6 +62,7 @@ These are the main commands an agent should reach for first. For full flags and
62
62
 
63
63
  ```bash
64
64
  tn-financial-data query resolve-ticker --query google
65
+ tn-financial-data query resolve-ticker --query google --query meta --query nvda
65
66
  tn-financial-data query available-tickers
66
67
  tn-financial-data query company --ticker AAPL
67
68
  tn-financial-data query general-overview --ticker AAPL
@@ -69,6 +70,7 @@ tn-financial-data query financials --ticker AAPL --period annual --statement all
69
70
  tn-financial-data query financial-metrics --ticker AAPL --period annual --limit 4
70
71
  tn-financial-data query financial-metrics-snapshot --ticker AAPL
71
72
  tn-financial-data query earnings --ticker AAPL --period quarterly --limit 8
73
+ tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16
72
74
  tn-financial-data query quarterly-highlights --ticker AAPL
73
75
  tn-financial-data query filings --ticker AAPL --filing-type 8-K --limit 10
74
76
  tn-financial-data query filing-items --ticker AAPL --accession-number 0000320193-26-000005 --item 2.02 --include-exhibits
@@ -76,6 +78,8 @@ tn-financial-data query analyst-estimates --ticker AAPL
76
78
  tn-financial-data query segmented-revenues --ticker AAPL --period annual --limit 4
77
79
  tn-financial-data query prices --ticker AAPL --interval day --start-date 2025-01-01 --end-date 2025-01-31
78
80
  tn-financial-data query snapshot --ticker AAPL
81
+ tn-financial-data query dividends --ticker AAPL --limit 20
82
+ tn-financial-data query splits --ticker AAPL --limit 20
79
83
  tn-financial-data query news --ticker AAPL --limit 20
80
84
  tn-financial-data query insider-trades --ticker AAPL --transaction-code P,S --limit 25
81
85
  tn-financial-data query institutional-ownership --ticker AAPL --limit 20
@@ -89,10 +93,12 @@ Practical defaults:
89
93
 
90
94
  - Use `general-overview` for broad one-ticker prompts like “what’s up with NVDA?”
91
95
  - Use `resolve-ticker` first when the user gives a company name, brand name, or broad one-company phrase without a trusted symbol
96
+ - Repeat `--query` on `resolve-ticker` when the user gives multiple ambiguous company names and you need to normalize them before batch comparisons
97
+ - Use `earnings-calendar` for upcoming date-window questions like “what earnings are coming up this week?” or “show me the next AAPL and MSFT earnings dates”
92
98
  - Use `quarterly-highlights` first for Apple product mix, Greater China, Meta ad KPIs, Amazon segment profitability, and Tesla services-and-other or free-cash-flow prompts
93
99
  - Use `filings` plus `filing-items` when the user explicitly asks for an SEC filing, `8-K`, `10-K`, `10-Q`, or raw filing text
94
100
  - Do not start Apple product-mix prompts with `segmented-revenues`; that surface only exposes broad `Product` and `Service` rollups, while `quarterly-highlights` carries the product-line fields the prompt usually wants
95
- - Use `financials`, `financial-metrics`, `earnings`, `analyst-estimates`, `segmented-revenues`, `news`, `prices`, or `snapshot` when the user asks for a specific slice
101
+ - Use `financials`, `financial-metrics`, `earnings`, `analyst-estimates`, `segmented-revenues`, `prices`, `snapshot`, `dividends`, `splits`, or `news` when the user asks for a specific slice
96
102
  - Use `investor-portfolio` for prompts like “What does Vanguard hold?” or “Show Berkshire’s latest 13F portfolio.”
97
103
  - Use `global-rates` for central-bank and rate-comparison prompts
98
104
 
@@ -26,6 +26,7 @@ Resolve ticker:
26
26
  ```bash
27
27
  tn-financial-data query resolve-ticker --query google
28
28
  tn-financial-data query resolve-ticker --query GOOGL
29
+ tn-financial-data query resolve-ticker --query google --query meta --query nvda
29
30
  ```
30
31
 
31
32
  Use this to resolve a company keyword, brand name, prompt fragment, or exact symbol against the hosted supported universe.
@@ -33,6 +34,7 @@ Use this to resolve a company keyword, brand name, prompt fragment, or exact sym
33
34
  Resolution semantics:
34
35
  - returns one of `exact_supported`, `resolved`, `ambiguous`, `exact_unsupported`, or `none`
35
36
  - use this before guessing a ticker from a company or brand prompt
37
+ - repeat `--query` when you need to normalize several ambiguous inputs before calling a batch snapshot read
36
38
  - `exact_unsupported` can suggest a nearby supported line, but that suggestion is a hint, not an automatic substitution
37
39
  - exact share-class mismatches must stay explicit to the user
38
40
 
@@ -133,6 +135,19 @@ Meaning:
133
135
  - if no matching quarterly statement exists for a reported quarter, the row still appears but statement-derived fields can be `null`
134
136
  - do not use Yahoo key-statistics growth fields as a substitute for statement-line YoY when the question is about revenue, operating income, net income, or EPS
135
137
 
138
+ Earnings calendar:
139
+
140
+ ```bash
141
+ tn-financial-data query earnings-calendar --tickers AAPL,MSFT --start-date 2026-04-02 --end-date 2026-04-16
142
+ tn-financial-data query earnings-calendar --ticker AAPL
143
+ ```
144
+
145
+ Meaning:
146
+ - upcoming date-window view over stored Yahoo-backed earnings calendar events
147
+ - use it for prompts like “what earnings are coming up this week?” or “show me the next Apple and Microsoft earnings dates”
148
+ - omit ticker filters to scan the whole covered universe
149
+ - `event_date_start` is the earliest announced date and `event_date_end` is only present when Yahoo returns a date range
150
+
136
151
  Quarterly highlights:
137
152
 
138
153
  ```bash
@@ -207,6 +222,18 @@ Snapshot:
207
222
  tn-financial-data query snapshot --ticker AAPL
208
223
  ```
209
224
 
225
+ Corporate actions:
226
+
227
+ ```bash
228
+ tn-financial-data query dividends --ticker AAPL --limit 20
229
+ tn-financial-data query splits --ticker AAPL --limit 20
230
+ ```
231
+
232
+ Meaning:
233
+ - use `dividends` for stored dividend ex-date rows and `splits` for stored stock-split rows
234
+ - both support optional `--start-date`, `--end-date`, and `--limit`
235
+ - use these when the user asks about payout timing, split history, or recent capital-return events that are already captured in the Yahoo price ingest
236
+
210
237
  News:
211
238
 
212
239
  ```bash