api.ukdatalayer.com/v1

Twelve endpoints. One response shape.

Nine of them read one company — what it is, what it has filed, what it actually does and how it performs, who runs it, who controls it and the money moving into it (grants is in early access). One resolves a person across the register, one searches the whole index, and one tells you where your allowance stands. Field names never change between companies, and a value that was not disclosed comes back null, never a guess.

Authentication every request · example company 00000042

# bearer key in the header — or ?key=, or X-API-Key
curl "https://api.ukdatalayer.com/v1/company?company_number=00000042" \
  -H "Authorization: Bearer YOUR_KEY"

{
  "status": "success",
  "credits_used": 1,
  "data": {
    "company_number": "00000042",
    "company_name": "NORTHGATE ANALYTICS LTD",
    "company_status": "active",
    "date_of_creation": "2016-05-11",
    "jurisdiction": "england-wales",
    "sic_codes": ["62012"],
    …the rest of the record
  }
}

How the API behaves

Predictable in, predictable out

A company number in the query string, extra layers in ?include=, and the same envelope back every time: status, credits used, data.

Typed, not stringly

Money is a plain number in GBP, dates are ISO 8601, enums are documented — and null means not disclosed, never zero.

Priced by what it costs us

Most calls are one credit. The hard-won layers — parsed accounts, reconstructed ownership, fundraisings — cost two, say so up front, and failures are never billed.

What a call costs

See pricing
1 credit

The registry and intelligence layers: the company record, filings, what it actually does, officers, a person, a search — and /grants once it is live.

2 credits / year

Financials. Every accounting period is parsed out of a filed document and normalised, so it is 2 credits per period returned — ask for three filed years, pay six.

2 credits

Ownership, group structure and /fundraisings — control chains walked and share events reconstructed.

0 credits

Errors, no-data and early-access responses, /account/credits — and the example companies, free and unmetered on every key.

Combining layers in one call with ?include= costs the sum of the layers, never more — and there is no overage billing, allowances simply reset monthly. Every response tells you what it charged, twice: "credits_used": 4 in the body and a real x-udl-credits-charged: 4 response header.

The company record

GET /v1/…?company_number={number}

The record almost everyone starts with — what it is, what it has filed, what it actually does and how it is performing. Each layer stands alone, or rides along on /company with ?include=.

GET /company 1 credit + layers

The registry record

Returns the complete registry record for one company: legal identity, status, incorporation and cessation dates, company type, jurisdiction, SIC codes, the geocoded registered office address, and the accounts and annual-return summaries. This is the base record every other company endpoint builds on.

CoverageEngland & Wales, Scotland, Northern Ireland — 5.48m companies on the total register.

Key params

  • company_number
  • include(optional)

Returns

  • company_status
  • sic_codes
  • registered_office_address
  • accounts_summary
  • company_previous_names
  • certifications
Full reference

GET /company?key=YOUR_KEY&company_number=00000042

{
  "status": "success",
  "credits_used": 1,
  "data": {
    "company_id": "UK-00000042",
    "company_number": "00000042",
    "company_name": "NORTHGATE ANALYTICS LTD",
    "company_status": "active",
    "company_type": "ltd",
    "date_of_creation": "2016-05-11",
    "date_of_cessation": null,
    "sic_codes": ["62012"],
    "jurisdiction": "england-wales",
    "region": "South West",
    "registered_office_address": {
      "address_string": "6 Northgate Street, Bristol, BS1 2AW",
      "lat": 51.4545,
      "lon": -2.5879
    },
    "accounts_summary": {
      "last_accounts_made_up_to": "2025-03-31",
      "last_accounts_type": "full",
      "next_due": "2026-12-31",
      "overdue": false
    },
    "has_charges": false,
    "has_insolvency_history": false,
    "certifications": []
  }
}

GET /company-filings 1 credit

What they have filed

Returns the filing history recorded at Companies House for one company: accounts, confirmation statements, officer changes, charge registrations, share allotments and mortgage filings. Use this to detect material change rather than re-polling the whole record.

CoverageAll UK jurisdictions. History depth varies by company age.

Key params

  • company_number
  • category(optional)
  • limit(optional)
  • cursor(optional)

Returns

  • filings[].category
  • filings[].type
  • filings[].date
  • filings[].made_up_to
  • next_cursor
Full reference

GET /company-filings?key=YOUR_KEY&company_number=00000042&limit=25

{
  "status": "success",
  "credits_used": 1,
  "data": {
    "company_number": "00000042",
    "filings": [
      {
        "category": "accounts",
        "type": "AA",
        "description": "accounts-with-accounts-type-full",
        "description_text": "Full accounts made up to 2025-03-31",
        "date": "2025-09-18",
        "made_up_to": "2025-03-31",
        "pages": 24,
        "transaction_id": "SANDBOX0001",
        "document_available": true,
        "document_url": "https://find-and-update.company-information.service.gov.uk/company/00000042/filing-history/SANDBOX0001/document?format=pdf"
      },
      {
        "category": "confirmation-statement",
        "type": "CS01",
        "description": "confirmation-statement-with-no-updates",
        "description_text": "Confirmation statement made up to 2025-05-11 with no updates",
        "date": "2025-05-19",
        "made_up_to": "2025-05-11",
        "pages": 3,
        "transaction_id": "SANDBOX0002",
        "document_available": true,
        "document_url": "https://find-and-update.company-information.service.gov.uk/company/00000042/filing-history/SANDBOX0002/document?format=pdf"
      }
    ],
    "next_cursor": null
  }
}

GET /financials 2 credits / period

How they are doing

Returns filed accounts normalised into consistent fields across every accounts type, plus compound annual growth rates over 1, 3 and 5 years. Saves you maintaining an iXBRL parser and reconciling micro-entity, abridged and full accounts into one shape.

CoverageCompanies that have filed accounts. Turnover is disclosed for a minority of companies — most small UK companies are not required to publish a profit and loss account.

Key params

  • company_number
  • period(optional)

Returns

  • turnover
  • ebitda
  • cash_eq
  • sh_funds
  • num_employees
  • growth
Full reference

GET /financials?key=YOUR_KEY&company_number=00000042&period=latest

{
  "status": "success",
  "credits_used": 2,
  "data": {
    "company_id": "UK-00000042",
    "period_end": "2025-03-31",
    "accounts_type": "full",
    "currency": "GBP",
    "turnover": 4120000,
    "cost_of_sales": 1236000,
    "gross_profit": 2884000,
    "op_profit_loss": 412500,
    "profit_loss_after_tax": 331900,
    "ebitda": 596300,
    "cash_eq": 1880400,
    "net_curr_assets": 1244600,
    "sh_funds": 2306800,
    "num_employees": 42,
    "source_filing": {
      "filed_on": "2025-09-18",
      "document_url": "https://find-and-update.company-information.service.gov.uk/company/00000042/filing-history/SANDBOX0001/document?format=pdf",
      "pages": 24
    },
    "ratios": {
      "gross_margin": 0.7,
      "operating_margin": 0.1001,
      "net_margin": 0.0806,
      "return_on_equity": 0.1439,
      "staff_cost_ratio": null,
      "turnover_per_employee": 98095
    },
    "growth": {
      "turnover_cagr_1y": 0.312,
      "turnover_cagr_3y": 0.268,
      "ebitda_cagr_3y": 0.194,
      "num_employees_cagr_3y": 0.221
    }
  }
}

People and control

/officers · /ownership · /group-structure · /person

Four questions that get muddled together everywhere else: who runs the company, who controls it, where it sits in a group, and what else one person is involved in. Ask the one you need.

GET /officers 1 credit

Who runs it

Returns every officer appointment recorded against a company, with role, appointment and resignation dates, occupation, nationality and a stable person identifier you can use to pivot to that person’s other directorships.

CoverageAll UK jurisdictions. Includes corporate officers and nominee appointments, flagged as such.

Key params

  • company_number
  • status(optional)

Returns

  • officers[].name
  • officers[].officer_role
  • officers[].appointed_on
  • officers[].resigned_on
  • officers[].person_number_short
Full reference

GET /officers?key=YOUR_KEY&company_number=00000042&status=active

{
  "status": "success",
  "credits_used": 1,
  "data": {
    "company_number": "00000042",
    "officers": [
      {
        "person_number_short": "900000123",
        "name": "Priya Raman",
        "officer_role": "director",
        "occupation": "Chief Executive",
        "nationality": "British",
        "date_of_birth": "1984-03",
        "appointed_on": "2016-05-11",
        "resigned_on": null,
        "officer_is_company": false
      },
      {
        "person_number_short": "900000124",
        "name": "Daniel Okoro",
        "officer_role": "director",
        "occupation": "Chief Technology Officer",
        "nationality": "British",
        "date_of_birth": "1987-11",
        "appointed_on": "2016-05-11",
        "resigned_on": null,
        "officer_is_company": false
      }
    ],
    "total": 2
  }
}

GET /ownership 2 credits

Who controls it

Returns who controls the company: persons with significant control as filed, plus the shareholder register from confirmation statements with share classes and percentage holdings. Corporate controllers are linked to their own company record so you can walk the chain.

CoverageThe PSC regime begins April 2016 — companies dissolved before then have no PSC record. Shareholder registers come from annual confirmation statements, so they are annual snapshots rather than live.

Key params

  • company_number
  • include_ceased(optional)

Returns

  • controls[].kind
  • controls[].natures_of_control
  • shareholders[].shares_perc
  • shareholders[].share_class
  • total_shareholders
Full reference

GET /ownership?key=YOUR_KEY&company_number=00000042

{
  "status": "success",
  "credits_used": 2,
  "data": {
    "company_number": "00000042",
    "controls": [
      {
        "name": "NORTHGATE GROUP HOLDINGS LTD",
        "kind": "corporate-entity-person-with-significant-control",
        "natures_of_control": ["ownership-of-shares-75-to-100-percent"],
        "notified_on": "2022-09-30",
        "ceased_on": null,
        "control_is_company": true,
        "parent_company_id": "UK-00000041"
      }
    ],
    "shareholders": [
      {
        "name": "NORTHGATE GROUP HOLDINGS LTD",
        "shares_perc": 82.5,
        "share_class": "ORDINARY",
        "is_company": true
      },
      {
        "name": "Priya Raman",
        "shares_perc": 17.5,
        "share_class": "ORDINARY",
        "is_company": false
      }
    ],
    "total_shareholders": 2
  }
}

GET /group-structure 2 credits

Where it sits in a group

Walks the corporate control chain in both directions from one company: every corporate parent above it and every company it controls below it, resolved recursively to a depth of 10 with cycle protection. Built from corporate PSC records rather than name matching.

CoverageCorporate relationships disclosed under the PSC regime, so from April 2016 onwards.

Key params

  • company_number
  • direction(optional)
  • max_depth(optional)
  • view(optional)

Returns

  • control_ancestors[]
  • control_descendants[]
  • depth
  • control_path
  • child_company_count
Full reference

GET /group-structure?key=YOUR_KEY&company_number=00000041&direction=descendants

{
  "status": "success",
  "credits_used": 2,
  "data": {
    "company_number": "00000041",
    "control_descendants": [
      {
        "company_id": "UK-00000042",
        "company_name": "NORTHGATE ANALYTICS LTD",
        "natures_of_control": ["ownership-of-shares-75-to-100-percent"],
        "depth": 1,
        "control_path": ["UK-00000041", "UK-00000042"]
      },
      {
        "company_id": "UK-00000043",
        "company_name": "NORTHGATE ANALYTICS IRELAND LTD",
        "natures_of_control": ["ownership-of-shares-75-to-100-percent"],
        "depth": 2,
        "control_path": ["UK-00000041", "UK-00000042", "UK-00000043"]
      }
    ],
    "child_company_count": 1,
    "parent_company_count": 0
  }
}

GET /person 1 credit

One person, every appointment

Returns a resolved individual and every directorship they hold or have held, along with companies related through shared directors and PSCs. Identity is resolved across name variants, so "Priya Raman" and "Priya A Raman" collapse to one person rather than two.

CoverageAll officers recorded at Companies House across the UK.

Key params

  • person_number_short
  • include_resigned(optional)

Returns

  • name
  • appointments[]
  • total_appointments
  • related_companies[]
  • former_names
Full reference

GET /person?key=YOUR_KEY&person_number_short=900000123

{
  "status": "success",
  "credits_used": 1,
  "data": {
    "person_number_short": "900000123",
    "name": "Priya Raman",
    "date_of_birth": "1984-03",
    "nationality": "British",
    "country_of_residence": "England",
    "former_names": [],
    "appointments": [
      {
        "company_id": "UK-00000042",
        "company_name": "NORTHGATE ANALYTICS LTD",
        "officer_role": "director",
        "appointed_on": "2016-05-11",
        "resigned_on": null
      },
      {
        "company_id": "UK-00000041",
        "company_name": "NORTHGATE GROUP HOLDINGS LTD",
        "officer_role": "director",
        "appointed_on": "2022-09-30",
        "resigned_on": null
      }
    ],
    "total_appointments": 2
  }
}

Funding signals

/fundraisings · /grants

Money moving into a company, read straight from the register — often before anything is announced. Fundraisings is live: SH01 share allotments reconstructed into events with the amount, price and date. Grants — public awards matched to the legal entity — is in early access: the route answers today, costs nothing until data lands, and starts returning it without a version change.

GET /grants 1 credit · early access Early access

Public grants and awards

Returns public funding awarded to the company — Innovate UK, R&D and regional growth programmes — matched to the legal entity rather than to a name string. Tells you who is building something before there is revenue to show for it.

Rolling out now

Early access — the dataset is rolling out. The endpoint is live in the v1 contract and returns status "early_access" until data lands; it will start returning grants without a version change.

No credits are consumed until data flows, and the fields below are the documented contract — integrate against them today.

Key params

  • company_number

Returns

  • total_awarded
  • grants[].funder
  • grants[].programme
  • grants[].amount
  • grants[].awarded_on
  • grants[].match_confidence
Full reference

GET /grants?key=YOUR_KEY&company_number=00000042

{
  "status": "early_access",
  "credits_used": 0,
  "message": "Public grants and awards (Innovate UK, R&D and regional growth funding, matched to the company) are rolling out. The endpoint is part of the v1 contract and will start returning data without a version change. No credits are consumed until it does."
}

Across the register

For when the question is not about one company: search the enriched index, keep an eye on your allowance — and a straight answer on what we have not shipped yet.

GET /search 1 credit

Find companies by what they do

Free text and structured filters run together across descriptions, offerings and customers — so "careers guidance software" matches a destinations platform for students without sharing a keyword.

127,000+ enriched companies at launch — active businesses with a verified website, classified facets and financials. Expanding towards the full register.

Full reference
/search?q=careers+guidance+software
  &filter=org_kind:=product_vendor
// "found": 342 · 1 credit

GET /account/credits free

Where your allowance stands

The credit balance, plan allowance and reset date for the key making the request. Free to call, so your dashboard never has to guess.

Full reference
/account/credits
// free — "credits_remaining": 22841

not shipped yet

What is not here

No webhooks, no bulk export, no SDKs yet — we would rather tell you that up front. The API is plain HTTPS and JSON with versioned schemas, and /company-filings is built for detecting change in the meantime.

Change detection
# until webhooks ship, poll newest-first
/company-filings?company_number=00000042

Errors you can act on

Standard status codes, a stable envelope, and a message you could put in front of a user. Nothing that fails is billed.

API status codes and what they mean
CodeMeaning
200Success. Credits were consumed.
400Missing or malformed parameter. No credits consumed.
401Missing, invalid or revoked API key. No credits consumed.
402Credit allowance exhausted for the current period.
404The company number or person ID does not exist. No credits consumed.
429Rate limit exceeded. Retry after the period given in the Retry-After header.
500Server error. No credits consumed — please retry.
501The requested lookup variant is not implemented yet. No credits consumed.
503The endpoint is not live yet. No credits consumed.
Error reference in the docs

Limits stated up front

Every response tells you what it cost. The limits are the same numbers we publish — not ones you discover in production.

  • 10 requests a second on the Free and Build plans; 50 a second on Scale 250k. Limits apply per key.
  • Break the limit and you get 429 with a Retry-After header saying when to come back.
  • Allowances reset monthly. When one runs out, requests return 402 until the reset — there is no overage billing.
  • credits_used is on every response body, the x-udl-credits-charged header is on every response — and failed requests always report zero.
{
  "status": "error",
  "code": 404,
  "credits_used": 0,
  "message": "No company found with number 99999999"
}

START FREE 50 LIVE CREDITS A MONTH

Try it against a company you already know.

The free plan runs against the live register — 50 credits a month, and the example companies stay free and unmetered, so you can build the whole integration before paying. No card required.