CompsDesk Data API

Every number the API returns is a figure a company filed, returned with the filing it came from. Nothing is estimated, modelled, or filled in.

Base URL https://compsdesk.com/api/v1
Auth Authorization: Bearer <your token> — your token is the #k= value in the access link emailed to you. It is in the URL fragment, so it never reaches a server log.
Included with an active Analyst, Team, or Enterprise membership.

The one rule worth stating first

When a company did not disclose something, the API returns "value": null with a reason. It does not return 0, and it does not substitute a similar tag. A zero in a spreadsheet is a number someone will subtract; a null is a question. If you ever see a figure from this API that you cannot trace to a filing, that is a bug worth reporting — hello@compsdesk.com.

Endpoints

GET /health — no auth

What the service is currently serving, including the newest filing date in the data. Check this before assuming a missing recent figure is a coverage gap — it may simply be newer than the last refresh.

curl https://compsdesk.com/api/v1/health

GET /excel/metric

One figure, with its provenance. The Excel CD.GET function calls this.

ParameterRequiredNotes
tickeryesTicker or 10-digit CIK
metricyesA derived metric or a disclosed XBRL tag — see /metrics
periodnolatest (default), FY2024, 2024, or an exact period end 2024-12-31
basisnoannual (default), quarterly, or any — see below

basis matters more than it looks. A filer discloses the same tag over several windows that end on the same day. Apple's Q2 FY2026 filing reports NetIncomeLoss for the quarter ($29.6bn) and for the six months to that same date ($71.7bn). Asking for a tag without saying which window you mean is an ambiguous question, so the API answers the annual one by default and tells you what it gave you: every response carries period_type (FY, Q, instant) and period_start. Use basis=quarterly for the discrete quarter. Balance sheet items are instants — they have no duration and are returned under any basis.

curl -H "Authorization: Bearer $CD_TOKEN" \
  "https://compsdesk.com/api/v1/excel/metric?ticker=AAPL&metric=Revenues&period=FY2025"

GET /excel/source

The same figure, plus the accession number and a direct link to the filing on EDGAR. This is the endpoint to use when someone asks you where a number came from.

GET /excel/peers

Companies sharing the subject's 4-digit SIC, ordered by closeness in latest-year revenue. Deterministic: the same request returns the same cohort, which is what makes a comparison defensible three months later.

ParameterRequiredNotes
tickeryesSubject company
countnoDefault 10

GET /query

The screen: one derived metric across every company, filtered. Rows where the metric is null are excluded — a screen is a ranking, and a company that did not disclose the input has no place in one.

ParameterRequiredNotes
metricyesA derived metric name from /metrics
sicno4-digit SIC code
min_revenue / max_revenuenoSize band, USD
fiscal_yearnoe.g. 2025
limitnoDefault 200, capped at 5,000
curl -H "Authorization: Bearer $CD_TOKEN" \
  "https://compsdesk.com/api/v1/query?metric=gross_margin_pct&sic=7372&min_revenue=250000000"

GET /metrics

Everything callable: the derived metrics CompsDesk computes, and the disclosed tags available as raw values. Start here rather than guessing a name.

GET /pack/working-capital

Builds a full working-capital workbook for a screened cohort and returns the .xlsx. This is a real computation over the whole warehouse, so allow up to a couple of minutes.

ParameterRequiredNotes
anchoryesThe subject company
sicyesComma-separated SIC codes defining the cohort
rev_min / rev_maxyesSize band, USD
year_from / year_toyesFiscal year range
min_nnoDefault 8. Percentiles are suppressed below this cohort size rather than computed on too few companies

Fiscal periods — the one thing that trips people up

Join on period_end, never on the fiscal-year label. Two companies can both call a period "FY2025" and mean year-ends eleven months apart. Every response carries period_end for exactly this reason. A comparison built on the FY label will look right and be wrong, and nothing in the output will say so.

Errors

StatusMeaning
401No bearer token was sent
403The token is invalid, expired, or the membership behind it is no longer active
404The company is not in coverage
422The company is covered, but discloses none of the inputs this metric needs for that period — the response names which inputs were missing
400An unknown metric or an unparseable period

A 200 with "value": null is not an error. It is the company not having disclosed the figure, which is a fact about the filing rather than a fault in the request.

Coverage and freshness

US XBRL filers, refreshed from EDGAR. /health reports the newest filing date currently being served; if a company filed after that, its latest figures are not in yet. Restated figures follow the same rule as everything else — the API returns what was filed, and /excel/source tells you which filing that was.