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: object

Async 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).

API Documentation:

https://developer-specs.company-information.service.gov.uk/guides/gettingStarted

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

__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:
Raises:

ValueError – If credentials is neither an AuthSettings instance nor an httpx.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.AuthSettings

API key credential container

ch_api.api_settings.LIVE_API_SETTINGS

Production API settings

ch_api.api_settings.TEST_API_SETTINGS

Sandbox 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:

CreateTestCompanyResponse

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.

Perform an advanced search for companies using the Companies House search API.

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_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]#