Registrum vs Companies House API

What Registrum adds on top of Companies House

The Companies House API is free and official - but it returns raw metadata with no financial data, no computed fields, and no resilience. Registrum adds 16 data categories and the infrastructure to use it reliably in production.

The response, side by side

Same company (Tesco PLC, 00445790), same instant. Highlighted fields are computed, derived, or entirely new.

Companies House API - raw

{

"company_name": "TESCO PLC",

"company_number": "00445790",

"company_status": "active",

"type": "plc",

"date_of_creation": "1947-11-27",

"registered_office_address": { ... },

"sic_codes": ["47110"],

"accounts": { "next_accounts": { "due_on": "2024-07-24" }, "last_accounts": { "made_up_to": "2024-02-24" } },

"confirmation_statement": { "next_due": "2025-06-15" },

"links": { "filing_history": "...", "officers": "..." },

}

≈ 10 fields · No financial data · Dates require calculation · No quality signals

Registrum API - enriched+18 fields

{

"company_name": "TESCO PLC",

"company_number": "00445790",

"company_status": "active",

"company_age_years": 78,enriched

"accounts": { "overdue": false, "next_due": "2024-07-24" },enriched

"sic_codes": ["47110"],

"sic_descriptions": ["Retail sale in non-specialised stores"],enriched

"financials": { "turnover": { "current": 68190000000 }, "profit_after_tax": { "current": 1400000000 }, ... },new field

"cached": true,

"credits_remaining": 49,

}

enrichednew fieldimprovedinfrastructure

Field-by-field comparison

Data categoryCompanies House (direct)Registrum
Company name / number / status✓ Raw
✓ Same
Company age✗ Must calculate from date_of_creation
✓ company_age_years pre-computedenriched
Accounts overdue✗ Must compare two date fields
✓ accounts.overdue booleanenriched
Confirmation overdue✗ Must compare two date fields
✓ confirmation_statement.overdue booleanenriched
SIC code descriptions✗ Codes only (e.g. 47110)
✓ Human-readable descriptions includedenriched
Revenue / turnover✗ Link to iXBRL filing document only
✓ Parsed JSON integer (actual GBP)new field
Profit & loss statement✗ Not available via API
✓ Full P&L: gross profit, operating profit, PATnew field
Balance sheet✗ Not available via API
✓ Assets, liabilities, equity, net assetsnew field
Employee count✗ Not available via API
✓ average_employees from filingsnew field
Prior year financials✗ Not available via API
✓ prior field on every financial valuenew field
Director list✓ Paginated (multiple calls required)
✓ Deduplicated, single endpointimproved
Director appointments✗ One API call per director
✓ Included in directors responsenew field
Director network (related companies)✗ Many paginated calls, manual dedup required
✓ One network endpoint, auto-traversalnew field
CH API key registration✗ Register at CH developer portal, manage your own key
✓ No CH key needed - one Registrum key covers everythinginfrastructure
Rate limit protection✗ 600 req/5min, errors propagate to your app
✓ Cached responses, shared budget shieldedinfrastructure
Resilience on CH outage✗ 5xx errors propagate to your app
✓ Stale cache served with X-Data-Stale headerinfrastructure
Request tracing✗ No correlation IDs
✓ X-Request-Id on every responseinfrastructure
Data quality signals✗ None
✓ data_quality block with completeness rationew field

The real cost of doing it yourself

The director network endpoint collapses ~16 paginated CH API calls into one. Each of those raw calls counts toward your 600 req/5min limit - and produces no caching. With Registrum the result is cached for 30 days and shared across all your requests.

Director network - raw CH API · ~16 API calls
# Python - director network with raw CH API
# Requires multiple paginated calls

import requests, base64

def get_network(company_number, ch_api_key):
    auth = base64.b64encode(f"{ch_api_key}:".encode()).decode()
    headers = {"Authorization": f"Basic {auth}"}
    base = "https://api.company-information.service.gov.uk"

    # Step 1: get officers
    officers = requests.get(
        f"{base}/company/{company_number}/officers",
        headers=headers
    ).json().get("items", [])

    network = {}
    seen_officers = set()

    for officer in officers:
        link = officer.get("links", {}).get("officer", {})
        appts_path = link.get("appointments", "")
        officer_id = appts_path.strip("/").split("/")[1]

        if officer_id in seen_officers:
            continue
        seen_officers.add(officer_id)

        # Step 2: one call per officer
        appts = requests.get(
            f"{base}/officers/{officer_id}/appointments",
            headers=headers
        ).json().get("items", [])

        for a in appts:
            cn = a.get("appointed_to", {}).get("company_number")
            if cn and cn != company_number:
                network.setdefault(cn, []).append(officer["name"])

    # Result: 1 + N calls (N = number of officers)
    # Tesco has ~15 officers = ~16 CH API calls
    # No caching. Rate limit consumed every time.
    return network
Director network - Registrum · 1 API call
# Python - director network with Registrum
# One call. Cached 24h. Rate-limit safe.

import requests

def get_network(company_number, api_key):
    r = requests.get(
        f"https://api.registrum.co.uk/v1/company/{company_number}/network",
        params={"depth": 1},
        headers={"X-API-Key": api_key},
    )
    data = r.json()["data"]
    return data["companies"]
    # Returns: list of connected companies
    # sorted by connection strength (shared directors)

Try it free

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

Was this page helpful?