Need help to access the Company API

We are trying to use the below API code to get the result of the company list but didn’t get anything. Could you please suggest us the correct way and let us know what wrong we are doing to get this?


try {
$input = $request->all();

        $data = json_encode(array(
            "grant_type" => "authorization_code",
            "client_id"  => "XXX",
            "client_secret" => "YYY"
        ));
        $header = [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data)
        ];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://identity.company-information.service.gov.uk/oauth2/token');
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLINFO_HEADER_OUT, true);
        //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        // EXECUTE:
        $result = curl_exec($curl);
        $info = curl_getinfo($curl);
        dd($info);
        if (!$result) {
            dd("Connection Failure");                
        }
        curl_close($curl);

        $result = json_decode($result);
        dd($result);
    } catch (\Exception $ex) {
        return Helper::rj($ex->getMessage(), 500);
    }

There are 2 different kinds of authentication in use in Companies House APIs:

  1. http basic
  2. OAuth

Your code is part of process 2 above. However this is only used to access some of the APIs. If you want to look up company information (e.g. via the Public Data API or Streaming API) then you need to use http basic authentication with your API key, not OAuth with e.g. client id and secret.

You say you want to “get the result of the company list” - I presume that’s to do a search or get a company profile? If so then yes, you need to use http basic authentication.

See the documentation on authentication here.

https://developer.company-information.service.gov.uk/authentication

Then try searching this forum - there are many answers to questions about this!

Thanks for your reply. But still, I am facing problems.

First of all, please find the attached screenshot once, and then I have executed the below CURL code for getting company stream information, but always get the 500 error.
​---------------------------------
Invalid Authorization header

^ {#1441
+“error”: “Invalid Authorization header”
+“type”: “ch:service”
}
​---------------------------------

​Here is the CURL code:-​
​===============​===

try {
$input = $request->all();

        $headers = [
            'Authorization: Basic 07e711f6-bd5f-420e-82ea-68e2f7eafee8'
        ];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, 'https://stream.companieshouse.gov.uk/companies');
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        // EXECUTE:
        $result = curl_exec($curl);
        $info = curl_getinfo($curl);
        //dd($info);
        if (!$result) {
            dd("Connection Failure");                
        }
        curl_close($curl);

        $result = json_decode($result);
        dd($result);
    } catch (\Exception $ex) {
        return Helper::rj($ex->getMessage(), 500);
    }

​===============​===
Please check and let me know what I am doing wrong.

In your PHP curl code it looks like you’re choosing to supply a header. If you do so you will have to follow the http Basic Authorization format which it doesn’t look like you do in your example.
You can save effort by getting the PHP curl library to do this for you:

// The format below requires username:password
// Companies House provide a username (API key) and no password
// … so the password is and empty string:
$userpwd = “YOUR_API_KEY_GOES_HERE” . “:”;
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPW, $userpwd);

… and don’t use:

curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

See eg.
https://www.php.net/manual/en/function.curl-setopt.php

You can also just pass all options as an array using the curl_setopt_array function.

Are you sure you want to use the streaming API and not the Public Data API? For the streaming API I think you need to keep consuming the data. So you’d normally ensure you had a loop with a long-running http connection, and you might also start that by passing a timepoint in.

https://developer-specs.company-information.service.gov.uk/streaming-api/guides/overview

Thank you @voracityemail for your reply. Now we have used the Rest API key for Basic Authorization and then we have got a response from the API end but we are getting the empty array under the items. Below is the curl code and then I have posted the response:-

Please check the attached screenshot file for your reference.

$input = $request->all();

        $headers = [
            'Content-Type: application/x.companieshouse.company-profile+json; version=1.1',
            'Accept: application/json'
        ];
        $userpwd = "a9d8d78a-694f-4123-ad29-f17836037304" . ":";
       
        $url = 'https://api-sandbox.company-information.service.gov.uk/search/companies';
        $url = sprintf("%s?%s", $url, http_build_query($input));
       
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");                    
        curl_setopt($curl, CURLOPT_URL, $url);
        //curl_setopt($curl, CURLOPT_HEADER, 0);
        //curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($curl, CURLOPT_USERPWD, $userpwd);
        // EXECUTE:
        $result = curl_exec($curl);

        if (!$result) {
            dd("Connection Failure");                
        }
        curl_close($curl);

This is the response we have received:-

{
“kind”: “search#companies”,
“items_per_page”: 10,
“page_number”: 1,
“total_results”: 0,
“items”: [],
“start_index”: 0
}

Good, you’ve got authorization working it would seem.

I would always start with the simplest case. I don’t know exactly what is in your $input. It might be best to specify the url completely first if something isn’t working e.g.

$url = 'https://api-sandbox.company-information.service.gov.uk/search/companies?q=greggs';

Before you even do that though I would try the following:

a) Just use the live environment not the test / sandbox environment for a search. I think people have had some issues with the test system. It may be that only certain test data is available there e.g. a general search may not work - I do not know.

b) I would use curl on the command line for speed until you’re sure you can get a result which “works”.

However I have just tried the following on the live system and this works:

curl -u THE_API_KEY_GOES_HERE: "https://api.company-information.service.gov.uk/search/companies?q=greggs"

That returns a set of tens of results.

After that try adding other parameters e.g.

curl -u THE_API_KEY_GOES_HERE: "https://api.company-information.service.gov.uk/search/companies?q=greggs&items_per_page=3"
curl -u THE_API_KEY_GOES_HERE: "https://api.company-information.service.gov.uk/search/companies?q=greggs&items_per_page=3&start_index=3"

If you have problems after this (e.g. if you get invalid authorisation / 401 etc.) you may need to check where your PHP code / the curl command is running from (your server). If you’re running on a localhost then search this forum for how to make that work. Either way you may need to ensure that your server’s IP address is listed in the “restricted IPs” in the Companies House console.

I don’t think you necessarily need either the Content-Type or the Accept headers - not to start with and for the Search endpoint. The only place I can think of where you definitely need the Accept header is the Documents API where that allows you to select which type of document you want to download, if there are multiple types.

@voracityemail Thanks for your help. We are getting data now after changing to the live environment. But still, I have a few queries, Is it possible to fetch all records at the same time with respect to search parameters? Currently, records are showing with the pagination but we need to display all records as per the user searches for anything in the search box and show all related company names in the dropdown.

See here for pagination.

See documents on advanced search - using this may allow you to obtain more records in one call:
https://developer-specs.company-information.service.gov.uk/companies-house-public-data-api/reference/search/advanced-company-search

If you want to display results in a dropdown control for searches I suspect you won’t want to show all the results anyway. Depending on search terms you might end up with a list so large a dropdown becomes unusable / unhelpful as an interface.

@voracityemail Thanks for your support. Finally, we got our expected data by using the advanced search API. But we need some more information from the response about the company like Company Registration Number, Company Phone and Company Email. Can you please help us again how we can get this required information? Below is the sample response we are getting currently:-

“company_name”: “JENNIFER GREGGS LIMITED”,
“company_number”: “11521185”,
“company_status”: “dissolved”,
“company_type”: “ltd”,
“kind”: “search-results#company”,
“links”: {
“company_profile”: “/company/11521185”
},
“date_of_cessation”: “2020-10-06”,
“date_of_creation”: “2018-08-16”,
“registered_office_address”: {
“address_line_1”: “36 Norman Road”,
“address_line_2”: “Northfield”,
“locality”: “Birmingham”,
“postal_code”: “B31 2EW”,
“country”: “England”
},
“sic_codes”: [
“73200”
]

company_number is the Company Registration Number

Phone and Email aren’t required to form a company and as such are not recorded at Companies House. It would be a nightmare if it was because everyone would just use this data for spam and direct marketing.

When you say “Registration Number” what do you mean? The main “number” or “code” for the company is the company number - which you can see in your example data. If you mean the VAT number Companies House doesn’t have that:

Companies House does not register an email or phone number for companies - see e.g. this thread:

Okay thanks, @voracityemail & @ash, for now, we are using company_number as Company Registration Number, and also I understand the rest of the comments. Thanks again.

@voracityemail @ash We need one urgent help. Please check below:-

We are currently using API like “https://api.company-information.service.gov.uk/advanced-search/companies?company_name_includes=google”. As the response we are getting for all company’s data which matches with any position of the character/word like start, middle, or any place in the company name data. But now we want to get only company data that exactly match our search query with starting letter of the company name. For example: Please check the attached screenshot.

I don’t know of any endpoint which ONLY gives you a single exact match or nothing. (Except if you have the company number but that’s not a search though.
I don’t know how the alphabetic search works though - just possibly that would?

So you could try using the “Companies Search” endpoint of the API.

If you get back zero results (an empty items array) your name doesn’t match. If you get back results you need to check the first one - or perhaps first few - to see if the name (title member) matches your text.

For the matching part you could either:

a) Try being lucky - assume an exact match will be the first result returned - and just check the name against what you have. Alternatively check several.

b) Make the search more specific with the new restrictions parameter. For example you could use the legally-equivalent-company-name value - this will only match on “legally equivalent names” as it says (e.g. so “ltd” in you search will match e.g “ltd.”, “limited” etc. So it won’t guarantee that it only matches EXACTLY what you’ve supplied. However this will greatly limit the numbers of responses that do match so an “exact” match should be the first one (if it exists). Again you will need to check your text against the returned title field.
You can add other restrictions here also e.g. active-companies for only active ones.

You can specify a small items_per_page value e.g. 2 or 3 to save retrieving data you won’t use. (There was and there may still be a bug if items_per_page is 1 - check this carefully).

Let’s try an example. I’m using curl here. That means that as we’re passing parameters in the url text values like space will need urlencoding - hence the “%20” etc.
Here’s a totally non-existent name, doesn’t match anything at all. Nothing found here:

curl -u YOURAPIKEY: “https://api.company-information.service.gov.uk/search/companies?q=abzxysfe&items_per_page=2&start_index=1

Response - http 200.

{
    "kind": "search#companies",
    "page_number": 1,
    "items_per_page": 3,
    "total_results": 0,
    "items": [ ],
    "start_index": 0
}

Items is empty - no results found.

Example 2 - a “standard” search for “AB CAPITAL LTD”:
curl -u YOURAPIKEY: “https://api.company-information.service.gov.uk/search/companies?q=ab%20capital%20ltd&items_per_page=3&start_index=1

(I’ve skipped the JSON here but it returns various companies matching the name and variations of it - the total_results is quite large, obviously it only returns the number of those given by items_per_page).

  1. Adding a restriction to this to make it more specific:
    curl -u YOURAPIKEY: “https://api.companyinformation.service.gov.uk/search/companies?q=ab&items_per_page=3&start_index=1&restrictions=legally-equivalent-company-name

(I’ve skipped some values below for clarity):

{
    "start_index": 0,
    "items_per_page": 3,
    "total_results": 4,
    "items": [
        {
            ...
            "company_number": "11325602",
            "title": "AB CAPITAL LTD",
        }
    ],
    ...
}
  1. If you add the active-companies restriction you only get one for this particular example:

curl -u YOURAPIKEY: “https://api.company-information.service.gov.uk/search/companies?q=ab&items_per_page=3&start_index=1&restrictions=active-companies%20legally-equivalent-company-name

Hope this helps.

@voracityemail okay I understand, thank you.