By the fastCRW team · Catalogue figures checked 2026-11-05 against GET /v1/data · Verify independently before relying on any figure.
A company registry API answers the questions that come before a deal, a payment or a sales contact: is this company real, who runs it, who owns it, and who sits above it. Three public registries answer different parts of that. Companies House covers UK companies, their officers and their persons with significant control. GLEIF indexes Legal Entity Identifiers (LEIs) worldwide and reports parent relationships. Entreprises covers French companies by SIREN. This guide shows the calls we ran on 2026-11-05, the output they returned, and the licence each registry attaches to its data.
What each registry is authoritative for
Each registry is the authority for its own jurisdiction and its own kind of record. Companies House is the authority on UK company filings, officers and control. GLEIF is the authority on LEI records, and it reports only the parent relationships that entities have declared. Entreprises is the French business directory for SIREN-registered companies. None of them is a complete picture alone, so an agent should query the one that owns the record it needs.
Companies House: search, profile, officers, control
Start with a name search. The results come back ranked by the registry's own matching, not by how well the name fits your query, so do not assume the first hit is the company you want.
curl "https://api.fastcrw.com/v1/data/companieshouse/company-search?q=monzo" \
-H "Authorization: Bearer $CRW_API_KEY"
In our run, the query monzo returned 20 items. The first four were:
BRAMAND LTD 15296432 dissolved ltd
CAPIWISE LTD 14728667 active ltd
12808379 LTD 12808379 dissolved ltd
MONZO BANK LIMITED 09446231 active ltd
MONZO BANK LIMITED is the fourth item, so filter in code by company_number or company_status rather than taking the first hit. Once you have the company number, the profile, officers and persons with significant control are one call each.
# pip install crw
from crw import CrwClient
client = CrwClient() # reads CRW_API_KEY
number = "09446231"
profile = client.get_data("companieshouse", "company", {"companyNumber": number})
officers = client.get_data("companieshouse", "officers", {"companyNumber": number})
psc = client.get_data("companieshouse", "psc", {"companyNumber": number})
print(profile["data"]["company_name"], profile["data"]["company_status"])
print(officers["data"]["total_results"], "officer records")
print(psc["data"]["items"][0]["name"], psc["data"]["items"][0]["natures_of_control"])
print(profile["provenance"]["attributionText"])
Output from that run:
MONZO BANK LIMITED active
31 officer records
Monzo Bank Holding Group Limited ['ownership-of-shares-75-to-100-percent', 'voting-rights-75-to-100-percent', 'right-to-appoint-and-remove-directors']
Contains public sector information licensed under the Open Government Licence v3.0 (Companies House)
The officer list is a register of appointments, and a person can hold several roles across several companies. The PSC record shows who holds significant control. In this run the controlling party was a corporate entity, which the record names directly. Do not read an officer list as an ownership list. Use the PSC record for control and the filings for the rest.
GLEIF: LEI record, parent, ISIN to LEI
An LEI is a 20-character identifier that a legal entity holds for its financial transactions. GLEIF publishes the index of those records. Given an ISIN, a security identifier, the by-ISIN capability finds the LEI of the issuer. This call used Apple's ISIN.
curl "https://api.fastcrw.com/v1/data/gleif/by-isin?isin=US0378331005" \
-H "Authorization: Bearer $CRW_API_KEY"
In our run the record returned LEI HWUPKR0MPOU8FGXBT394, legal name "Apple Inc.", status ACTIVE. The autocomplete capability works the other way, from a partial name to candidate records, and it is the step to use when you only have a company name. A search for monzo returned several unrelated entities as well, and "MONZO BANK LTD" (LEI 213800PLUYXGZ8LU7T61) was the fourth candidate, so the same rule applies: filter, do not take the first.
The parent relationship lives in a separate capability, direct-parent. When an entity has not reported a parent, GLEIF returns a 404. Our run of gleif/direct-parent for Apple's LEI returned 404, which means no parent was reported. That is an answer, not a failure. Code should read it as "no parent reported" and move on.
# pip install crw
from crw import CrwClient, CrwApiError
client = CrwClient() # reads CRW_API_KEY
lei = "HWUPKR0MPOU8FGXBT394" # Apple Inc., from the by-isin call
try:
client.get_data("gleif", "direct-parent", {"lei": lei})
except CrwApiError as err:
print("no parent reported" if err.status_code == 404 else f"failed: {err.error_code}")
This printed no parent reported. The REST body for the same call is {"success": false, "error": "GLEIF Global LEI Index returned 404 for this request", ..., "errorCode": "upstream_error"}. A 404 is an upstream answer, so it arrives with the same upstream_error code as a real upstream failure. Check the status before you retry.
France: SIREN search
The Entreprises provider searches the French business directory by name. A search for Airbus returned the SIREN 383474814 with the legal name AIRBUS and the administrative state A, which means active.
curl "https://api.fastcrw.com/v1/data/entreprises/search?q=airbus" \
-H "Authorization: Bearer $CRW_API_KEY"
The results carry the SIREN, the legal name, the creation and closure dates where they apply, and the officers list under dirigeants. Use the SIREN as the join key for French records. Do not treat a name match alone as the same company.
Joining the three registries
No registry gives you a key that the other two accept. A UK company number, an LEI and a French SIREN identify different things, so joins are done by matching. The one useful bridge is the LEI record itself: it carries the number the entity is registered under and the code of the registration authority that issued it.
# pip install crw
from crw import CrwClient
client = CrwClient() # reads CRW_API_KEY
rec = client.get_data("gleif", "lei-record", {"lei": "213800PLUYXGZ8LU7T61"})
entity = rec["data"]["data"]["attributes"]["entity"]
print(entity["legalName"]["name"], entity["jurisdiction"])
print(entity["registeredAt"]["id"], entity["registeredAs"])
MONZO BANK LTD GB
RA000592 730427
The registration number here is 730427, not the Companies House number 09446231 from the earlier search. The record names a different registration authority, so the two cannot be compared directly. Read registeredAt before you treat registeredAs as a company number. When the numbers do not line up, fall back to name, country and registered address together, and keep low-confidence matches flagged instead of merging them silently. Two registries listing the same name is not proof of the same legal entity.
For the full pattern of resolving an entity and citing each fact, see lead enrichment with fastCRW.
Commercial use
Each registry's licence is attached to its response. Quote the line that came back, and check it against the registry's own terms before you build a product on the data.
- Companies House, from its catalogue row: "Crown copyright, published under the Open Government Licence v3.0." The row adds that the register data "may be used and re-used free of charge, including commercially, provided the source is acknowledged."
- GLEIF, from its catalogue row: the Access Service "is provided for free" and its data is "under the CC0 licence". The row also sets conditions of use, so read it in full.
- Entreprises, from its catalogue row: "Licence Ouverte / Open Licence 2.0 (Etalab). Free reuse including commercial, with attribution."
These lines describe what each publisher allows. They are not legal advice, and registries can change their terms. Check the source before you ship.
The order of calls for one company
A due-diligence or KYB check usually runs the same sequence. Keep each step's output, because the final record should show which registry said what.
- Search the registry that matches the company's country, and filter the hits by company number or status.
- Pull the profile, then the officers and the persons with significant control for the UK.
- Look up the LEI by name or by ISIN through GLEIF, then check
direct-parent. Treat a 404 as "no parent reported". - For a French company, search Entreprises and read the officers under
dirigeants. - Write the result with one source line per fact, and list the registries that returned nothing.
The order matters less than the record of it. An agent that cannot show which registry produced a claim should not state that claim.
Honest limits
- Coverage differs by country. A company outside the UK or France needs a different registry, and the catalogue lists which ones are present.
- Upstream registries are sometimes slow or unavailable. A failed call is not billed, and the error code tells you whether to retry.
- A 404 from a registry usually means no record exists for that query. It is not proof that the entity is absent elsewhere. For example,
companieshouse/insolvencyfor Monzo's company number returned 404 because no insolvency record exists. - US companies are not covered by these three. The SEC's company tickers list is the starting point there. The FCA Financial Services Register runs on your own machine with your own key, so it needs the local install and is not part of the hosted calls above.
Cost
Find and catalogue calls are free. Each call to a server source costs its creditsCost, usually 1 credit, and a failed call is not billed. Plan prices are on the pricing page.
Sources
- Data sources reference
- Companies House API documentation
- GLEIF API documentation
- Recherche d'entreprises API documentation
Start with the Companies House page and its capability list.
Related: Public data API for AI agents · Build a finance research agent · Pergamon catalogue
