Client API#
The :mod:`ch_api.api` module provides the main :class:`~ch_api.api.Client` class for interacting with the Companies House API.
Async Companies House API client.
Provides direct access to the Companies House public data API with authentication, rate limiting, and automatic pagination support.
Example
Basic usage:
>>> from ch_api import Client, api_settings
>>> @run_async_func
... async def basic_example(client):
... company = await client.get_company_profile("09370755")
... return True
- class ch_api.api.Client(credentials: AuthSettings | AsyncClient, settings: ApiSettings = ApiSettings(api_url='https://api.company-information.service.gov.uk', identity_url='https://identity.company-information.service.gov.uk', test_data_generator_url=None), api_limiter: Callable[[], AsyncContextManager[None, bool | None]] | None = None)[source]#
Bases:
objectAsync client for the Companies House API.
This client provides direct access to the Companies House API endpoints with minimal abstraction and data validation. It handles all HTTP communication, authentication, and automatic pagination for list endpoints.
The Companies House API returns live, real-time data about UK companies, including profiles, officers, charges, filing history, and persons with significant control (PSCs).
Example
Create a client and fetch company information:
>>> from ch_api import Client, api_settings >>> @run_async_func ... async def client_example(client): ... # Fetch a company's profile ... profile = await client.get_company_profile("09370755") ... print(f"{profile.company_name} - Status: {profile.company_status}") ... # Fetch company officers ... officers = await client.get_officer_list("09370755") ... async for officer in officers: ... print(f"Officer: {officer.name}") ... # Search for companies ... results = await client.search_companies("Apple") ... async for result in results: ... print(f"Found: {result.title} ({result.company_number})") ... ...
Note
All methods are asynchronous and must be called with
await. This client is designed for rate-limited access to the Companies House API.See also
:mod:`ch_api.api_settings`: Configuration and authentication settings
:mod:`ch_api.types`: Pydantic models for API responses
- __init__(credentials: AuthSettings | AsyncClient, settings: ApiSettings = ApiSettings(api_url='https://api.company-information.service.gov.uk', identity_url='https://identity.company-information.service.gov.uk', test_data_generator_url=None), api_limiter: Callable[[], AsyncContextManager[None, bool | None]] | None = None) None[source]#
Initialize the Companies House API client.
- Parameters:
credentials (Union[AuthSettings, httpx.AsyncClient]) –
Authentication credentials for the API. Can be either:
An :class:`~ch_api.api_settings.AuthSettings` instance containing an API key
A pre-configured :class:`httpx.AsyncClient` with authentication headers already set
settings (api_settings.ApiSettings, optional) – API endpoint configuration. Defaults to :data:`~ch_api.api_settings.LIVE_API_SETTINGS`. Use :data:`~ch_api.api_settings.TEST_API_SETTINGS` for the sandbox environment.
api_limiter (Callable, optional) –
An optional async context manager callable that acts as a rate limiter for API calls. If provided, the limiter is called for each API request to control request velocity.
The limiter should be a callable that returns an async context manager:
async def my_limiter(): # Control request rate here async with some_rate_limiter: yield
A good option is asyncio-throttle for implementing token bucket rate limiting.
If
None(default), no rate limiting is applied.
- Raises:
ValueError – If
credentialsis neither anAuthSettingsinstance nor anhttpx.AsyncClient.
Example
Create a client with API key authentication:
from ch_api import Client, api_settings auth = api_settings.AuthSettings(api_key="your-api-key") client = Client(credentials=auth)
Create a client with a custom rate limiter:
import asyncio_throttle from ch_api import Client, api_settings auth = api_settings.AuthSettings(api_key="your-api-key") limiter = asyncio_throttle.AsyncThrottle(max_rate=2, time_period=1.0) # Limiter expects a callable returning an async context manager def rate_limiter(): return limiter client = Client(credentials=auth, api_limiter=rate_limiter)
Use as async context manager for automatic cleanup:
async with Client(credentials=auth) as client: company = await client.get_company_profile("09370755")
See also
ch_api.api_settings.AuthSettingsAPI key credential container
ch_api.api_settings.LIVE_API_SETTINGSProduction API settings
ch_api.api_settings.TEST_API_SETTINGSSandbox API settings
- async aclose() None[source]#
Close the HTTP session if owned by this client.
This method should be called when you’re done with the client to properly clean up network resources. If the client was initialized with an AuthSettings object (meaning it created its own session), this will close the underlying HTTP session. If initialized with an external AsyncClient, the session is not closed as it’s assumed to be managed externally.
Example
Manual cleanup:
>>> @run_async_func ... async def manual_cleanup(client): ... c = Client(credentials=client._api_session) ... try: ... company = await c.get_company_profile("09370755") ... finally: ... await c.aclose()
Or use as context manager for automatic cleanup:
>>> @run_async_func ... async def context_cleanup(client): ... async with client: ... company = await client.get_company_profile("09370755")
- async create_test_company(company: CreateTestCompanyRequest) CreateTestCompanyResponse | None[source]#
Create a test company using the Test Data Generator API.
- Parameters:
company (CreateTestCompanyRequest) – The request data for creating the test company.
- Returns:
The response data containing details of the created test company.
- Return type:
- async get_company_profile(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) CompanyProfile | None[source]#
Fetch the company profile for a given company.
- Parameters:
company_number (str) – The company number to fetch the profile for.
- Returns:
The company profile data.
- Return type:
types.public_data.company_profile.CompanyProfile
- async registered_office_address(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) RegisteredOfficeAddress | None[source]#
Fetch the registered office address for a given company.
- Parameters:
company_number (str) – The company number to fetch the registered office address for.
- Returns:
The registered office address data for the company.
- Return type:
types.public_data.registered_office.RegisteredOfficeAddress
- async get_officer_list(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], only_type: ~typing.Literal['directors', 'secretaries', 'llp-members'] | None = None, order_by: ~typing.Literal['appointed_on', 'resigned_on', 'surname'] = 'appointed_on') MultipageList[OfficerSummary][source]#
Fetch the list of company officers for a given company.
- Parameters:
company_number (str) – The company number to fetch the officers for.
- Returns:
The list of company officers.
- Return type:
types.pagination.async_list.MultipageList[types.public_data.company_officers.OfficerSummary]
- async get_officer_appointment(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], appointment_id: str) OfficerSummary | None[source]#
- async get_company_registers(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) CompanyRegister | None[source]#
- async search(query: str) MultipageList[Annotated[CompanySearchItem | OfficerSearchItem | DisqualifiedOfficerSearchItem, FieldInfo(annotation=NoneType, required=True, discriminator='kind')]][source]#
Search for companies using the Companies House search API.
- Parameters:
query (str) – The search query string.
- async advanced_company_search(company_name_includes: str | None = None, company_name_excludes: str | None = None, company_status: Sequence[str] | str | None = None, company_type: Sequence[str] | str | None = None, company_subtype: Sequence[str] | str | None = None, dissolved_from: date | None = None, dissolved_to: date | None = None, incorporated_from: date | None = None, incorporated_to: date | None = None, location: str | None = None, sic_codes: Sequence[str] | None = None, max_results: Annotated[int, Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=5000), None]] = 100) AdvancedSearchResult[CompanySearchItem][source]#
Perform an advanced search for companies using the Companies House search API.
- async alphabetical_companies_search(query: str, page_size: Annotated[int, Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 10) TopHitList[AlphabeticalCompanySearchResult[AlphabeticalCompany], AlphabeticalCompany][source]#
- async search_dissolved_companies(query: str, page_size: Annotated[int, Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 10, type: Literal['alphabetical', 'best-match', 'previous-name-dissolved'] = 'alphabetical') TopHitList[AlphabeticalCompanySearchResult[DissolvedCompany], DissolvedCompany][source]#
Search for dissolved companies using the Companies House search API.
- Parameters:
query (str) – The search query string.
- async search_companies(query: str) MultipageList[CompanySearchItem][source]#
Search for companies using the Companies House search API.
- Parameters:
query (str) – The search query string.
- async search_officers(query: str) MultipageList[OfficerSearchItem][source]#
Search for officers using the Companies House search API.
- Parameters:
query (str) – The search query string.
- async search_disqualified_officers(query: str) MultipageList[DisqualifiedOfficerSearchItem][source]#
Search for disqualified officers using the Companies House search API.
- Parameters:
query (str) – The search query string.
- async get_company_charges(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) ChargeList | None[source]#
Fetch all charges for a given company.
- Parameters:
company_number (str) – The company number to fetch the charges for.
- Returns:
The list of charges for the company.
- Return type:
types.public_data.charges.ChargeList
- async get_company_charge_details(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], charge_id: str) ChargeDetails | None[source]#
Fetch all charges for a given company.
- Parameters:
company_number (str) – The company number to fetch the charges for.
charge_id (str) – The charge ID to fetch details for.
- Returns:
The details of the charge for the company.
- Return type:
types.public_data.charges.ChargeDetails
- async get_company_filing_history(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], categories: ~typing.Tuple[~typing.Literal['accounts', 'address', 'annual-return', 'capital', 'change-of-name', 'incorporation', 'liquidation', 'miscellaneous', 'mortgage', 'officers', 'resolution'], ...] | None = None, page_size: ~typing.Annotated[int, typing.Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 25) MultipageList[FilingHistoryItem][source]#
Fetch the filing history for a given company.
- Parameters:
company_number (str) – The company number to fetch the filing history for.
- Returns:
The filing history data.
- Return type:
types.public_data.filing_history.FilingHistoryList
- async get_filing_history_item(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], filing_history_id: str) FilingHistoryItem | None[source]#
Fetch a specific filing history item for a given company.
- Parameters:
company_number (str) – The company number to fetch the filing history item for.
filing_history_id (str) – The filing history ID to fetch.
- Returns:
The filing history item data.
- Return type:
types.public_data.filing_history.FilingHistoryItem
- async get_company_insolvency(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) CompanyInsolvency | None[source]#
Fetch insolvency information for a given company.
- Parameters:
company_number (str) – The company number to fetch insolvency information for.
- Returns:
The company insolvency data.
- Return type:
types.public_data.insolvency.CompanyInsolvency
- async get_company_exemptions(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) CompanyExemptions | None[source]#
Fetch exemptions information for a given company.
- Parameters:
company_number (str) – The company number to fetch exemptions for.
- Returns:
The exemptions data.
- Return type:
types.public_data.exemptions.CompanyExemptions
- async get_corporate_officer_disqualification(officer_id: Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) CorporateDisqualification | None[source]#
Fetch the corporate officer disqualification for a given officer.
- Parameters:
officer_id (str) – The officer ID to fetch the disqualification for.
- Returns:
The corporate officer disqualification data.
- Return type:
types.public_data.disqualifications.CorporateDisqualification
- async get_natural_officer_disqualification(officer_id: Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) NaturalDisqualification | None[source]#
Fetch the natural officer disqualification for a given officer.
- Parameters:
officer_id (str) – The officer ID to fetch the disqualification for.
- Returns:
The natural officer disqualification data.
- Return type:
types.public_data.disqualifications.NaturalDisqualification
- async get_officer_appointments(officer_id: Annotated[str, StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)], filter: Literal['active'] | None = None, page_size: Annotated[int, Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 25) OfficerAppointments[source]#
Fetch the officer appointments for a given officer.
- Parameters:
officer_id (str) – The officer ID to fetch the appointments for.
- Returns:
The officer appointments data.
- Return type:
types.compound_api_types.OfficerAppointments
- async get_company_uk_establishments(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)]) CompanyUKEstablishments | None[source]#
Fetch the UK establishments for a given company.
- Parameters:
company_number (str) – The company number to fetch the UK establishments for.
- Returns:
The UK establishments data.
- Return type:
types.public_data.uk_establishments.CompanyUKEstablishments
- async get_company_psc_list(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], register_view: bool = False, page_size: ~typing.Annotated[int, typing.Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 25) OfficerAppointments[source]#
- register_view - Display register specific information. If register is held at Companies House and
register_view is set to true, only PSCs which are active or were terminated during election period are shown.
- async get_company_psc_statements(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], register_view: bool = False, page_size: ~typing.Annotated[int, typing.Annotated[int, None, Interval(gt=None, ge=1, lt=None, le=100), None]] = 25) StatementList[source]#
- register_view - Display register specific information. If register is held at Companies House and
register_view is set to true, only PSCs which are active or were terminated during election period are shown.
- async get_company_corporate_psc(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) CorporateEntity | None[source]#
- async get_company_corporate_psc_beneficial_owner(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) CorporateEntityBeneficialOwner | None[source]#
- async get_company_individual_psc_beneficial_owner(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) IndividualBeneficialOwner | None[source]#
- async get_company_individual_psc(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) Individual | None[source]#
- async get_company_legal_person_psc_beneficial_owner(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) LegalPersonBeneficialOwner | None[source]#
- async get_company_legal_person_psc(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) LegalPerson | None[source]#
- async get_company_super_secure_psc(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) SuperSecure | None[source]#
- async get_company_super_secure_beneficial_owner_psc(company_number: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=^[A-Za-z0-9]{1,8}$)], psc_id: ~typing.Annotated[str, ~pydantic.types.StringConstraints(strip_whitespace=None, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None)]) SuperSecureBeneficialOwner | None[source]#