sentisense 0.54.0 → 0.55.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
@@ -174,9 +174,9 @@ Affected: every method whose declared return type is `PreviewResponse<T>`. A tes
174
174
 
175
175
  | Namespace | Methods |
176
176
  |-----------|---------|
177
- | `analyst` | `consensus` `actions` `estimates` `marketActivity` `coverage` `profile` `calls` |
177
+ | `analyst` | `consensus` `consensusHistory` `calledIt` `actions` `estimates` `marketActivity` `coverage` `profile` `calls` |
178
178
  | `calendar` | `getEarnings` |
179
- | `earnings` | `getSummaries` `getRecent` |
179
+ | `earnings` | `getSummaries` `getRecent` `getStatistics` `getRanked` |
180
180
  | `etfs` | `analystAggregate` `insiderAggregate` `sentimentAggregate` |
181
181
  | `insider` | `getActivity` `getTrades` `getClusterBuys` |
182
182
  | `insights` | `stock` `stockRange` `market` `latest` `user` |
@@ -364,6 +364,8 @@ The price target cone (mean, high, low, upside %) and consensus are free for eve
364
364
 
365
365
  ```typescript
366
366
  client.analyst.consensus("AAPL") // Price target cone + consensus. Free, full data.
367
+ client.analyst.consensusHistory("AAPL", { limit: 90 }) // Daily history. Free: last 30 days; distribution fields null.
368
+ client.analyst.calledIt("AAPL", { limit: 10 }) // Recorded calls for 20% moves over five sessions. Free: newest move, up to 5 calls, move counts intact.
367
369
  client.analyst.actions("AAPL", { lookbackDays: 30 }) // Upgrade/downgrade feed. Free: 3 most recent.
368
370
  client.analyst.estimates("AAPL") // Forward EPS + surprises. Free: 1 quarter.
369
371
  client.analyst.marketActivity({ lookbackDays: 7 }) // Market-wide analyst actions (PRO).
@@ -411,11 +413,14 @@ Two shapes to read rather than assume. A firm can appear with `noteCount: 0`, a
411
413
 
412
414
  ### Earnings
413
415
 
414
- The earnings analysis report is the assembled version of a quarter: one object per fiscal period carrying the editorial headline, the KPI cards with year-over-year deltas, the guidance language as management phrased it, and a summary of the earnings call. Pair it with the recent-reporters feed to drive a post-earnings sweep. Both return the preview envelope.
416
+ The earnings analysis report is the assembled version of a quarter: one object per fiscal period carrying the editorial headline, the KPI cards with year-over-year deltas, the guidance language as management phrased it, and a summary of the earnings call. Pair it with the recent-reporters feed to drive a post-earnings sweep. Summaries, recent reports, statistics, and rankings return the preview envelope; per-ticker reactions return a direct payload.
415
417
 
416
418
  ```typescript
417
419
  client.earnings.getSummaries("AAPL", { limit: 4 }) // Per-quarter analysis, newest first. Free: latest quarter, shaped.
418
420
  client.earnings.getRecent({ days: 7, limit: 25 }) // Who reported in the last N days. Full window on every key.
421
+ client.earnings.getReactions("AAPL") // Up to twelve measured post-report moves. Full series on every key.
422
+ client.earnings.getStatistics({ window: "week_to_date" }) // Market-wide outcomes, reaction rates, baseline, and coverage.
423
+ client.earnings.getRanked({ reportedDays: 14, upcomingDays: 7 }) // Free: first 3 rows per section. PRO: full ranking.
419
424
  ```
420
425
 
421
426
  ```typescript
@@ -476,7 +481,7 @@ client.entityMetrics.getDistribution("AAPL", "sentiment")
476
481
  client.entityMetrics.getDistribution("AAPL", "mentions", { dimension: "source" })
477
482
  ```
478
483
 
479
- Available metric types: `mentions`, `sentiment`, `sentisense_score`, `sentisense_rating`, `social_dominance`, `creators`. `sentisense_rating` is the SentiSense Rating score and is a time series only: it has no source breakdown, so `getDistribution` answers with an empty distribution for it.
484
+ Available metric types: `mentions`, `sentiment`, `sentisense_score`, `sentisense_rating`, `social_dominance`, `creators`. `sentisense` is an alias for `sentisense_score`; either spelling returns the same series, and keys are case-insensitive. Responses always name the canonical type, so a `sentisense` request answers with `SENTISENSE_SCORE`. `sentisense_rating` is the SentiSense Rating score and is a time series only: it has no source breakdown, so `getDistribution` answers with an empty distribution for it.
480
485
 
481
486
  ### Options
482
487
 
package/dist/cli.cjs CHANGED
@@ -36,6 +36,13 @@ var RateLimitError = class extends SentiSenseError {
36
36
  this.retryAfter = retryAfter;
37
37
  }
38
38
  };
39
+ var TemporarilyUnavailableError = class extends SentiSenseError {
40
+ constructor(message, retryAfter, code) {
41
+ super(message, 503, code);
42
+ this.name = "TemporarilyUnavailableError";
43
+ this.retryAfter = retryAfter;
44
+ }
45
+ };
39
46
  var APIError = class extends SentiSenseError {
40
47
  constructor(message, status, code) {
41
48
  super(message, status, code);
@@ -1324,7 +1331,7 @@ var flowsCommand = {
1324
1331
  };
1325
1332
 
1326
1333
  // src/version.ts
1327
- var VERSION = "0.54.0";
1334
+ var VERSION = "0.55.0";
1328
1335
 
1329
1336
  // src/resources/analyst.ts
1330
1337
  var Analyst = class {
@@ -1340,6 +1347,38 @@ var Analyst = class {
1340
1347
  `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/consensus`
1341
1348
  );
1342
1349
  }
1350
+ /**
1351
+ * Get daily consensus observations, ordered by `snapshotDate` ascending.
1352
+ * Each row describes the target fields as observed on that date. When
1353
+ * `countsObserved` is `false`, the vendor panel did not come back that day and the
1354
+ * distribution counts are carried forward.
1355
+ *
1356
+ * A PRO key receives the requested window. A FREE key receives the last 30 days;
1357
+ * `targetMedian`, `recommendationMean`, and the five distribution fields are `null`.
1358
+ * The envelope's `totalCount` still sizes the full requested window.
1359
+ */
1360
+ async consensusHistory(ticker, options) {
1361
+ return this.client.get(
1362
+ `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/consensus/history`,
1363
+ options
1364
+ );
1365
+ }
1366
+ /**
1367
+ * Get factual call history as recorded when a stock moved 20% or more over five
1368
+ * sessions, newest move first by `moveEndDate`.
1369
+ *
1370
+ * PRO receives full moves and calls. FREE receives the newest move with up to five
1371
+ * calls and all move-level counts intact. The envelope's `totalCount` counts all
1372
+ * available moves before the limit. A known stock with no qualifying move returns
1373
+ * an empty `moves` array. Each call includes `analystName`: it is `null`, never
1374
+ * absent, when the publisher named nobody.
1375
+ */
1376
+ async calledIt(ticker, options) {
1377
+ return this.client.get(
1378
+ `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/called-it`,
1379
+ options
1380
+ );
1381
+ }
1343
1382
  /**
1344
1383
  * Get recent analyst upgrade/downgrade actions for a ticker, newest first.
1345
1384
  * Free users receive the 3 most recent.
@@ -1572,6 +1611,52 @@ var Earnings = class {
1572
1611
  async getRecent(options) {
1573
1612
  return this.client.get("/api/v1/earnings/recent", options);
1574
1613
  }
1614
+ /**
1615
+ * Measured price reactions to a ticker's last earnings reports, newest first.
1616
+ *
1617
+ * Use this after {@link getRecent} when you need one company's realized
1618
+ * post-report history. `client.calendar.getEarnings()` is the forward-looking
1619
+ * schedule instead. This endpoint returns its payload directly, without a
1620
+ * preview envelope, and every API key receives the full series.
1621
+ *
1622
+ * `timing` is always present on each row and can be `null` when the reacting
1623
+ * session was inferred rather than observed.
1624
+ */
1625
+ async getReactions(ticker) {
1626
+ return this.client.get(
1627
+ `/api/v1/stocks/${encodeURIComponent(ticker.toUpperCase())}/earnings/reactions`
1628
+ );
1629
+ }
1630
+ /**
1631
+ * Market-wide earnings outcomes and realized reaction statistics.
1632
+ *
1633
+ * Use this for aggregate beat, miss, inline, and post-report move rates.
1634
+ * {@link getRecent} returns individual recent reports, while
1635
+ * `client.calendar.getEarnings()` covers upcoming dates. The response uses
1636
+ * the preview envelope, but every API key receives the full body and
1637
+ * `isPreview` is always `false`.
1638
+ *
1639
+ * `baseline` and `deviation` are omitted for long-span windows, and rates can
1640
+ * be `null` when their denominator is zero.
1641
+ */
1642
+ async getStatistics(options) {
1643
+ return this.client.get("/api/v1/earnings/statistics", options);
1644
+ }
1645
+ /**
1646
+ * Important recently reported and upcoming earnings in one ranking.
1647
+ *
1648
+ * Use this to prioritize a cross-ticker sweep. Follow reported rows with
1649
+ * {@link getReactions} for realized history; use {@link getRecent} for an
1650
+ * unranked recent feed or `client.calendar.getEarnings()` for the broader
1651
+ * forward schedule.
1652
+ *
1653
+ * A PRO key receives the full ranking. A FREE key receives the first three
1654
+ * rows in each section with `totalInWindow` left intact. Optional row fields
1655
+ * are omitted when null, so check them before use.
1656
+ */
1657
+ async getRanked(options) {
1658
+ return this.client.get("/api/v1/earnings/ranked", options);
1659
+ }
1575
1660
  };
1576
1661
 
1577
1662
  // src/resources/entityMetrics.ts
@@ -2300,7 +2385,7 @@ var Stocks = class {
2300
2385
  * the full series. Returns 404 for tickers that do not yet have curated coverage.
2301
2386
  *
2302
2387
  * Coverage today: near-complete for the S&P 500 plus extended universe
2303
- * (~500 tickers). Use `listKpiCoverage()` to enumerate.
2388
+ * (900+ tickers). Use `listKpiCoverage()` to enumerate.
2304
2389
  */
2305
2390
  async getKpis(ticker) {
2306
2391
  return this.client.get(
@@ -2597,12 +2682,23 @@ var SentiSense = class {
2597
2682
  if (!response.ok) {
2598
2683
  const isRetryable = response.status === 429 || response.status >= 500;
2599
2684
  if (isRetryable && attempt < this.maxRetries) {
2600
- if (response.status === 429) {
2601
- delayMs = retryAfterSeconds(
2685
+ if (response.status === 429 || response.status === 503) {
2686
+ const requestedS = retryAfterSeconds(
2602
2687
  response.headers.get("Retry-After"),
2603
2688
  RATE_LIMIT_FALLBACK_WAIT_S,
2604
- MAX_RATE_LIMIT_WAIT_S
2605
- ) * 1e3;
2689
+ Number.POSITIVE_INFINITY
2690
+ );
2691
+ if (requestedS > MAX_RATE_LIMIT_WAIT_S) {
2692
+ try {
2693
+ await response.body?.cancel();
2694
+ } catch {
2695
+ }
2696
+ throw new TemporarilyUnavailableError(
2697
+ `Server asked for a ${Math.round(requestedS)}s wait, longer than this client's ${MAX_RATE_LIMIT_WAIT_S}s budget`,
2698
+ requestedS
2699
+ );
2700
+ }
2701
+ delayMs = requestedS * 1e3;
2606
2702
  } else {
2607
2703
  delayMs = Math.min(BASE_DELAY_MS * Math.pow(2, attempt), MAX_DELAY_MS) + Math.random() * 1e3;
2608
2704
  }
package/dist/index.cjs CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  RateLimitError: () => RateLimitError,
28
28
  SentiSense: () => SentiSense,
29
29
  SentiSenseError: () => SentiSenseError,
30
+ TemporarilyUnavailableError: () => TemporarilyUnavailableError,
30
31
  VERSION: () => VERSION,
31
32
  default: () => SentiSense
32
33
  });
@@ -67,6 +68,13 @@ var RateLimitError = class extends SentiSenseError {
67
68
  this.retryAfter = retryAfter;
68
69
  }
69
70
  };
71
+ var TemporarilyUnavailableError = class extends SentiSenseError {
72
+ constructor(message, retryAfter, code) {
73
+ super(message, 503, code);
74
+ this.name = "TemporarilyUnavailableError";
75
+ this.retryAfter = retryAfter;
76
+ }
77
+ };
70
78
  var APIError = class extends SentiSenseError {
71
79
  constructor(message, status, code) {
72
80
  super(message, status, code);
@@ -88,6 +96,38 @@ var Analyst = class {
88
96
  `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/consensus`
89
97
  );
90
98
  }
99
+ /**
100
+ * Get daily consensus observations, ordered by `snapshotDate` ascending.
101
+ * Each row describes the target fields as observed on that date. When
102
+ * `countsObserved` is `false`, the vendor panel did not come back that day and the
103
+ * distribution counts are carried forward.
104
+ *
105
+ * A PRO key receives the requested window. A FREE key receives the last 30 days;
106
+ * `targetMedian`, `recommendationMean`, and the five distribution fields are `null`.
107
+ * The envelope's `totalCount` still sizes the full requested window.
108
+ */
109
+ async consensusHistory(ticker, options) {
110
+ return this.client.get(
111
+ `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/consensus/history`,
112
+ options
113
+ );
114
+ }
115
+ /**
116
+ * Get factual call history as recorded when a stock moved 20% or more over five
117
+ * sessions, newest move first by `moveEndDate`.
118
+ *
119
+ * PRO receives full moves and calls. FREE receives the newest move with up to five
120
+ * calls and all move-level counts intact. The envelope's `totalCount` counts all
121
+ * available moves before the limit. A known stock with no qualifying move returns
122
+ * an empty `moves` array. Each call includes `analystName`: it is `null`, never
123
+ * absent, when the publisher named nobody.
124
+ */
125
+ async calledIt(ticker, options) {
126
+ return this.client.get(
127
+ `/api/v1/analyst/${encodeURIComponent(ticker.toUpperCase())}/called-it`,
128
+ options
129
+ );
130
+ }
91
131
  /**
92
132
  * Get recent analyst upgrade/downgrade actions for a ticker, newest first.
93
133
  * Free users receive the 3 most recent.
@@ -320,6 +360,52 @@ var Earnings = class {
320
360
  async getRecent(options) {
321
361
  return this.client.get("/api/v1/earnings/recent", options);
322
362
  }
363
+ /**
364
+ * Measured price reactions to a ticker's last earnings reports, newest first.
365
+ *
366
+ * Use this after {@link getRecent} when you need one company's realized
367
+ * post-report history. `client.calendar.getEarnings()` is the forward-looking
368
+ * schedule instead. This endpoint returns its payload directly, without a
369
+ * preview envelope, and every API key receives the full series.
370
+ *
371
+ * `timing` is always present on each row and can be `null` when the reacting
372
+ * session was inferred rather than observed.
373
+ */
374
+ async getReactions(ticker) {
375
+ return this.client.get(
376
+ `/api/v1/stocks/${encodeURIComponent(ticker.toUpperCase())}/earnings/reactions`
377
+ );
378
+ }
379
+ /**
380
+ * Market-wide earnings outcomes and realized reaction statistics.
381
+ *
382
+ * Use this for aggregate beat, miss, inline, and post-report move rates.
383
+ * {@link getRecent} returns individual recent reports, while
384
+ * `client.calendar.getEarnings()` covers upcoming dates. The response uses
385
+ * the preview envelope, but every API key receives the full body and
386
+ * `isPreview` is always `false`.
387
+ *
388
+ * `baseline` and `deviation` are omitted for long-span windows, and rates can
389
+ * be `null` when their denominator is zero.
390
+ */
391
+ async getStatistics(options) {
392
+ return this.client.get("/api/v1/earnings/statistics", options);
393
+ }
394
+ /**
395
+ * Important recently reported and upcoming earnings in one ranking.
396
+ *
397
+ * Use this to prioritize a cross-ticker sweep. Follow reported rows with
398
+ * {@link getReactions} for realized history; use {@link getRecent} for an
399
+ * unranked recent feed or `client.calendar.getEarnings()` for the broader
400
+ * forward schedule.
401
+ *
402
+ * A PRO key receives the full ranking. A FREE key receives the first three
403
+ * rows in each section with `totalInWindow` left intact. Optional row fields
404
+ * are omitted when null, so check them before use.
405
+ */
406
+ async getRanked(options) {
407
+ return this.client.get("/api/v1/earnings/ranked", options);
408
+ }
323
409
  };
324
410
 
325
411
  // src/resources/entityMetrics.ts
@@ -1048,7 +1134,7 @@ var Stocks = class {
1048
1134
  * the full series. Returns 404 for tickers that do not yet have curated coverage.
1049
1135
  *
1050
1136
  * Coverage today: near-complete for the S&P 500 plus extended universe
1051
- * (~500 tickers). Use `listKpiCoverage()` to enumerate.
1137
+ * (900+ tickers). Use `listKpiCoverage()` to enumerate.
1052
1138
  */
1053
1139
  async getKpis(ticker) {
1054
1140
  return this.client.get(
@@ -1249,7 +1335,7 @@ var Trackers = class {
1249
1335
  };
1250
1336
 
1251
1337
  // src/version.ts
1252
- var VERSION = "0.54.0";
1338
+ var VERSION = "0.55.0";
1253
1339
 
1254
1340
  // src/client.ts
1255
1341
  var DEFAULT_BASE_URL = "https://app.sentisense.ai";
@@ -1348,12 +1434,23 @@ var SentiSense = class {
1348
1434
  if (!response.ok) {
1349
1435
  const isRetryable = response.status === 429 || response.status >= 500;
1350
1436
  if (isRetryable && attempt < this.maxRetries) {
1351
- if (response.status === 429) {
1352
- delayMs = retryAfterSeconds(
1437
+ if (response.status === 429 || response.status === 503) {
1438
+ const requestedS = retryAfterSeconds(
1353
1439
  response.headers.get("Retry-After"),
1354
1440
  RATE_LIMIT_FALLBACK_WAIT_S,
1355
- MAX_RATE_LIMIT_WAIT_S
1356
- ) * 1e3;
1441
+ Number.POSITIVE_INFINITY
1442
+ );
1443
+ if (requestedS > MAX_RATE_LIMIT_WAIT_S) {
1444
+ try {
1445
+ await response.body?.cancel();
1446
+ } catch {
1447
+ }
1448
+ throw new TemporarilyUnavailableError(
1449
+ `Server asked for a ${Math.round(requestedS)}s wait, longer than this client's ${MAX_RATE_LIMIT_WAIT_S}s budget`,
1450
+ requestedS
1451
+ );
1452
+ }
1453
+ delayMs = requestedS * 1e3;
1357
1454
  } else {
1358
1455
  delayMs = Math.min(BASE_DELAY_MS * Math.pow(2, attempt), MAX_DELAY_MS) + Math.random() * 1e3;
1359
1456
  }
@@ -1464,6 +1561,7 @@ var SentiSense = class {
1464
1561
  RateLimitError,
1465
1562
  SentiSense,
1466
1563
  SentiSenseError,
1564
+ TemporarilyUnavailableError,
1467
1565
  VERSION
1468
1566
  });
1469
1567
  //# sourceMappingURL=index.cjs.map