Owner Scorecard


The data, documented

Every figure this publication renders is also served as static JSON. This page documents each public endpoint: its URL, its exact shape, one real example, its freshness, and the terms. It is written for a programmer and for an AI agent alike.

Coverage today: 2,858 US filers, 741 ADRs (foreign 20-F filers), and 204 Japanese companies. A machine-readable site guide lives at /llms.txt, with an expanded index of the browse surfaces at /llms-full.txt.

The terms

The endpoints are free. There is no key, no login, and no registered application.

There are no rate-limit promises beyond politeness. Everything here is a static file behind a CDN; ordinary use needs no throttling. If you fetch in bulk, honor the cache headers and keep to a few requests a second.

Attribution is requested, never required: "Owner Scorecard (ownerscorecard.com), data from SEC filings". Company records and Notes carry a suggested citation on the page and in the JSON; use it where a fuller cite fits.

Every figure is either as the company filed it or computed with the method named. The computations are defined on the Principles page, and each JSON record names its source under provenance.

The files carry no ratings, no estimates, and no price data, by design: the publication presents the record and leaves the judgment to the reader, and a judgment quoted bare by a machine reads as a rating.

Method change, dated: on July 31, 2026 the trailing-twelve-month accounts-payable figure gained a pair guard. Many filers tag the pure trade-payables concept on the annual balance sheet but only a combined payables-and-accrued concept in their quarterly filings, and the trailing cell used to switch basis silently on the tag change. Now the pure concept stands where the latest quarter carries it; a combined-only quarter is decomposed through the filer's own most recent year in which both concepts were tagged; and where no such year exists the cell is withheld. Working capital and the current ratio inherit the same treatment.

Method change, dated: on July 21, 2026 the insurer float figures moved from the narrow loss-reserves basis to the full arithmetic (net reserves plus unearned premiums and policy benefits, less prepaid reinsurance, receivables and deferred acquisition costs), and the yield-on-float figures moved to the same denominator. Insurer records also gained the prior-year reserve-development line, signed as filed (negative favorable). Where a filer's components don't extract cleanly the figure is withheld rather than approximated, and the basis in use is named beside every float figure.

Correction, dated: on July 21, 2026 the reserve-development line gained a sign-integrity gate arbitrated by each filer's own arithmetic (current-year incurred plus prior-year development must equal total incurred). It corrected Elevance's 2016–2021 development, which our extraction had carried with the sign convention of the filer's earlier tagging regime — six favorable years had displayed as adverse — and single mis-signed years at Centene and Humana. Years the identity rejects both ways are withheld. Separately, Cigna's legacy life-policy reserves no longer read as a claims liability, and Trupanion, a pet insurer, moved from the Managed Care grouping to Insurance — Property & Casualty.

Method extension, dated: on July 21, 2026 a second extraction tier began reading named facts from the filings’ own inline XBRL where the SEC’s structured-data API is blind — each target mapped to its exact dimensional coordinates and value-verified before entry, behind the same identity gates as every other line. Four withheld records came down that day: Travelers’ reserve development (eight years, the incurred identity holding exactly in each), Cigna’s insurance-book development and claims liabilities, Centene’s premium line (restoring its medical-loss ratio), and Wells Fargo’s modern net charge-offs (two independent identities per year). What remains withheld remains for a stated reason.

Correction, dated: on July 22, 2026 the overhead row was rebuilt. Software and much of modern services never file the combined selling, general and administrative element at all; they file selling-and-marketing and general-and-administrative separately, and the row had been showing only the second under the first’s name. Where both legs are filed they are now summed, which is the concept the row claims to show. Where a business genuinely runs no selling line, its administrative expense still stands alone. The figures move a long way at the companies affected: Salesforce read 7 percent of revenue and is 42, Adobe read 7 and is 34, Oracle read 2 and is 15.

Correction, dated: on July 22, 2026 the fiscal-year label was fixed for filers on a 52- or 53-week calendar whose year ends in the first days of January. Their year belongs to the one that just closed, and reading it as the calendar year of the period end both mislabelled the column and collided two real years into one, erasing the older. Leidos regains its 2020 and Cadence its 2021. Filers ending in late January, whose own convention names the later year, are unaffected.

Correction, dated: on July 22, 2026 two rules were added to the cost-of-sales line. Some filers tag a small fragment under one element and the true total under a near synonym, and taking the first of them printed a 99.9 percent gross margin for Caterpillar against a true 33.8. Where the two disagree by more than tenfold the larger is now read as the total; where they differ narrowly, which is a presentation choice rather than a difference of scope, the established order still decides. And where a filer tags only the fragment, with no larger element to promote, the line is withheld rather than shown: a utility that buys fuel does not have a 100 percent gross margin, and the row now reads as unavailable.

Method extension, dated: on July 25, 2026 the software shelf gained three readings, and one rule about what will not be shown. Remaining performance obligations are revenue a customer has committed to and the company has not yet earned, the nearest thing a software business has to an insurer’s float. The headline total misleads on its own, because a contract signed for seven years counts the same as one signed for one: Oracle’s total rose elevenfold in a year while the share it expects to collect within twelve months fell from 62 percent to 12. So the total is never shown without that twelve-month band for the same year end, and where a company discloses the band only in prose, as Oracle does, both figures are withheld. The band itself is read from the filings’ own inline XBRL where it is tagged behind a dimension the structured-data API omits, and it is published exactly as filed rather than multiplied back into dollars the filer called approximate. Alongside it, sales and marketing is carried as its own line, and stock compensation is shown against the change in the share count, because a repurchase that merely cancels the shares issued as pay returns nothing to an owner. Where a stock split or a first listing sits inside the window, the share-count change is withheld rather than reported as a change that never happened.

Freshness

Every data pool carries an asOf stamp written by the pipeline at its last successful refresh, never the build clock. The record endpoints repeat their pool's stamp under provenance.asOf; /wire-lite.json carries its own asOf and refreshes daily. If a refresh silently stops, the stamp freezes and the staleness is visible rather than hidden behind a fresh build date. The masthead dateline shows the oldest stamp across the four record pools; the enrichment layers run on their own, deliberately slower clocks and are dated here and where they render.

DatasetAs ofCadence
US records (fundamentals.json)2026-08-20weekdays
ADR records (fundamentals.adr.json)2026-08-17weekly
Japan records (fundamentals.jp.json)2026-08-20weekly
Europe records (fundamentals.eu.json)2026-08-20weekly
Filing language (language.json)2026-08-05monthly — narrative changes only with a new annual report
Segments (segments.json)2026-08-20monthly
Market rates (rates.json)2026-08-18with the record refreshes; each rate carries its own date where it renders
Executive pay (proxyComp.json)2026-07-19proxy season; refreshed as proxies file
Meeting votes (voteResults.json)2026-07-19meeting season; refreshed as results file
ADS ratios (adrRatios.json)2026-08-05on depositary-program changes
The wire (wire.json)2026-08-20daily

Stability

URLs are permanent. Nothing that has been linked is allowed to 404; renamed surfaces leave 301 redirects behind (as /articles and /archetypes did).

The tuple-shaped files (company-index, wire-lite, follow-context) carry a v field, and their rows only ever gain trailing fields: a consumer indexing the positions documented below keeps working. The object-shaped files (the record, the card) gain fields; existing fields are never renamed or repurposed. An absent field means the company did not disclose that item, not zero.

Every endpoint is a static file, rebuilt at most daily. Responses revalidate cheaply with ETags; /company-index.json also carries a one-hour browser TTL. If you cache on your side, key on the asOf stamps: an unchanged stamp means unchanged figures.

The endpoints

/c/{TICKER}.json — the full record

One company's record: roughly a decade of filed line items, the latest filing's identifiers, provenance, and a suggested citation. Covers the US and ADR pools (Japanese companies appear in the card and index endpoints below). record is an array of fiscal years, oldest first; each year's lines holds the filed line items in as-reported units (USD for US filers, home currency for ADRs). latest repeats the most recent year's lines. Example: /c/ADBE.json, truncated:

{
  "ticker": "ADBE",
  "name": "Adobe Inc.",
  "cik": "0000796343",
  "latestFiling": {
    "fy": 2025,
    "form": "10-K",
    "periodEnd": "2025-11-28"
  },
  "sourceUrl": "https://www.sec.gov/Archives/edgar/data/796343/000079634326000003/0000796343-26-000003-index.htm",
  "record": [
    … 9 earlier fiscal years
    {
      "fy": 2025,
      "lines": {
        "revenue": 23769000000,
        "operatingIncome": 8706000000,
        "netIncome": 7130000000,
        "cashFromOps": 10031000000,
        "capex": 179000000,
        "sharesDiluted": 427000000,
        "totalDebt": 6210000000,
        "stockholdersEquity": 11623000000,
        … more line items
      }
    }
  ],
  "latest": {
    "revenue": 23769000000,
    "operatingIncome": 8706000000,
    "netIncome": 7130000000,
    "cashFromOps": 10031000000,
    … more line items
  },
  "provenance": {
    "source": "SEC EDGAR XBRL (companyfacts)",
    "asOf": "2026-08-20",
    "note": "Every figure traces to the company's own filings. This endpoint carries no ratings, estimates, or derived judgments by design."
  },
  "page": "https://ownerscorecard.com/c/ADBE",
  "publisher": "Owner Scorecard",
  "suggestedCitation": "Owner Scorecard, \"Adobe Inc. (ADBE), the owner's record,\" https://ownerscorecard.com/c/ADBE, data as of 2026-08-20."
}

/compare/{TICKER}.json — the record card

The slim per-company card behind the Compare page: the record reduced to quality, compounding, survival, stewardship, and the inputs a reverse-DCF needs to turn a price into "what you'd have to believe." All three pools, including Japan. Ratios are decimals (0.06 is six percent), money is whole as-reported units, null means not disclosed or not reliably computable. Example: /compare/ADBE.json, truncated:

{
  "ticker": "ADBE",
  "name": "Adobe Inc.",
  "pool": "US",
  "currency": "USD",
  "fy": 2025,
  "recordYears": 10,
  "spanLabel": "2016–2025",
  "quality": {
    "roicThroughCycle": {
      "median": 0.326829,
      "lo": 0.146453,
      "hi": 0.573064,
      "n": 10
    },
    "operatingMarginThroughCycle": {
      "median": 0.321887,
      "lo": 0.255123,
      "hi": 0.367564,
      "n": 10
    },
    "grossMarginLatest": 0.894039,
    … 4 more fields
  },
  "survival": {
    "netDebt": 1019000000,
    "netCash": false,
    "interestCoverage": 34.827586,
    "profitableYears": 10,
    … more fields, and graham: the defensive tests as rows
  },
  "stewardship": {
    "shareChange": -0.193732,
    "returnOnRetained": null,
    … 8 more fields
  },
  "price": {
    "mode": "owner-earnings",
    "shares": 397500000,
    "netDebt": 1019000000,
    "oe": 10280000000,
    "gDeliv": 0.055552,
    … more reverse-DCF inputs
  },
  … sym, form, archetype, basis, compounding
}

/company-index.json — every covered company

One row per company across all three pools: [ticker, name, poolCode, prominence, place]. poolCode 0 is the United States, 1 is ADR, 2 is Japan; the page URL follows from it (/jp/<ticker> for pool 2, /c/<ticker> otherwise). prominence is a log-scaled revenue magnitude used only for ordering search matches; place is the country (ADRs) or industry (Japan). Truncated:

{
  "v": 1,
  "rows": [
    [
      "A",
      "Agilent Technologies Inc.",
      0,
      98,
      ""
    ],
    [
      "AA",
      "Alcoa",
      0,
      101,
      ""
    ],
    [
      "AAL",
      "American Airlines Group",
      0,
      107,
      ""
    ],
    … 3845 more rows
  ]
}

/ledger.json — the Ledger, checkable by machine

Every dated conclusion the publication has reached, verbatim, oldest first, with its date and the note that reached it — the same record the Ledger renders. Entries are never edited, never removed, and never graded by the publication itself. The endpoint exists so the record can be audited programmatically by anyone, including the assistant a reader asks. The same honesty runs the other way too: companies whose data cannot support a truthful page are withheld and named.

/wire-lite.json — the day's filings

The Filing Wire reduced to its public facts, one tuple per filing: [ticker, form, label, date, href, revYoyPct, oiYoyPct, quote, grave, basis]. href is null where the library has no page for the ticker. revYoyPct, oiYoyPct and quote are null except on 10-K/10-Q items whose XBRL carried the comparison: year-over-year revenue and operating-income change in percent, computed from the filing's own prior-year figures, and the company's verbatim MD&A sentence where one passed the verification gates. grave is 1 when the filing reports an SEC-defined material 8-K event and 0 otherwise; basis names the comparison period (fy, ytd, or yoy) where those figures are present. Refreshes daily. Truncated:

{
  "v": 1,
  "asOf": "2026-08-20",
  "items": [
    [
      "ADI",
      "10-Q",
      "Quarterly report",
      "2026-08-19",
      "/c/ADI",
      39.6,
      97.2,
      null,
      0,
      "quarter"
    ],
    [
      "ADI",
      "8-K",
      "Reported results",
      "2026-08-19",
      "/c/ADI",
      null,
      null,
      null,
      0,
      null
    ],
    … 798 more items
  ]
}

/follow-context.json — names, chapters, latest filings

One compact row per company for putting a name, an industry chapter, and the latest annual filing beside a bare ticker. industries is [label, slug] per chapter (the slug routes to /industries/<slug>); rows is [ticker, name, pool, industryIdx, fy, form, periodEnd], where industryIdx points into industries and is −1 where no chapter exists. Truncated:

{
  "v": 2,
  "industries": [
    [
      "Life Sciences Tools & Services",
      "life-sciences-tools-and-services"
    ],
    [
      "Metals & Mining",
      "metals-and-mining"
    ],
    … 99 more chapters
  ],
  "rows": [
    [
      "A",
      "Agilent Technologies Inc.",
      0,
      0,
      2025,
      "10-K",
      "2025-10-31"
    ],
    [
      "AA",
      "Alcoa",
      0,
      1,
      2025,
      "10-K",
      "2025-12-31"
    ],
    … 3801 more rows
  ]
}

/llms.txt and /llms-full.txt — the site, for machines

Plain-text guides in the llms.txt convention: what the site is, where the surfaces live, the URL patterns, the citation format, and the data vintage. /llms-full.txt adds the full index of grouping tables and industry chapters, one line each. Both are static text; neither inlines company data.

/wire.xml — the Filing Wire, as a feed

The Filing Wire as an Atom 1.0 feed: one entry per SEC filing, newest first, each keyed by its filing accession number (a stable, un-fakeable id that never re-notifies a reader on rebuild) and dated with the filing's own date, never the build clock. Every entry carries the plain-English label, the computed year-over-year figures where the filing supplied them, and links to both the company's record page and the EDGAR source; entries are tagged with the ticker and form so a reader's rules can filter per company or per form. The Notes are published separately at /rss.xml. Both feeds are discoverable from every page's <link rel="alternate"> tags.

A worked example

From a shell:

curl -s https://ownerscorecard.com/c/ADBE.json

Reading a record in Node (18 or later, no dependencies):

const res = await fetch("https://ownerscorecard.com/c/ADBE.json");
const rec = await res.json();

console.log(rec.name, "FY" + rec.latestFiling.fy, "as of", rec.provenance.asOf);
for (const year of rec.record.slice(-3)) {
  const m = year.lines.operatingIncome / year.lines.revenue;
  console.log(year.fy, (m * 100).toFixed(1) + "% operating margin");
}
console.log("Filed at:", rec.sourceUrl);
console.log(rec.suggestedCitation);