sentisense 0.11.0 → 0.15.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/dist/index.d.mts CHANGED
@@ -6,16 +6,31 @@ interface SentiSenseOptions {
6
6
  }
7
7
  interface StockPrice {
8
8
  ticker: string;
9
+ /** Regular-session price. During RTH: live last trade. Otherwise: most recent RTH close. */
9
10
  price: number;
10
11
  change: number;
11
12
  changePercent: number;
12
13
  previousClose: number;
13
14
  /** Unix timestamp in milliseconds of the price quote. */
14
15
  timestamp: number;
16
+ /** Extended-hours view (pre-market or after-hours). Null/absent during RTH, overnight, and weekends. */
17
+ extendedHours?: ExtendedHoursInfo | null;
18
+ }
19
+ /**
20
+ * Extended-hours session view embedded in price / quote responses when the snapshot sees
21
+ * pre-market (04:00–09:30 ET) or after-hours (16:00–20:00 ET) activity. `change` and
22
+ * `changePercent` are computed by the server vs the regular-session `currentPrice`.
23
+ */
24
+ interface ExtendedHoursInfo {
25
+ session: "pre" | "post";
26
+ price: number;
27
+ change: number;
28
+ changePercent: number;
15
29
  }
16
30
  /** Aggregate quote snapshot from GET /api/v1/stocks/{ticker}/quote. */
17
31
  interface StockQuote {
18
32
  ticker: string;
33
+ /** Regular-session price. During RTH: live last trade. Otherwise: most recent RTH close. */
19
34
  currentPrice: number | null;
20
35
  change: number | null;
21
36
  changePercent: number | null;
@@ -31,7 +46,8 @@ interface StockQuote {
31
46
  epsTTM: number | null;
32
47
  dividendYield: number | null;
33
48
  timestamp: number | null;
34
- extendedHours: boolean | null;
49
+ /** Extended-hours view (pre-market or after-hours). Null/absent during RTH, overnight, and weekends. */
50
+ extendedHours?: ExtendedHoursInfo | null;
35
51
  }
36
52
  interface StockDetail {
37
53
  ticker: string;
@@ -67,12 +83,20 @@ interface StockEntity {
67
83
  [key: string]: unknown;
68
84
  }
69
85
  interface ChartDataPoint {
86
+ /** Unix timestamp in milliseconds. */
87
+ timestamp?: number;
70
88
  date: string;
71
89
  open: number;
72
90
  high: number;
73
91
  low: number;
74
92
  close: number;
75
93
  volume: number;
94
+ /**
95
+ * US-equity market session: "pre" (04:00–09:30 ET), "regular" (09:30–16:00 ET),
96
+ * or "post" (16:00–20:00 ET). Populated for intraday timeframes (1D / 5D / 1W / 1M);
97
+ * `null` for daily / weekly bars (3M and longer) that span whole sessions.
98
+ */
99
+ session?: "pre" | "regular" | "post" | null;
76
100
  }
77
101
  interface ChartData {
78
102
  ticker: string;
@@ -112,7 +136,7 @@ interface AISummary {
112
136
  [key: string]: unknown;
113
137
  }
114
138
  interface GetChartOptions {
115
- timeframe?: "1M" | "3M" | "6M" | "1Y";
139
+ timeframe?: "1D" | "5D" | "1W" | "1M" | "3M" | "6M" | "1Y" | "ALL";
116
140
  }
117
141
  interface GetImagesOptions {
118
142
  forced?: boolean;
@@ -173,8 +197,8 @@ interface Story {
173
197
  tickers: string[];
174
198
  primaryEntityNames: string[];
175
199
  impactScore: number;
176
- /** Unix timestamp in seconds when the story first broke. */
177
- brokeAt: number;
200
+ /** Unix timestamp in seconds when the story first broke. Null when the story has no representative document timestamp yet. */
201
+ brokeAt: number | null;
178
202
  }
179
203
  interface GetByTickerOptions {
180
204
  source?: DocumentSource;
@@ -701,6 +725,163 @@ declare class EntityMetrics {
701
725
  getAverageSentiment(symbol: string, options?: EntityMetricsDateRange): Promise<SentimentData>;
702
726
  }
703
727
 
728
+ interface EtfInfo {
729
+ ticker: string;
730
+ name: string;
731
+ kbEntityId: string | null;
732
+ urlSlug: string | null;
733
+ issuer: string | null;
734
+ trackedIndex: string | null;
735
+ assetClass: string | null;
736
+ }
737
+ interface EtfHolding {
738
+ ticker: string;
739
+ name: string | null;
740
+ /** Weight in the fund as a percentage (0-100). */
741
+ weight_pct: number;
742
+ /** First date this holding appeared in the composition. */
743
+ first_seen: string | null;
744
+ }
745
+ interface EtfHoldings {
746
+ ticker: string;
747
+ issuer: string;
748
+ issuer_endpoint: string | null;
749
+ as_of_date: string;
750
+ fetched_at: string;
751
+ next_refresh_due: string;
752
+ total_holdings: number;
753
+ holdings: EtfHolding[];
754
+ /** True when this is a top-N view rather than the full fund. */
755
+ partial?: boolean | null;
756
+ /** Issuer's reported total holdings when `partial=true`. */
757
+ total_known_holdings?: number | null;
758
+ }
759
+ interface EtfAggregateCoverage {
760
+ holdingsCount: number;
761
+ holdingsCovered: number;
762
+ /** Sum of weights (0-100) for the covered holdings. */
763
+ weightCovered: number;
764
+ partial?: boolean | null;
765
+ totalKnownHoldings?: number | null;
766
+ }
767
+ interface WeightedConsensus {
768
+ upsidePercent: number | null;
769
+ consensusLabel: string | null;
770
+ /** Fractions of covered AUM in each bucket. Sums to ~1.0. */
771
+ distribution: Record<string, number>;
772
+ totalAnalysts: number;
773
+ }
774
+ interface EtfAnalystContributor {
775
+ ticker: string;
776
+ weightPct: number;
777
+ upsidePercent: number | null;
778
+ consensusLabel: string | null;
779
+ /** Signed contribution to the fund's weighted upside in percentage points. */
780
+ contributionPp: number;
781
+ }
782
+ interface EtfAnalystAggregate {
783
+ ticker: string;
784
+ asOfDate: string | null;
785
+ computedAt: string;
786
+ coverage: EtfAggregateCoverage;
787
+ weightedConsensus: WeightedConsensus;
788
+ /** PRO-only; null on the free preview. */
789
+ topContributors: EtfAnalystContributor[] | null;
790
+ }
791
+ interface WeightedNetFlow {
792
+ /** Weighted net dollar flow (buys - sells). Negative = net selling. */
793
+ netDollars: number;
794
+ buyDollars: number;
795
+ sellDollars: number;
796
+ /** Unweighted; for context. */
797
+ buyTradeCount: number;
798
+ /** Unweighted; for context. */
799
+ sellTradeCount: number;
800
+ distinctInsiderCount: number;
801
+ }
802
+ interface EtfInsiderContributor {
803
+ ticker: string;
804
+ weightPct: number;
805
+ /** Per-stock net flow over the window (signed). */
806
+ netDollars: number;
807
+ /** Signed contribution to the weighted headline. */
808
+ weightedNetDollars: number;
809
+ tradeCount: number;
810
+ }
811
+ interface EtfInsiderAggregate {
812
+ ticker: string;
813
+ asOfDate: string | null;
814
+ computedAt: string;
815
+ lookbackDays: number;
816
+ coverage: EtfAggregateCoverage;
817
+ weightedNetFlow: WeightedNetFlow;
818
+ /** PRO-only; null on the free preview. */
819
+ topContributors: EtfInsiderContributor[] | null;
820
+ }
821
+ interface EtfSentimentReading {
822
+ sentiSenseScore: number | null;
823
+ /** BULLISH / NEUTRAL / BEARISH. */
824
+ scoreLabel: string;
825
+ /** Epoch millis when the underlying metric was produced. */
826
+ asOfTimestamp: number | null;
827
+ }
828
+ interface EtfSentimentAggregate {
829
+ ticker: string;
830
+ asOfDate: string | null;
831
+ computedAt: string;
832
+ coverage: EtfAggregateCoverage;
833
+ /** Holdings-weighted SentiSense across the fund's constituents. */
834
+ constituentsWeighted: EtfSentimentReading;
835
+ /** Direct reading from mentions of the fund's own ticker. Null for low-mention funds. */
836
+ direct: EtfSentimentReading | null;
837
+ }
838
+ interface GetEtfInsiderAggregateOptions {
839
+ /** Trailing window for the trade aggregation. Typical values: 30, 90. Default 30. */
840
+ lookbackDays?: number;
841
+ }
842
+ /**
843
+ * ETF discovery, composition (holdings), and holdings-weighted aggregate views.
844
+ *
845
+ * Funds aren't rated by analysts directly, don't have insiders of their own, and
846
+ * may not get many direct news mentions -- but the companies inside them do. The
847
+ * aggregate endpoints synthesize fund-level views from each constituent's per-stock
848
+ * data, weighted by allocation, with a coverage block so consumers see how much of
849
+ * the fund's AUM the underlying data covered.
850
+ *
851
+ * Beta as of 2026-05-15: starting with a limited set of widely-traded funds.
852
+ */
853
+ declare class Etfs {
854
+ private client;
855
+ constructor(client: APIClient);
856
+ /**
857
+ * List every ETF tracked by SentiSense, sorted by ticker.
858
+ */
859
+ list(): Promise<EtfInfo[]>;
860
+ /**
861
+ * Get the full holdings composition for an ETF, including per-holding weights
862
+ * and freshness metadata. Returns 404 for unknown ETFs or commodity-only funds.
863
+ */
864
+ holdings(ticker: string): Promise<EtfHoldings>;
865
+ /**
866
+ * Get the holdings-weighted analyst consensus for an ETF. Free users receive
867
+ * the headline and coverage block; PRO unlocks per-holding `topContributors`.
868
+ */
869
+ analystAggregate(ticker: string): Promise<PreviewResponse<EtfAnalystAggregate>>;
870
+ /**
871
+ * Get the holdings-weighted SEC Form 4 insider aggregate for an ETF over a
872
+ * configurable trailing window. Free users receive the headline + buy/sell
873
+ * split; PRO unlocks per-holding `topContributors` with signed contribution.
874
+ */
875
+ insiderAggregate(ticker: string, options?: GetEtfInsiderAggregateOptions): Promise<PreviewResponse<EtfInsiderAggregate>>;
876
+ /**
877
+ * Get two SentiSense Score readings side-by-side: `constituentsWeighted`
878
+ * (precomputed daily weighted average across the fund's holdings) and `direct`
879
+ * (score from mentions of the fund's own ticker). The two can diverge, and the
880
+ * gap is itself information.
881
+ */
882
+ sentimentAggregate(ticker: string): Promise<PreviewResponse<EtfSentimentAggregate>>;
883
+ }
884
+
704
885
  declare class Insider {
705
886
  private client;
706
887
  constructor(client: APIClient);
@@ -963,6 +1144,7 @@ declare class SentiSense implements APIClient {
963
1144
  private maxRetries;
964
1145
  readonly stocks: Stocks;
965
1146
  readonly documents: Documents;
1147
+ readonly etfs: Etfs;
966
1148
  readonly institutional: Institutional;
967
1149
  readonly insider: Insider;
968
1150
  readonly politicians: Politicians;
@@ -1000,6 +1182,6 @@ declare class APIError extends SentiSenseError {
1000
1182
  constructor(message: string, status: number, code?: string);
1001
1183
  }
1002
1184
 
1003
- declare const VERSION = "0.11.0";
1185
+ declare const VERSION = "0.15.0";
1004
1186
 
1005
- export { type AISummary, APIError, type AnalystAction, type AnalystConsensus, type AnalystEarningsSurprise, type AnalystEstimate, type AnalystEstimatesResponse, AuthenticationError, type ChartData, type ChartDataPoint, type ClusterBuy, type CompanyKpisData, type CongressTrade, type Document, type DocumentSource, type FloatInfo, type Fundamentals, type FundamentalsPeriod, type GetAnalystActionsOptions, type GetAnalystMarketActivityOptions, type GetInsiderOptions, type GetInsightsOptions, type GetLatestInsightsOptions, type GetPoliticiansOptions, type GetStockInsightsRangeOptions, type GetUserInsightsOptions, type Holder, type InsiderActivityResponse, type InsiderActivitySummary, type InsiderTrade, type Insight, type InsightPreviewResponse, type InstitutionalFlow, type InstitutionalFlowsResponse, type KBEntity, type KpiCoverageEntry, type KpiCoverageResponse, type KpiDataPoint, type KpiSeries, type KpiTypeEntry, type LockedInsight, type MarketMood, type MarketStatus, type MarketSummary, type MentionCount, type MentionData, type MetricDistribution, type MetricDistributionOptions, type MetricType, type MetricsBreakdown, type MetricsOptions, NotFoundError, type PoliticianDetail, type PoliticianSummary, type PreviewResponse, type Quarter, RateLimitError, SentiSense, SentiSenseError, type SentiSenseOptions, type SentimentData, type SentimentEntry, type ServingMetric, type ShortInterest, type ShortVolume, type SimilarStock, type StockDetail, type StockEntity, type StockImage, type StockPrice, type StockProfile, type StockQuote, type Story, type StoryCluster, VERSION, SentiSense as default };
1187
+ export { type AISummary, APIError, type AnalystAction, type AnalystConsensus, type AnalystEarningsSurprise, type AnalystEstimate, type AnalystEstimatesResponse, AuthenticationError, type ChartData, type ChartDataPoint, type ClusterBuy, type CompanyKpisData, type CongressTrade, type Document, type DocumentSource, type EtfAggregateCoverage, type EtfAnalystAggregate, type EtfAnalystContributor, type EtfHolding, type EtfHoldings, type EtfInfo, type EtfInsiderAggregate, type EtfInsiderContributor, type EtfSentimentAggregate, type EtfSentimentReading, type FloatInfo, type Fundamentals, type FundamentalsPeriod, type GetAnalystActionsOptions, type GetAnalystMarketActivityOptions, type GetEtfInsiderAggregateOptions, type GetInsiderOptions, type GetInsightsOptions, type GetLatestInsightsOptions, type GetPoliticiansOptions, type GetStockInsightsRangeOptions, type GetUserInsightsOptions, type Holder, type InsiderActivityResponse, type InsiderActivitySummary, type InsiderTrade, type Insight, type InsightPreviewResponse, type InstitutionalFlow, type InstitutionalFlowsResponse, type KBEntity, type KpiCoverageEntry, type KpiCoverageResponse, type KpiDataPoint, type KpiSeries, type KpiTypeEntry, type LockedInsight, type MarketMood, type MarketStatus, type MarketSummary, type MentionCount, type MentionData, type MetricDistribution, type MetricDistributionOptions, type MetricType, type MetricsBreakdown, type MetricsOptions, NotFoundError, type PoliticianDetail, type PoliticianSummary, type PreviewResponse, type Quarter, RateLimitError, SentiSense, SentiSenseError, type SentiSenseOptions, type SentimentData, type SentimentEntry, type ServingMetric, type ShortInterest, type ShortVolume, type SimilarStock, type StockDetail, type StockEntity, type StockImage, type StockPrice, type StockProfile, type StockQuote, type Story, type StoryCluster, VERSION, type WeightedConsensus, type WeightedNetFlow, SentiSense as default };
package/dist/index.d.ts CHANGED
@@ -6,16 +6,31 @@ interface SentiSenseOptions {
6
6
  }
7
7
  interface StockPrice {
8
8
  ticker: string;
9
+ /** Regular-session price. During RTH: live last trade. Otherwise: most recent RTH close. */
9
10
  price: number;
10
11
  change: number;
11
12
  changePercent: number;
12
13
  previousClose: number;
13
14
  /** Unix timestamp in milliseconds of the price quote. */
14
15
  timestamp: number;
16
+ /** Extended-hours view (pre-market or after-hours). Null/absent during RTH, overnight, and weekends. */
17
+ extendedHours?: ExtendedHoursInfo | null;
18
+ }
19
+ /**
20
+ * Extended-hours session view embedded in price / quote responses when the snapshot sees
21
+ * pre-market (04:00–09:30 ET) or after-hours (16:00–20:00 ET) activity. `change` and
22
+ * `changePercent` are computed by the server vs the regular-session `currentPrice`.
23
+ */
24
+ interface ExtendedHoursInfo {
25
+ session: "pre" | "post";
26
+ price: number;
27
+ change: number;
28
+ changePercent: number;
15
29
  }
16
30
  /** Aggregate quote snapshot from GET /api/v1/stocks/{ticker}/quote. */
17
31
  interface StockQuote {
18
32
  ticker: string;
33
+ /** Regular-session price. During RTH: live last trade. Otherwise: most recent RTH close. */
19
34
  currentPrice: number | null;
20
35
  change: number | null;
21
36
  changePercent: number | null;
@@ -31,7 +46,8 @@ interface StockQuote {
31
46
  epsTTM: number | null;
32
47
  dividendYield: number | null;
33
48
  timestamp: number | null;
34
- extendedHours: boolean | null;
49
+ /** Extended-hours view (pre-market or after-hours). Null/absent during RTH, overnight, and weekends. */
50
+ extendedHours?: ExtendedHoursInfo | null;
35
51
  }
36
52
  interface StockDetail {
37
53
  ticker: string;
@@ -67,12 +83,20 @@ interface StockEntity {
67
83
  [key: string]: unknown;
68
84
  }
69
85
  interface ChartDataPoint {
86
+ /** Unix timestamp in milliseconds. */
87
+ timestamp?: number;
70
88
  date: string;
71
89
  open: number;
72
90
  high: number;
73
91
  low: number;
74
92
  close: number;
75
93
  volume: number;
94
+ /**
95
+ * US-equity market session: "pre" (04:00–09:30 ET), "regular" (09:30–16:00 ET),
96
+ * or "post" (16:00–20:00 ET). Populated for intraday timeframes (1D / 5D / 1W / 1M);
97
+ * `null` for daily / weekly bars (3M and longer) that span whole sessions.
98
+ */
99
+ session?: "pre" | "regular" | "post" | null;
76
100
  }
77
101
  interface ChartData {
78
102
  ticker: string;
@@ -112,7 +136,7 @@ interface AISummary {
112
136
  [key: string]: unknown;
113
137
  }
114
138
  interface GetChartOptions {
115
- timeframe?: "1M" | "3M" | "6M" | "1Y";
139
+ timeframe?: "1D" | "5D" | "1W" | "1M" | "3M" | "6M" | "1Y" | "ALL";
116
140
  }
117
141
  interface GetImagesOptions {
118
142
  forced?: boolean;
@@ -173,8 +197,8 @@ interface Story {
173
197
  tickers: string[];
174
198
  primaryEntityNames: string[];
175
199
  impactScore: number;
176
- /** Unix timestamp in seconds when the story first broke. */
177
- brokeAt: number;
200
+ /** Unix timestamp in seconds when the story first broke. Null when the story has no representative document timestamp yet. */
201
+ brokeAt: number | null;
178
202
  }
179
203
  interface GetByTickerOptions {
180
204
  source?: DocumentSource;
@@ -701,6 +725,163 @@ declare class EntityMetrics {
701
725
  getAverageSentiment(symbol: string, options?: EntityMetricsDateRange): Promise<SentimentData>;
702
726
  }
703
727
 
728
+ interface EtfInfo {
729
+ ticker: string;
730
+ name: string;
731
+ kbEntityId: string | null;
732
+ urlSlug: string | null;
733
+ issuer: string | null;
734
+ trackedIndex: string | null;
735
+ assetClass: string | null;
736
+ }
737
+ interface EtfHolding {
738
+ ticker: string;
739
+ name: string | null;
740
+ /** Weight in the fund as a percentage (0-100). */
741
+ weight_pct: number;
742
+ /** First date this holding appeared in the composition. */
743
+ first_seen: string | null;
744
+ }
745
+ interface EtfHoldings {
746
+ ticker: string;
747
+ issuer: string;
748
+ issuer_endpoint: string | null;
749
+ as_of_date: string;
750
+ fetched_at: string;
751
+ next_refresh_due: string;
752
+ total_holdings: number;
753
+ holdings: EtfHolding[];
754
+ /** True when this is a top-N view rather than the full fund. */
755
+ partial?: boolean | null;
756
+ /** Issuer's reported total holdings when `partial=true`. */
757
+ total_known_holdings?: number | null;
758
+ }
759
+ interface EtfAggregateCoverage {
760
+ holdingsCount: number;
761
+ holdingsCovered: number;
762
+ /** Sum of weights (0-100) for the covered holdings. */
763
+ weightCovered: number;
764
+ partial?: boolean | null;
765
+ totalKnownHoldings?: number | null;
766
+ }
767
+ interface WeightedConsensus {
768
+ upsidePercent: number | null;
769
+ consensusLabel: string | null;
770
+ /** Fractions of covered AUM in each bucket. Sums to ~1.0. */
771
+ distribution: Record<string, number>;
772
+ totalAnalysts: number;
773
+ }
774
+ interface EtfAnalystContributor {
775
+ ticker: string;
776
+ weightPct: number;
777
+ upsidePercent: number | null;
778
+ consensusLabel: string | null;
779
+ /** Signed contribution to the fund's weighted upside in percentage points. */
780
+ contributionPp: number;
781
+ }
782
+ interface EtfAnalystAggregate {
783
+ ticker: string;
784
+ asOfDate: string | null;
785
+ computedAt: string;
786
+ coverage: EtfAggregateCoverage;
787
+ weightedConsensus: WeightedConsensus;
788
+ /** PRO-only; null on the free preview. */
789
+ topContributors: EtfAnalystContributor[] | null;
790
+ }
791
+ interface WeightedNetFlow {
792
+ /** Weighted net dollar flow (buys - sells). Negative = net selling. */
793
+ netDollars: number;
794
+ buyDollars: number;
795
+ sellDollars: number;
796
+ /** Unweighted; for context. */
797
+ buyTradeCount: number;
798
+ /** Unweighted; for context. */
799
+ sellTradeCount: number;
800
+ distinctInsiderCount: number;
801
+ }
802
+ interface EtfInsiderContributor {
803
+ ticker: string;
804
+ weightPct: number;
805
+ /** Per-stock net flow over the window (signed). */
806
+ netDollars: number;
807
+ /** Signed contribution to the weighted headline. */
808
+ weightedNetDollars: number;
809
+ tradeCount: number;
810
+ }
811
+ interface EtfInsiderAggregate {
812
+ ticker: string;
813
+ asOfDate: string | null;
814
+ computedAt: string;
815
+ lookbackDays: number;
816
+ coverage: EtfAggregateCoverage;
817
+ weightedNetFlow: WeightedNetFlow;
818
+ /** PRO-only; null on the free preview. */
819
+ topContributors: EtfInsiderContributor[] | null;
820
+ }
821
+ interface EtfSentimentReading {
822
+ sentiSenseScore: number | null;
823
+ /** BULLISH / NEUTRAL / BEARISH. */
824
+ scoreLabel: string;
825
+ /** Epoch millis when the underlying metric was produced. */
826
+ asOfTimestamp: number | null;
827
+ }
828
+ interface EtfSentimentAggregate {
829
+ ticker: string;
830
+ asOfDate: string | null;
831
+ computedAt: string;
832
+ coverage: EtfAggregateCoverage;
833
+ /** Holdings-weighted SentiSense across the fund's constituents. */
834
+ constituentsWeighted: EtfSentimentReading;
835
+ /** Direct reading from mentions of the fund's own ticker. Null for low-mention funds. */
836
+ direct: EtfSentimentReading | null;
837
+ }
838
+ interface GetEtfInsiderAggregateOptions {
839
+ /** Trailing window for the trade aggregation. Typical values: 30, 90. Default 30. */
840
+ lookbackDays?: number;
841
+ }
842
+ /**
843
+ * ETF discovery, composition (holdings), and holdings-weighted aggregate views.
844
+ *
845
+ * Funds aren't rated by analysts directly, don't have insiders of their own, and
846
+ * may not get many direct news mentions -- but the companies inside them do. The
847
+ * aggregate endpoints synthesize fund-level views from each constituent's per-stock
848
+ * data, weighted by allocation, with a coverage block so consumers see how much of
849
+ * the fund's AUM the underlying data covered.
850
+ *
851
+ * Beta as of 2026-05-15: starting with a limited set of widely-traded funds.
852
+ */
853
+ declare class Etfs {
854
+ private client;
855
+ constructor(client: APIClient);
856
+ /**
857
+ * List every ETF tracked by SentiSense, sorted by ticker.
858
+ */
859
+ list(): Promise<EtfInfo[]>;
860
+ /**
861
+ * Get the full holdings composition for an ETF, including per-holding weights
862
+ * and freshness metadata. Returns 404 for unknown ETFs or commodity-only funds.
863
+ */
864
+ holdings(ticker: string): Promise<EtfHoldings>;
865
+ /**
866
+ * Get the holdings-weighted analyst consensus for an ETF. Free users receive
867
+ * the headline and coverage block; PRO unlocks per-holding `topContributors`.
868
+ */
869
+ analystAggregate(ticker: string): Promise<PreviewResponse<EtfAnalystAggregate>>;
870
+ /**
871
+ * Get the holdings-weighted SEC Form 4 insider aggregate for an ETF over a
872
+ * configurable trailing window. Free users receive the headline + buy/sell
873
+ * split; PRO unlocks per-holding `topContributors` with signed contribution.
874
+ */
875
+ insiderAggregate(ticker: string, options?: GetEtfInsiderAggregateOptions): Promise<PreviewResponse<EtfInsiderAggregate>>;
876
+ /**
877
+ * Get two SentiSense Score readings side-by-side: `constituentsWeighted`
878
+ * (precomputed daily weighted average across the fund's holdings) and `direct`
879
+ * (score from mentions of the fund's own ticker). The two can diverge, and the
880
+ * gap is itself information.
881
+ */
882
+ sentimentAggregate(ticker: string): Promise<PreviewResponse<EtfSentimentAggregate>>;
883
+ }
884
+
704
885
  declare class Insider {
705
886
  private client;
706
887
  constructor(client: APIClient);
@@ -963,6 +1144,7 @@ declare class SentiSense implements APIClient {
963
1144
  private maxRetries;
964
1145
  readonly stocks: Stocks;
965
1146
  readonly documents: Documents;
1147
+ readonly etfs: Etfs;
966
1148
  readonly institutional: Institutional;
967
1149
  readonly insider: Insider;
968
1150
  readonly politicians: Politicians;
@@ -1000,6 +1182,6 @@ declare class APIError extends SentiSenseError {
1000
1182
  constructor(message: string, status: number, code?: string);
1001
1183
  }
1002
1184
 
1003
- declare const VERSION = "0.11.0";
1185
+ declare const VERSION = "0.15.0";
1004
1186
 
1005
- export { type AISummary, APIError, type AnalystAction, type AnalystConsensus, type AnalystEarningsSurprise, type AnalystEstimate, type AnalystEstimatesResponse, AuthenticationError, type ChartData, type ChartDataPoint, type ClusterBuy, type CompanyKpisData, type CongressTrade, type Document, type DocumentSource, type FloatInfo, type Fundamentals, type FundamentalsPeriod, type GetAnalystActionsOptions, type GetAnalystMarketActivityOptions, type GetInsiderOptions, type GetInsightsOptions, type GetLatestInsightsOptions, type GetPoliticiansOptions, type GetStockInsightsRangeOptions, type GetUserInsightsOptions, type Holder, type InsiderActivityResponse, type InsiderActivitySummary, type InsiderTrade, type Insight, type InsightPreviewResponse, type InstitutionalFlow, type InstitutionalFlowsResponse, type KBEntity, type KpiCoverageEntry, type KpiCoverageResponse, type KpiDataPoint, type KpiSeries, type KpiTypeEntry, type LockedInsight, type MarketMood, type MarketStatus, type MarketSummary, type MentionCount, type MentionData, type MetricDistribution, type MetricDistributionOptions, type MetricType, type MetricsBreakdown, type MetricsOptions, NotFoundError, type PoliticianDetail, type PoliticianSummary, type PreviewResponse, type Quarter, RateLimitError, SentiSense, SentiSenseError, type SentiSenseOptions, type SentimentData, type SentimentEntry, type ServingMetric, type ShortInterest, type ShortVolume, type SimilarStock, type StockDetail, type StockEntity, type StockImage, type StockPrice, type StockProfile, type StockQuote, type Story, type StoryCluster, VERSION, SentiSense as default };
1187
+ export { type AISummary, APIError, type AnalystAction, type AnalystConsensus, type AnalystEarningsSurprise, type AnalystEstimate, type AnalystEstimatesResponse, AuthenticationError, type ChartData, type ChartDataPoint, type ClusterBuy, type CompanyKpisData, type CongressTrade, type Document, type DocumentSource, type EtfAggregateCoverage, type EtfAnalystAggregate, type EtfAnalystContributor, type EtfHolding, type EtfHoldings, type EtfInfo, type EtfInsiderAggregate, type EtfInsiderContributor, type EtfSentimentAggregate, type EtfSentimentReading, type FloatInfo, type Fundamentals, type FundamentalsPeriod, type GetAnalystActionsOptions, type GetAnalystMarketActivityOptions, type GetEtfInsiderAggregateOptions, type GetInsiderOptions, type GetInsightsOptions, type GetLatestInsightsOptions, type GetPoliticiansOptions, type GetStockInsightsRangeOptions, type GetUserInsightsOptions, type Holder, type InsiderActivityResponse, type InsiderActivitySummary, type InsiderTrade, type Insight, type InsightPreviewResponse, type InstitutionalFlow, type InstitutionalFlowsResponse, type KBEntity, type KpiCoverageEntry, type KpiCoverageResponse, type KpiDataPoint, type KpiSeries, type KpiTypeEntry, type LockedInsight, type MarketMood, type MarketStatus, type MarketSummary, type MentionCount, type MentionData, type MetricDistribution, type MetricDistributionOptions, type MetricType, type MetricsBreakdown, type MetricsOptions, NotFoundError, type PoliticianDetail, type PoliticianSummary, type PreviewResponse, type Quarter, RateLimitError, SentiSense, SentiSenseError, type SentiSenseOptions, type SentimentData, type SentimentEntry, type ServingMetric, type ShortInterest, type ShortVolume, type SimilarStock, type StockDetail, type StockEntity, type StockImage, type StockPrice, type StockProfile, type StockQuote, type Story, type StoryCluster, VERSION, type WeightedConsensus, type WeightedNetFlow, SentiSense as default };
package/dist/index.mjs CHANGED
@@ -220,6 +220,59 @@ var EntityMetrics = class {
220
220
  }
221
221
  };
222
222
 
223
+ // src/resources/etfs.ts
224
+ var Etfs = class {
225
+ constructor(client) {
226
+ this.client = client;
227
+ }
228
+ /**
229
+ * List every ETF tracked by SentiSense, sorted by ticker.
230
+ */
231
+ async list() {
232
+ return this.client.get("/api/v1/etfs");
233
+ }
234
+ /**
235
+ * Get the full holdings composition for an ETF, including per-holding weights
236
+ * and freshness metadata. Returns 404 for unknown ETFs or commodity-only funds.
237
+ */
238
+ async holdings(ticker) {
239
+ return this.client.get(
240
+ `/api/v1/etfs/${encodeURIComponent(ticker.toUpperCase())}/holdings`
241
+ );
242
+ }
243
+ /**
244
+ * Get the holdings-weighted analyst consensus for an ETF. Free users receive
245
+ * the headline and coverage block; PRO unlocks per-holding `topContributors`.
246
+ */
247
+ async analystAggregate(ticker) {
248
+ return this.client.get(
249
+ `/api/v1/etfs/${encodeURIComponent(ticker.toUpperCase())}/aggregates/analyst`
250
+ );
251
+ }
252
+ /**
253
+ * Get the holdings-weighted SEC Form 4 insider aggregate for an ETF over a
254
+ * configurable trailing window. Free users receive the headline + buy/sell
255
+ * split; PRO unlocks per-holding `topContributors` with signed contribution.
256
+ */
257
+ async insiderAggregate(ticker, options) {
258
+ return this.client.get(
259
+ `/api/v1/etfs/${encodeURIComponent(ticker.toUpperCase())}/aggregates/insider`,
260
+ options
261
+ );
262
+ }
263
+ /**
264
+ * Get two SentiSense Score readings side-by-side: `constituentsWeighted`
265
+ * (precomputed daily weighted average across the fund's holdings) and `direct`
266
+ * (score from mentions of the fund's own ticker). The two can diverge, and the
267
+ * gap is itself information.
268
+ */
269
+ async sentimentAggregate(ticker) {
270
+ return this.client.get(
271
+ `/api/v1/etfs/${encodeURIComponent(ticker.toUpperCase())}/aggregates/sentiment`
272
+ );
273
+ }
274
+ };
275
+
223
276
  // src/resources/insider.ts
224
277
  var Insider = class {
225
278
  constructor(client) {
@@ -612,7 +665,7 @@ var Stocks = class {
612
665
  };
613
666
 
614
667
  // src/version.ts
615
- var VERSION = "0.11.0";
668
+ var VERSION = "0.15.0";
616
669
 
617
670
  // src/client.ts
618
671
  var DEFAULT_BASE_URL = "https://app.sentisense.ai";
@@ -631,6 +684,7 @@ var SentiSense = class {
631
684
  this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
632
685
  this.stocks = new Stocks(this);
633
686
  this.documents = new Documents(this);
687
+ this.etfs = new Etfs(this);
634
688
  this.institutional = new Institutional(this);
635
689
  this.insider = new Insider(this);
636
690
  this.politicians = new Politicians(this);