Financial Data

Does the Companies House API return turnover?

No: the official Companies House REST API returns filing metadata, not figures. It tells you that a company filed accounts, when, and where to download them; the turnover number lives inside the filed accounts document, which is mostly iXBRL, and small and micro companies often do not file turnover at all.

The rest of this page covers which companies file turnover, how to extract it yourself, and the JSON you get from Registrum if you would rather not. Examples are real responses captured from the live API on 2026-10-15. For a full walkthrough of one company, see the financials example.

What the official API gives you

The filing history endpoint lists each filing: category, date, a description code and a link to the document. The company profile endpoint carries accounts dates and the last accounts type. Neither carries a profit and loss figure. To read one you fetch the document through the Document API and parse it yourself. Companies House also publishes a free Accounts Data Product of filed accounts in bulk, which is the same parsing job at larger scale.

Which companies file turnover at all

Only companies that file a profit and loss account have a turnover figure. Micro-entities and many small companies file reduced accounts, often a balance sheet only, and a company that files dormant accounts has no trading figures. The size limits that decide this are set by law and change, so check the current rules on GOV.UK rather than a number quoted on a third-party page.

You can see what a company filed without opening the document: the profile's last accounts type takes values such as full, group, small, medium, micro-entity, dormant, total-exemption-full, total-exemption-small and unaudited-abridged. Registrum returns the same value as accounts_type. Large listed companies add a different problem: many file accounts as image-only PDFs with no text layer, which no parser can read without OCR, so there is nothing to extract.

Extracting turnover yourself

  1. Read the filing history and pick the newest filing in the accounts category. Filter by type: administrative forms such as AA01 (change of accounting reference date) also sit in that category and carry a document link, but contain no accounts.
  2. Fetch the document metadata from the Document API and request the iXBRL (XHTML) version. The resources field is keyed by content type, not a list.
  3. Parse the inline XBRL facts and match them to the current period's context.
  4. Normalise the concept name. The same figure appears as uk-core:Turnover, core:Turnover, bus:Turnover, uk-gaap:Turnover or ifrs-full:Revenue depending on the filing software, so strip the namespace and match on synonyms.

Two traps account for most wrong or missing answers:

  • Untagged turnover. Some filers print a Turnover row in the profit and loss account but wrap the value in no iXBRL tag. The figure is visible to a human and absent from the structured data, so no tag mapping, however complete, will find it. In a 307-filing sample of real accounts we confirmed at least four such filings. Treat null as "not extractable", not as zero.
  • Dimensioned facts. A turnover fact can carry a dimension, for example revenue by segment or geography. If you take the first current-period fact you can return a segment as the company's turnover. Prefer the fact with no dimension members, and only fall back to a dimensioned one if none exists.

Getting turnover as JSON from Registrum

GET /v1/company/{number}/financials does the steps above and returns the current and prior-year figure for each field. This is the same call in curl and Python.

curl
curl -H "X-API-Key: reg_live_..." \
  "https://api.registrum.co.uk/v1/company/00034603/financials"
python
import requests

resp = requests.get(
    "https://api.registrum.co.uk/v1/company/00034603/financials",
    headers={"X-API-Key": "reg_live_..."},
    timeout=30,
)
resp.raise_for_status()
data = resp.json()["data"]

turnover = data["profit_and_loss"]["turnover"]
if turnover is None:
    # Not filed, or printed but untagged. Check which before treating it as zero.
    flag = data["data_quality"]["turnover_untagged_suspected"]
    print("no turnover; untagged suspected:", flag)
else:
    print(turnover["current"], turnover["prior"])
python (with the client)
from companies_house import Registrum   # pip install companies-house

reg = Registrum("reg_live_...")
data = reg.financials("00034603")    # the client returns the data object directly

turnover = data["profit_and_loss"]["turnover"]
print(turnover["current"], turnover["prior"] if turnover else None)

The third block uses the companies-house Python package from PyPI.

Gloucester Rugby Limited (00034603) files full accounts with a tagged turnover, so the figure comes back with its prior-year comparative:

response (abbreviated)
{
  "status": "success",
  "data": {
    "company_number": "00034603",
    "company_name": "GLOUCESTER RUGBY LIMITED",
    "accounts_type": "full",
    "period_start": "2024-07-01",
    "period_end": "2025-06-30",
    "currency": "GBP",
    "profit_and_loss": {
      "turnover":         { "current": 13438261, "prior": 14922948 },
      "gross_profit":     { "current": 2507782,  "prior": 3511769 },
      "profit_before_tax":{ "current": -4619296, "prior": -2912421 },
      "profit_after_tax": { "current": -3556187, "prior": -1966225 }
    },
    "data_quality": {
      "turnover_untagged_suspected": false,
      "completeness": 0.9,
      "filed_on": "2026-06-30"
    }
  }
}

BlueCrest Health Screening Limited (08119445) also files full accounts, but its turnover row is printed without a tag. Registrum returns null and says why, instead of inventing a number:

response (abbreviated)
{
  "status": "success",
  "data": {
    "company_number": "08119445",
    "company_name": "BLUECREST HEALTH SCREENING LIMITED",
    "accounts_type": "full",
    "period_end": "2025-12-31",
    "currency": "GBP",
    "profit_and_loss": {
      "turnover": null,
      "profit_before_tax": { "current": 2199515, "prior": 2374192 },
      "profit_after_tax":  { "current": 1974417, "prior": 2247397 }
    },
    "data_quality": {
      "turnover_untagged_suspected": true,
      "missing_fields": ["turnover", "gross_profit", "operating_profit", "depreciation", "stocks"],
      "filed_on": "2026-05-08"
    }
  }
}

turnover_untagged_suspected: true means the filing appears to print a turnover row that carries no tag. missing_fields lists every field the parser looked for and did not find, so a missing figure is distinguishable from a zero.

Questions people ask

Does the Companies House API return turnover?
No. The official REST API returns filing metadata and links to the accounts documents. Turnover is a figure inside those documents, and for many companies it is not there at all.
Does Companies House show turnover?
Only when the company files a profit and loss account. Micro-entities and many small companies file reduced accounts, often a balance sheet only, so there is no turnover to show.
Why is turnover null for a company that files full accounts?
Some filers print a Turnover row in the profit and loss account but do not wrap the value in an iXBRL tag, so the filing carries nothing machine-readable to extract. Registrum returns null with turnover_untagged_suspected set to true rather than guessing.
How do I get turnover from Companies House as JSON?
Either download the accounts through the Document API and parse the iXBRL yourself, or call Registrum GET /v1/company/{number}/financials, which does that parsing and returns turnover with the prior-year comparative as JSON.

Limits to know about

  • Companies have months after their year end to file, so the newest figure can be many months old.
  • Newly incorporated companies may have filed no accounts yet.
  • Image-only PDF accounts cannot be parsed deterministically, so those companies return no figures.

Get your free API key

60 days of full access - every endpoint, no monthly cap. No credit card.

Was this page helpful?