Skip to main content
Press ⌘K to search

Short data

Short-selling data — daily short volume, bi-monthly short interest, off-exchange volume, fails-to-deliver, and composite squeeze scores. The historical /v1/stocks/{ticker} route shape accepts an exact stock or ETF listing; raw observations never substitute another series owned by the same SEC filer. Listing history is restated onto today's own split basis so a series stays continuous across a split. Forecast and squeeze-score endpoints remain issuer-trained operating-company models and refuse ETF or secondary listings. For the dataset overview, the free tier and client setup, see the short interest API page.

/v1/stocks/

Individual net short-position disclosures published by a European regulator's register, matched to the exact ISIN of a verified European listing. This is a separate dataset from FINRA short interest: rows are dated disclosures, not a current-position total. Multiple disclosures for one holder may remain in an export.

Parameters: {exchange} and {ticker} (path, required); limit (default 20, minimum 1, maximum 100); source (AMF-France, the default; AFM-Netherlands-Current; AFM-Netherlands-History; FSMA-Belgium-Current; FSMA-Belgium-History; CBI-Ireland; CNMV-Spain; KNF-Poland; FINFSA-Finland; BAnz-Germany; or DFSA-Denmark). The normal API key is required.

Returns: source, sourceName, isin, coverageStatus, coverage, measure, percentageBasis, checkedAt, sourceModifiedAt, isStale, sourceUrl, totalDisclosures, and newest-first disclosures.

Each disclosure contains holderName, holderLei, issuerName, isin, percentOfIssuedCapital, positionDate, nullable publicationDate and nullable publicationEndDate. The Dutch source supplies no holder LEI, publication date or archive-transfer date; these remain unknown. Percentages use percentage points: 0.35 means 0.35% of issued capital, not 35% and not a percentage of free float.

Coverage status distinguishes unresolved_security, not_captured, no_matching_disclosures and available. None of the first three means zero short positions. A below-threshold exit disclosure does not establish what the holder subsequently held. The result is bounded by limit; full-history paging is not provided.

Reads use stored captures and never fetch the regulator on demand. Coverage remains not_captured until collection is enabled and a complete export is accepted.

Dutch current-register and archive sources: the current register includes earlier notifications from the same holder; it is not one latest holding per person. Crossing below 0.5% moves a notification to the archive after one working day, but an archived row does not prove closure. Never sum current-register and archived disclosures. Freshness uses the successful capture time because these exports provide no modification timestamp.

National registers: Belgium's FSMA (current and superseded notifications as separate sources), Ireland's Central Bank, Spain's CNMV, Poland's KNF, Finland's FIN-FSA, Germany's Federal Gazette and Denmark's Danish FSA (a monthly workbook of notifications at or above 0.5%). Each is read from its own stored export; Ireland states positions as fractions, returned here as percentage points.

/v1/stocks/

Source-separated regulator-published aggregates for an exact verified exchange and ticker. This is not total short interest, daily short volume, or a complete shareholder register. The endpoint requires an API key.

Parameters: exchange and ticker identify a verified listing; limit defaults to 20 and accepts 1–100 observations per source.

The response is an array of reports carrying source, sourceName, identityScope, isin, issuerLei, measure, coverage, coverageStatus, percentageBasis, checkedAt, sourceModifiedAt, isStale, totalObservations, sourceUrl and observations.

Each observation preserves positionDate, percentOfIssuedCapital in percentage points, nullable shares, nullable becameHistoricalOn, and source-stated holders. Norwegian holders retain their own dates and shares; holderSharesReconcile flags whether their share counts equal the source aggregate. The source aggregate is never replaced by a sum of holder rows.

Norway's history covers positions active within the source's two-year window and includes only public positions at or above 0.5%. UK current and historical anonymised aggregates are separate reports; historical records must never be added to current values. UK collection and publication remain permission-gated.

Sweden's FI aggregate is issuer-scoped: identityScope is issuer, issuerLei is the exact verified issuer LEI, and isin is null. It includes reported positions exceeding 0.1% of issued share capital. It does not identify individual share classes or holders, and must not be summed across listings of the same issuer. Other sources remain security-scoped. The successful check and source update timestamps accompany each report.

Denmark's daily aggregate includes current reported positions at or above 0.1% of issued share capital, matched to the exact ISIN. Its records use reportedAggregates, with isin, issuerName, percentOfIssuedCapital and latestReportedAtLocal. The timestamp is the latest report received, as displayed without a timezone; it is not the position date. observations is empty for this report, and existing sources retain their dated observation format. An unchanged position can have an old report timestamp even when the table was checked recently. The separate monthly holder disclosures must not be added to this aggregate.

Coverage status distinguishes permission_required, unresolved_security, unresolved_issuer, not_captured, no_matching_observations and available. Missing observations do not mean zero short positions. Reads never contact the regulator.

/v1/stocks/

Daily FINRA short-volume tape for one exact stock or ETF listing, newest first — reported short volume, short-exempt volume, total FINRA-facility volume, and the same-day short-volume percentage. Volumes cover off-exchange trades reported to FINRA facilities only (roughly 40% of consolidated tape volume), so a 40–50% short percentage is the normal baseline. Daily coverage begins 2026-04-06 — earlier dates return an empty page.

Parameters: {ticker} (path, required — e.g. NVDA); startDate, endDate (yyyy-MM-dd; default the trailing 3 months); limit (default 90, max 500) and offset for paging.

curl "https://api.equibles.com/v1/stocks/NVDA/short-volume?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/short-volume?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/short-volume?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "data": [
    {
      "date": "2026-07-13",
      "shortVolume": 16289793,
      "shortExemptVolume": 12647,
      "totalVolume": 48733456,
      "shortVolumePercent": 33.42630368755296
    },
    {
      "date": "2026-07-10",
      "shortVolume": 26602058,
      "shortExemptVolume": 178353,
      "totalVolume": 66211891,
      "shortVolumePercent": 40.1771609271815
    }
  ],
  "meta": {
    "limit": 2,
    "offset": 0,
    "count": 2,
    "hasMore": true
  }
}

/v1/stocks/

Bi-monthly FINRA short-interest settlements for one exact stock or ETF listing, newest first — the current short position, its change since the prior settlement, average daily volume, and days to cover. FINRA caps daysToCover at 999.99: a returned 999.99 is a genuine reading meaning "999.99 or more", while the 999.99 placeholder FINRA files for a settlement with zero average daily volume is returned as null — the ratio is undefined there, not a measurement.

Parameters: {ticker} (path, required — e.g. NVDA); startDate, endDate (yyyy-MM-dd settlement dates; default the trailing 12 months); limit (default 24, max 500) and offset for paging.

curl "https://api.equibles.com/v1/stocks/NVDA/short-interest?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/short-interest?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/short-interest?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "data": [
    {
      "settlementDate": "2026-06-30",
      "shortPosition": 310126785,
      "changeInShortPosition": 10460476,
      "averageDailyVolume": 155989510,
      "daysToCover": 1.99
    },
    {
      "settlementDate": "2026-06-15",
      "shortPosition": 299666309,
      "changeInShortPosition": 14943593,
      "averageDailyVolume": 167960279,
      "daysToCover": 1.78
    }
  ],
  "meta": {
    "limit": 2,
    "offset": 0,
    "count": 2,
    "hasMore": true
  }
}

/v1/stocks/

A model prediction, not FINRA data. FINRA measures a settlement about two weeks before it publishes the figure, so the newest official row is routinely stale. This endpoint answers with our model's estimate of that pending settlement, and withdraws it the moment the official figure exists.

Never present this number as a reported short position. Every response carries a note that says so, and the confidence band tells you how much weight the estimate deserves: high and medium estimates called the direction correctly about 70% and 67% of the time in retrospective testing over 2025 through mid-2026, against about 60% across all estimates; a low estimate is close to a coin flip, so quote likelyRangeLow-likelyRangeHigh rather than the central figure. Methodology: equibles.com/research/does-daily-short-volume-predict-short-interest.

Parameters: {ticker} (path, required — e.g. NVDA). No paging: one pending settlement, one answer.

404 is the normal state in the days after a release, when the last measured settlement has already been published and there is nothing left to forecast. It is not an error — fall back to /v1/stocks/{ticker}/short-interest.

curl "https://api.equibles.com/v1/stocks/NVDA/short-interest/forecast" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/short-interest/forecast",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/short-interest/forecast", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "ticker": "NVDA",
  "settlementDate": "2026-07-31",
  "publicationDate": "2026-08-11",
  "previousSettlementDate": "2026-07-15",
  "previousReportedPosition": 299666309,
  "estimatedShortPosition": 312480117,
  "estimatedChangePercent": 4.2762,
  "likelyRangeLow": 288114903,
  "likelyRangeHigh": 338905442,
  "confidence": "medium",
  "asOfDate": "2026-08-04",
  "note": "Model estimate, not official FINRA data. Estimated from daily short volume through 2026-08-04; FINRA publishes the official figure for the 2026-07-31 settlement on 2026-08-11. Say it is an estimate whenever you repeat it."
}

/v1/stocks/

Weekly off-exchange (dark-pool / OTC) volume for one exact stock or ETF listing from FINRA's OTC/ATS Transparency data, newest first — split into ATS and non-ATS OTC share and trade counts. Each row carries mayIncludeCaseFoldedSiblingVolume; it is true before 2025-08-11 because those weeks may include a case-variant sibling security's volume and have aged out of FINRA's rolling source window.

Parameters: {ticker} (path, required — e.g. NVDA); startDate, endDate (yyyy-MM-dd week starts; default the trailing 6 months); limit (default 26, max 500) and offset for paging.

curl "https://api.equibles.com/v1/stocks/NVDA/off-exchange-volume?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/off-exchange-volume?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/off-exchange-volume?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "data": [
    {
      "weekStartDate": "2026-06-22",
      "atsVolume": 80942287,
      "atsTradeCount": 1256234,
      "nonAtsOtcVolume": 263394397,
      "nonAtsOtcTradeCount": 6122784,
      "totalOffExchangeVolume": 344336684,
      "mayIncludeCaseFoldedSiblingVolume": false
    },
    {
      "weekStartDate": "2026-06-15",
      "atsVolume": 55489159,
      "atsTradeCount": 848691,
      "nonAtsOtcVolume": 219576379,
      "nonAtsOtcTradeCount": 4605721,
      "totalOffExchangeVolume": 275065538,
      "mayIncludeCaseFoldedSiblingVolume": false
    }
  ],
  "meta": {
    "limit": 2,
    "offset": 0,
    "count": 2,
    "hasMore": true
  }
}

/v1/stocks/

Lists SEC fails-to-deliver records for one exact stock or ETF listing — settlement date, share quantity, reference price, and dollar value — newest first. Each row's quantity is the aggregate outstanding fail position on its settlement date (a balance, not a daily flow — don't sum it across dates), and price is the prior trading day's closing price per the SEC file convention. The SEC publishes FTD data in half-month batches with a roughly two-week lag. The response's coverageStartDate says when full coverage begins (the earliest settlement date with full-universe ingestion, across all listings): from it onward, an absent date means no reported fails; earlier dates are only partially covered, so their absence is not evidence of no fails.

Parameters: {ticker} (path) · optional startDate, endDate (yyyy-MM-dd settlement dates; default last 3 months) · limit, offset (paging).

curl "https://api.equibles.com/v1/stocks/NVDA/fails-to-deliver?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/stocks/NVDA/fails-to-deliver?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/stocks/NVDA/fails-to-deliver?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "data": [
    { "settlementDate": "2026-06-11", "quantity": 2, "price": 200.42, "value": 400.84 },
    { "settlementDate": "2026-06-10", "quantity": 3, "price": 208.19, "value": 624.57 }
  ],
  "meta": { "limit": 2, "offset": 0, "count": 2, "hasMore": true },
  "coverageStartDate": "2026-03-02"
}

/v1/short-interest/snapshot

Latest market-wide short-interest snapshot — one row per stock for the most recent settlement date, sorted by days to cover descending. Rows at FINRA's 999.99 days-to-cover cap are a sentinel tier (almost always illiquid names with a tiny volume denominator) and rank after real readings; pass minAverageDailyVolume to drop illiquid names entirely.

Parameters: minDaysToCover (default 0 = no filter); minAverageDailyVolume (minimum average daily share volume, e.g. 100000; default 0 = no floor — also accepted as minAvgDailyVolume); sortBy (daysToCover, shortPosition, or change; default daysToCover); limit (default 50, max 500) and offset for paging down the ranking (ties break on ticker, so pages never repeat or skip rows). The top-level settlementDate names the settlement the board is drawn from.

curl "https://api.equibles.com/v1/short-interest/snapshot?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/short-interest/snapshot?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/short-interest/snapshot?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "settlementDate": "2026-06-30",
  "data": [
    {
      "ticker": "SAXPF",
      "name": "Sampo OYJ",
      "shortPosition": 5506396,
      "changeInShortPosition": -88225,
      "averageDailyVolume": 6114,
      "daysToCover": 900.62
    },
    {
      "ticker": "CODGF",
      "name": "Compagnie De Saint Gobain",
      "shortPosition": 805997,
      "changeInShortPosition": -85002,
      "averageDailyVolume": 900,
      "daysToCover": 895.55
    }
  ]
}

/v1/short-volume/largest

Stocks with the largest daily short volume for a single trading day, sorted by short volume descending. Volumes cover FINRA-reported off-exchange facility trades only, so a 40–50% short percentage is the normal baseline.

Parameters: date (yyyy-MM-dd; default the latest available trading day); minShortVolume (default 0 = no filter); minTotalVolume (minimum total reported volume, default 0 = no floor — use it before sorting by percent so thin tapes don't top the board); sortBy (shortVolume or shortPercent; default shortVolume); limit (default 50, max 500) and offset for paging down the ranking (ties break on ticker, so pages never repeat or skip rows). The top-level date names the trading day the board covers.

curl "https://api.equibles.com/v1/short-volume/largest?limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/short-volume/largest?limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/short-volume/largest?limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "date": "2026-07-13",
  "data": [
    {
      "ticker": "SOBR",
      "name": "SOBR Safe, Inc.",
      "shortVolume": 97258226,
      "shortExemptVolume": 22093363,
      "totalVolume": 161936624,
      "shortVolumePercent": 60.05943782056368
    },
    {
      "ticker": "AAL",
      "name": "American Airlines Group Inc.",
      "shortVolume": 67876880,
      "shortExemptVolume": 68577,
      "totalVolume": 128483694,
      "shortVolumePercent": 52.82917846368894
    }
  ]
}

/v1/short-squeeze-scores

Highest composite short-squeeze scores — a peer-relative 0–100 rank blending six short-pressure factors (short interest % of shares, days to cover, price vs trailing VWAP, short-volume trend, short-interest change, fails-to-deliver pressure) with catalyst boosts for a price spike, volume surge, or a near-term earnings call, highest first. Percentage fields come over the wire as fractions (0.112 = 11.2%). Pass a liquidity floor so untradeable micro-caps don't dominate the board.

Each row also carries the working behind its score: rank (position in the whole scored universe, stamped before your liquidity filters — so a filtered board keeps each row's real standing instead of renumbering from 1, and matches what a single-ticker lookup reports), baseScore and catalystBoost (score is their sum clamped to 100, so the split says whether a name rests on standing short pressure or a transient event), and the peer-relative factor percentiles — shortInterestPercentile, daysToCoverPercentile, shortVolumeTrendPercentile, shortInterestChangePercentile, failsToDeliverPercentile, priceAboveVwapPercentile. A percentile is absent when its factor is missing and drops out of the weighted mean. scoredCount on the response is the size of the scored universe the percentiles are relative to; total is how many rows survive your liquidity filters.

Parameters: ticker (one exact listed symbol — a single-stock lookup that returns only that row, with its board-wide rank also echoed at the top level and no total; limit, offset, and both liquidity floors are ignored, and a stock outside the scored universe returns 404 naming why); minMarketCap (USD, default 0 = no floor; unknown-cap stocks are excluded when set); minDollarVolume (USD average daily dollar volume, default 0 = no floor); limit (default 25, max 200) and offset for paging down the board (total reports the full filtered board size).

curl "https://api.equibles.com/v1/short-squeeze-scores?minMarketCap=1000000000&limit=2" \
  -H "Authorization: Bearer eq_your_api_key"
import requests
r = requests.get(
    "https://api.equibles.com/v1/short-squeeze-scores?minMarketCap=1000000000&limit=2",
    headers={"Authorization": "Bearer eq_your_api_key"},
)
print(r.json())
const res = await fetch("https://api.equibles.com/v1/short-squeeze-scores?minMarketCap=1000000000&limit=2", {
  headers: { Authorization: "Bearer eq_your_api_key" },
});
console.log(await res.json());
{
  "settlementDate": "2026-07-15",
  "data": [
    {
      "ticker": "DNOW",
      "rank": 4,
      "score": 100.0,
      "shortInterestPercentOfShares": 0.09711299871293606,
      "daysToCover": 8.08,
      "shortVolumeShareTrend": 0.10830688766709835,
      "shortInterestChangePercent": 0.21658863934914815,
      "failsToDeliverPercentOfShares": 0.00019041308926037818,
      "priceAboveVwap": 0.22238909958215858,
      "hasPriceSpikeCatalyst": true,
      "hasVolumeSurgeCatalyst": false,
      "hasEarningsProximityCatalyst": true,
      "marketCapitalization": 3027259856.2080235,
      "averageDailyDollarVolume": 36401236.80468409,
      "baseScore": 82.91,
      "catalystBoost": 20.0,
      "shortInterestPercentile": 88.51654514862591,
      "daysToCoverPercentile": 84.97150997150997,
      "shortVolumeTrendPercentile": 78.31572769953051,
      "shortInterestChangePercentile": 83.19160997732426,
      "failsToDeliverPercentile": 52.636006730229944,
      "priceAboveVwapPercentile": 93.56386732533521
    },
    {
      "ticker": "FIGS",
      "rank": 6,
      "score": 100.0,
      "shortInterestPercentOfShares": 0.11988330918646428,
      "daysToCover": 6.71,
      "shortVolumeShareTrend": 0.06820869005617618,
      "shortInterestChangePercent": 0.13417834397806064,
      "failsToDeliverPercentOfShares": 0.0007231721740239189,
      "priceAboveVwap": 0.23829202237527236,
      "hasPriceSpikeCatalyst": true,
      "hasVolumeSurgeCatalyst": false,
      "hasEarningsProximityCatalyst": true,
      "marketCapitalization": 2384943104.0,
      "averageDailyDollarVolume": 42591226.331520475,
      "baseScore": 82.59,
      "catalystBoost": 20.0,
      "shortInterestPercentile": 92.37240605720696,
      "daysToCoverPercentile": 78.37606837606837,
      "shortVolumeTrendPercentile": 67.34154929577466,
      "shortInterestChangePercentile": 77.19671201814059,
      "failsToDeliverPercentile": 72.3780145821649,
      "priceAboveVwapPercentile": 94.3119266055046
    }
  ],
  "scoredCount": 7133,
  "total": 2939
}

Try it with a real key

Every example on this page runs against the live API. A free account includes an API key and MCP access — set up in under a minute.