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,882 US filers, 742 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.

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 dateline in the site masthead shows the oldest stamp across the core pools for the same reason. As this page was built, the pools were stamped July 9, 2026 (oldest) to July 18, 2026 (newest).

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-07-18",
    "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-07-18."
}

/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.325284,
      "lo": 0.146453,
      "hi": 0.573064,
      "n": 10
    },
    "operatingMarginThroughCycle": {
      "median": 0.314507,
      "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,
      ""
    ],
    … 3870 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.

/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-07-17",
  "items": [
    [
      "ALV",
      "8-K",
      "Reported results",
      "2026-07-17",
      "/c/ALV",
      null,
      null,
      null,
      0,
      null
    ],
    [
      "FEIM",
      "10-K",
      "Annual report",
      "2026-07-17",
      "/c/FEIM",
      -9.4,
      -125.6,
      null,
      0,
      "fy"
    ],
    … 498 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"
    ],
    … 91 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"
    ],
    … 3826 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);