The Companies House API documentation is functional. It tells you what endpoints exist, what parameters they take, and what fields the responses contain. What it doesn’t tell you is what happens when the data doesn’t come back the way you expect, which company types behave differently from others, and where the edge cases will bite you in production.
These are seven things I’ve found building Companies House integrations that I wish I’d known before I started. None of them are insurmountable, but all of them have caused unexpected debugging time for people who assumed the documentation covered everything.
1. Search and profile are two different endpoints with two different data sets
The /search/companies endpoint and the /company/{company_number} endpoint both return company data, but they return different subsets of it. This catches people out when they build a search-first flow and assume the search results contain everything they need.
Search results include: company name, number, status, company type, date of creation, address snippet, and a few other fields. They do not include SIC codes, accounts due dates, confirmation statement due dates, charges flags, or insolvency flags.
The profile endpoint returns all of those. So if your integration needs the full data set, you need two calls: search to find the company number, then profile to get the complete record. Build this into your architecture from the start rather than discovering you need the second call after you’ve already built the search-and-display flow.
2. Company numbers need zero-padding and it matters
UK company registration numbers are nominally eight characters. Older companies have numbers that are fewer than eight digits — sometimes six, sometimes seven — and the convention is to left-pad them with zeros to eight characters. Companies House does this automatically in the UI but the API is less forgiving.
If a user enters a company number as 123456 and you send it to the API as 123456, you may get a 404 rather than the company record. The same company at 00123456 returns the correct result.
Scottish companies use a different format: SC followed by six digits (SC123456). Northern Ireland companies use NI followed by six digits. These don’t need zero-padding in the same way but they do need correct prefix handling — the API won’t find a Scottish company if you submit its number without the SC prefix.
Build a normalisation function that handles zero-padding and prefix detection before you send anything to the API.
3. The rate limit is per API key across all endpoints
The Companies House API rate limit is 600 requests per five minutes. What the documentation doesn’t spell out clearly is that this limit applies across all endpoints combined, not per endpoint. A single page load that makes three API calls — profile, officers, and filing history — uses three of your 600 requests.
For most use cases this is fine. 600 requests per five minutes is 7,200 per hour, which is more than enough for a single-user tool or a low-traffic integration. But if you’re building something with multiple concurrent users, or if you’re running scheduled monitoring checks across a large company watch list, you need to account for this in your architecture.
The solution is caching: store the API response alongside a timestamp and serve the cached version for repeat lookups within a defined window. For most data — company profile, officer details — a cache lifetime of an hour or a day is appropriate. For a public-facing search tool, caching repeat lookups eliminates the vast majority of your API calls.
4. Dissolved companies return data — you have to check the status explicitly
This one has caused production bugs in integrations I’ve reviewed. When you request the profile of a dissolved company, the API returns a full response with a 200 status code. It doesn’t return an error. The company record exists, it’s just that company_status is "dissolved" rather than "active".
If your integration assumes a 200 response means the company is active and doesn’t check the company_status field, you’ll accept dissolved companies without flagging them. For a recruitment agency verifying client companies before extending credit, or a lender running KYB checks, this is a significant gap.
Always check company_status explicitly. The possible values are: active, dissolved, liquidation, receivership, administration, voluntary-arrangement, converted-closed, registered, and removed. Only active and registered represent currently operating companies.
5. Registered address fields are inconsistently structured
The Companies House registered address is returned as an object with multiple fields: premises, address_line_1, address_line_2, locality, region, postal_code, country, and po_box. The problem is that different companies populate these fields differently, and there’s no guarantee of which fields will be present for any given company.
Some companies have a premises field (the building name or number) and an address_line_1 (the street). Others have no premises and put the building number in address_line_1. Others use po_box instead of a street address. Registered office service providers — accountancy firms that register companies at their address — often appear with minimal field population.
You cannot safely concatenate premises + address_line_1 + locality + postal_code and expect a coherent address for every company. You need to filter out null and empty fields, handle the case where premises is present but address_line_1 is not, and decide how you want to format the result.
The function I use filters each address field for truthiness before joining with a comma, which handles the missing-field cases cleanly.
6. Officer date of birth is intentionally obscured
The Companies House API returns director date of birth data, but not the full date. For privacy reasons, the API returns only month and year — never the day. This is by design and documented, but it’s easy to miss until you’re trying to display a DOB and find you only have two of the three components.
This also means you can’t use the API to verify a director’s exact date of birth against another source. If your KYB process requires full DOB verification, Companies House is not the source for that — you need an identity verification service.
For display purposes, month and year is enough for most use cases: “Appointed director June 2018, born March 1975” gives meaningful context without exposing a full birthdate.
7. The filing history description field requires decoding
Filing history items come back with a description field and sometimes a description_values object. The description field is a snake_case key — something like confirmation-statement-with-updates or appoint-person-director-company-with-name-date — not a human-readable string.
If you display this raw, your users see appoint-person-director-company-with-name-date rather than “Director appointed.” The description_values object sometimes contains a human-readable description field, but not always, and the format varies by filing type.
The clean solution is a mapping object that converts the common description keys to readable strings. The Companies House API reference lists the available description keys — there are around 200 of them, but the 30 most common account for the vast majority of filings. Map those and use a fallback that converts the key format (replace hyphens with spaces, capitalise first letter) for anything not in your map.
Building around the gotchas
None of these are reasons not to use the Companies House API — they’re just the kind of real-world detail that separates a working integration from one that breaks in production. Address normalisation, status checking, zero-padding, description mapping: all of these are standard parts of a properly built integration.
You can see how the data actually comes back by using the live Companies House demo tool — try a few different company types (a large PLC, a small Ltd, an LLP) and look at the variation in the data across the tabs.
If you want the integration built properly with all of this handled from the start, see the Companies House API integration service. For pricing context, the cost breakdown post explains what drives the price of a production-grade build. And if you’re deciding between building on the API or scraping the website, the API vs scraping comparison covers that in full.
Related posts
- How much does Companies House API integration cost in 2026?
- Companies House API vs scraping: which should you use?
If you need help building a Companies House API integration into your website or internal tools, I can help. I build custom API integrations for businesses across the UK, from simple company lookup tools to full automated onboarding systems. See API integration pricing or get in touch to discuss your project.
Need a custom integration built?
I build custom API integrations — Stripe, Companies House and bespoke data pipelines. Reliable, well-documented, no agency overhead.
Discuss your project →
