API Reference

Trackers API

Observational market trackers in one standardized envelope: institution rankings, hedge fund returns, Reddit positioning, and sentiment leaderboards.

Base: /api/v1/trackersFree (API key required); some trackers gate richer data to PRO2 endpoints

Overview

Trackers are observational data products. Each tracker has its own data source and refresh cadence; underneath, they all return the same standardized envelope, so a builder writes one renderer per viewType and gets every current and future SentiSense tracker for free.

Currently live trackers:

Tracker id viewType accessTier What it shows
institution-concentration table free 13F filers ranked by top-10 concentration (the most conviction-driven portfolios)
institution-aum table free Largest 13F filers by total disclosed long-equity AUM
hedge-fund-reported-returns table pro Net-of-fee annual returns large hedge funds publish, with a citation per number
reddit-picks table free Tradeable stocks finance-Reddit turned bullish on, scored vs SPY
media-darlings table free Stocks ranked by how bullish or bearish the curated financial press is on them
sentiment-leaderboard table free Most bullish and most bearish stocks by pure sentiment polarity, with a driving story per row
sentiment-movers table free Biggest 7-day sentiment shifts (improving and deteriorating)
trending-products table free Products and services ranked by mention volume and week-over-week growth

More tracker types ship over time; the discovery endpoint is the source of truth for what's live.

Access: an API key is required on every tracker endpoint. Each tracker declares an accessTier of "free" or "pro" in the discovery listing. A pro tracker returns a truncated preview to FREE callers (isPreview: true, previewReason: "PRO_REQUIRED", with totalCount) and the full snapshot to PRO; a free tracker returns the full snapshot to everyone.

Methodology: every tracker carries a methodologyAnchor field in the discovery listing that points at its section on sentisense.ai/methodology (e.g. #institution-rankings for the concentration and AUM rankings).


GET /api/v1/trackers

Discovery endpoint. Returns every publicly-visible tracker the platform knows about, with the metadata you need to render a hub or build a navigation menu.

Response

{
  "trackers": [
    {
      "trackerId": "institution-concentration",
      "displayName": "Most concentrated institutions",
      "category": "institutional",
      "description": "13F filers ranked by the share of their disclosed book held in their top 10 positions.",
      "viewType": "table",
      "accessTier": "free",
      "methodologyAnchor": "#institution-rankings",
      "refreshIntervalSeconds": 86400,
      "canonicalUrl": "/api/v1/trackers/institution-concentration"
    }
  ]
}
Field Type Notes
trackerId string Slug for the detail endpoint
displayName string Hub-card title; also surfaced inside the snapshot envelope
category string Coarse grouping for hub filtering ("institutional", etc.)
description string One sentence; suitable for a hub card subtitle
viewType string Renderer hint. Phase 1 publishes "table". New viewType values are documented here when a tracker using them ships.
accessTier string "free" or "pro". pro trackers return a truncated preview to FREE callers; free trackers return the full snapshot to everyone.
methodologyAnchor string Fragment on /methodology for the tracker (link out without per-tracker logic)
refreshIntervalSeconds integer Expected snapshot refresh cadence in seconds
canonicalUrl string Detail endpoint path

GET /api/v1/trackers/{trackerId}

Standardized snapshot envelope for one tracker.

Path parameter

Parameter Description
trackerId Slug from the discovery listing, e.g. institution-concentration. Unknown ids return 404 unknown_tracker.

Query parameters (optional, provider-specific)

Parameter Description
scope For geographically-scoped trackers (none in Phase 1). Unknown keys are ignored.
category For the institution-ranking trackers (concentration, aum): overrides the default filer-category filter. Pass ?category= (empty) to open the universe across all categories instead of the default hedge-fund filter.

Response shape (the envelope)

Every tracker returns the same wire shape:

{
  "isPreview": false,
  "previewReason": null,
  "data": {
    "trackerId": "institution-concentration",
    "schemaVersion": "1.0",
    "displayName": "Most concentrated institutions",
    "description": "13F filers ranked by the share of their disclosed book held in their top 10 positions.",
    "viewType": "table",
    "asOf": "2026Q1",
    "generatedBy": "InstitutionRankingsService",
    "headline": [
      { "label": "Institutions ranked", "value": 28, "unit": "filers" }
    ],
    "rows": [
      {
        "rank": 1,
        "rowId": "0001067983",
        "name": "Berkshire Hathaway",
        "category": "HEDGE_FUND",
        "url": "/institutions/Berkshire-Hathaway",
        "metrics": [
          { "label": "Top-10 concentration", "value": 91.2, "unit": "percent" },
          { "label": "Disclosed AUM", "value": 264000000000, "unit": "usd" },
          { "label": "Holdings",      "value": 40,  "unit": "count" }
        ]
      }
    ]
  }
}
Envelope field Type Notes
isPreview boolean true only when a pro-tier tracker is served to a non-PRO caller (the rows are truncated to a free preview). false for free trackers and for PRO callers.
previewReason "PRO_REQUIRED" or null Only set when isPreview is true.
totalCount integer Present only on preview responses. The full row count before truncation.
data object The standardized TrackerSnapshot (below).
Snapshot field Type Notes
trackerId string Echoes the request path.
schemaVersion string "1.0" today. Bumped when the envelope shape changes incompatibly.
displayName string Same as the discovery listing. Surfaced here so renderers don't need to cross-reference.
description string Same as the discovery listing.
viewType string The renderer hint. Phase 1 publishes "table"; dispatch on this to pick a renderer.
asOf string Free-form 'data as of' label, typically a quarter ("2026Q1") or ISO date for daily trackers.
headline array Top-of-page stat tiles. Each item is { label, value, unit?, asOf?, methodologyNote?, trend? }.
rows array Populated when viewType === "table". Each row carries its per-cell metrics[] (label + value + unit) so a generic renderer can derive column headers from rows[0].metrics.

Reading the table-row metrics

Each rows[].metrics[] entry is a { label, value, unit } tuple. Column headers come from the labels on the first row; the order is stable across rows in a single response.

For the institution-ranking trackers, the metric set per row is:

Tracker Metrics (in order)
institution-concentration Top-10 concentration, Disclosed AUM, Holdings
institution-aum Disclosed AUM, Holdings

unit is one of "percent", "usd", "count"; a renderer can use it to format value without per-tracker logic.

Error responses

Status Body Cause
404 unknown_tracker { "error": "unknown_tracker", "message": "No registered tracker with id '...'" } Slug not in the registry
404 no_snapshot { "error": "no_snapshot", "message": "Tracker '...' has no snapshot available" } Tracker registered but hasn't produced data yet
503 tracker_unavailable { "error": "tracker_unavailable", "message": "Tracker '...' is temporarily unavailable" } The provider threw; retry with backoff

SDK usage

Python:

from sentisense import SentiSenseClient

client = SentiSenseClient(api_key="...")

for tracker in client.list_trackers().trackers:
    print(tracker.trackerId, tracker.displayName)

snapshot = client.get_tracker("institution-concentration")
print(snapshot.data.displayName, snapshot.data.asOf)
for row in snapshot.data.rows[:5]:
    print(row.rank, row.name, row.metrics[0].value)  # first metric = top-10 concentration

Node:

import { SentiSense } from "sentisense";

const client = new SentiSense({ apiKey: "..." });

const { trackers } = await client.trackers.list();
for (const t of trackers) console.log(t.trackerId, t.displayName);

const snap = await client.trackers.get("institution-concentration");
console.log(snap.data.displayName, snap.data.asOf);
for (const row of (snap.data.rows ?? []).slice(0, 5)) {
  console.log(row.rank, row.name, row.metrics[0].value);
}

Why this shape

Trackers are observational dashboards (see also the Indexes vs. Trackers taxonomy on the methodology page). The standardized envelope plus the viewType taxonomy means:

  • One renderer per viewType in your code, and you cover every tracker we ship.
  • Adding a new tracker is additive: no breaking changes to the contract, no parallel endpoints, no per-tracker shape work for consumers.
  • Discovery (GET /api/v1/trackers) returns enough metadata to render a navigation menu without hitting any tracker's detail endpoint.

This is the same convention used by CDC NNDSS (US disease surveillance), FRED (economic indicators), World Bank, OECD, and EIA dashboards.

Try It

Test endpoints directly from your browser. Paste your API key once: it's saved locally and shared across all widgets. Get a free key

GET/api/v1/trackers

List every publicly-visible tracker

Try It
curl -H "X-SentiSense-API-Key: ssk_YOUR_KEY" \ "https://app.sentisense.ai/api/v1/trackers"
Enter your API key to send requests

GET/api/v1/trackers/{trackerId}

Standardized snapshot envelope for one tracker

Try It
curl -H "X-SentiSense-API-Key: ssk_YOUR_KEY" \ "https://app.sentisense.ai/api/v1/trackers/{trackerId}"
Enter your API key to send requests