Getting invalid authorization

Hello,

I’ve been trying to get started with the new API, with little luck so far. I am trying initially to run a company search as described here: https://developer.companieshouse.gov.uk/api/docs/search/companies/companysearch.html

It says that no authentication is required, yet when I try leave the ‘Authorise with API key’ at ‘None’ and click the ‘Try it out’ button, I get an error:

“Failure while contacting API. Some possible causes are connection problems or cross-origin resource sharing protection. Please check javascript domains registered against APIKey / OAuth2 registration.”

I have tried to create an ‘Application’ but have obviously got some mistakes in the set up for that as it fails with the same error.
Any help would be appreciated.
Thanks,
Chris

Update:
I’ve created a new ‘Application’ and entered the IP address of my PC (which I guess changes each time I log in). I’ve left the Javascript Domain blank and I can now do searches using ‘Explore this API’ from your website.
My next step will be to write a program which will use a new ‘Application’ where I can set the IP address to that of the server I use and the Javascript Domain to the URL of the Oracle Apex page that I’m running the code from (??).

Regards,
Chris

2nd Update,
I’ve started writing some Oracle code and I’m now getting an Oracle error ‘Certificate validation failure’. You get this when accessing via SSL and need to create an Oracle Wallet to get around it. Since we’re developing on a shared server this may prove difficult.Is there a non-SSL, straight http webservice available? (I tried it without the ‘s’ and it just timed out).

Regards,
Chris

We are currently working on more detailed authentication documentation.

Providing an IP address in your API registration locks that API key to a single client (the one presenting that IP address). This is not generally necessary if the client is internal to an organisation and not public, as you have physical security protecting the API key. This of course could be multiple physical clients if they are hiding behind a firewall or proxy providing NAT.

It is necessary to provide a Javascript Domain if you are sending requests from a Javascript client that is W3C compliant (which most browsers in use these days are). A compliant JS client will refuse to process the result of a request unless it receives an Access-Control-Allow-Origin header that matches the Origin header that it sent in the request. The Companies House API will only return an Access-Control-Allow-Origin header if the received Origin header value matches one of the Javascript domains registered against the API key that was used.

1 Like

The Companies House API will only be available over a secure connection. We recommend TLS 1.2, and may not support earlier protocols in the future.

Authentication information is submitted as part of the request, the API key for example, and therefore a secure connection is essential.

Can you please provide step-by-step guide and example code (PHP/PERL) showing the authentication process?

Why do you need this extra complication when the previous API was so straightforward?

Thanks

1 Like

The existing XML Gateway API employs a custom authentication mechanism unique to Companies House, and involves the complex MD5 hashing of passwords and transaction ID’s.

The new Companies House REST API uses standard [Basic HTTP Authorisation][1]. This makes API key authentication as simple as the following curl command:

curl -v -uYOUR_APIKEY_FOLLOWED_BY_A_COLON: https://api.companiseshouse.gov.uk/company/00002065

You may have to do a little more work in code, depending on whether your client framework directly supports basic authorisation, which is highly likely, but if not, it simply comes down to setting the HTTP Authorization: header with content Basic followed by the base64 encoding of YOUR_APIKEY_FOLLOWED_BY_A_COLON:

If your API key really was YOUR_APIKEY_FOLLOWED_BY_A_COLON, then the Authorization header would be:

Authorization: Basic WU9VUl9BUElLRVlfRk9MTE9XRURfQllfQV9DT0xPTjo=
```

Cut-n-paste this base64 string to this [online base64 decoder][2] to see the content. Note the colon at the end of the API key, this is the delimiter between the username and the password and **must** be present, even if there is no password. A common error is to omit it.

Here is a quick bit of Perl which demonstrates making an API request using Basic Authorisation. I've spelt everything out, so you can see exactly how you form an `Authorization` header if you find you have to do it yourself:

```perl
    #!/usr/bin/perl
    
    use strict;
    use LWP::UserAgent;
    use JSON;
    use Data::Dumper;
    use MIME::Base64;
    
    my $APIKEY   = 'PUT_YOUR_API_KEY_HERE';
    my $resource = 'https://api.companieshouse.gov.uk/company/00002065';
    
    # Create a standard HTTP Basic authentication
    # This consists of a username:password pair, but with a blank password
    my $credentials = 'Basic '. encode_base64( $APIKEY.':' );
    
    # Create a user agent and submit the request with an Authorization header.
    my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } );
    my $response = $ua->get( $resource, 'Authorization' => $credentials );
    
    die 'Error. Http status: '.$response->code.' '.$response->message unless $response->is_success;
    
    # Decode JSON (use decode_json, as it handles UTF-8)
    my $response_data = decode_json( $response->content );
    
    # Dump out the parsed resource so you can see it.
    print Dumper $response_data;
```

I hope that explains the authentication mechanism for you. If you were after anything else, let us know.


  [1]: https://en.wikipedia.org/wiki/Basic_access_authentication
  [2]: https://www.base64decode.org/

I am getting 401 Unauthorized no matter what I try. I have the API Key established since 6-22-2015 and it will not work at all. This PERL script is giving me the same problem also. However the API Key under my account is showing as active. Does anyone know how long it takes to provision a new key? Is there a chance it hasn’t synced up yet?

The API key is provisioned immediately and they are available for use. You could validate using the “Try It Out” functionality within the developer hub.

If you go to the following page and log in you can then test the API keys you have registered by adding a company number and clicking “try it out” button.

Let me know if this works or fails and then we can try and work out what the issue is

Hi,

Is it possible to run a straightforward URL in a browser to test the API, for example the following works for a Bank REST webservice over SSL:

https://www.unifiedsoftware.co.uk/services/bankvaluk/bankvalplus2/userid/MYUSERID/pin/MYPIN/sortcode/SEARCHSORTCODE/account/SEARCHACCNTNUM/xml .

where MYUSER and MYPIN represent my username and password for that webservice and SEARCHSORTCODE and SEARCHACCNTNUM are the search parameters.

I would guess that I would have to take my APIKEY, add a colon and put that through the base64 encoder. I could then use it in a URL something like:

https://api.companieshouse.gov.uk/search/companies?name=tesco&apiKey=MYBASE64APIKEYPLUS:

If I could get something like this working I could then start wrestling with Oracle wallets (or to be more exact ask a DBA to do that for me).

Thanks,
Chris

1 Like

Depending on the client, you should be able to do the following to get the company profile information back (one of the reasons we used standard HTTP authentication):

https://YOURAPIKEY:@api.companieshouse.gov.uk/company/00002065

However, trying this in my browser I don’t see the credentials being sent as an authentication header, so this is not going to help you. This should work, so we will have to investigate why the browser is not sending them.

Note, for the record, it is always a bad idea to put authentication credentials in a URL - these often get logged and leak your credentials. The HTTP authentication gets transported in the header, so is much safer, though if using the above representation, there is still a risk that the client logs the initial full URL.

Hi,

I was trying this test this using Chrome Advanced Rest Client but getting 401 unauthorised response.

URL-https://api.companieshouse.gov.uk/company/04274912
GET /company/04274912 HTTP/1.1
HOST: api.companieshouse.gov.uk
authorization: Basic api key

Thanks
Pradeep

@p_sadasivan

Have you base 64 encoded your API key, with a colon on the end before encoding?

Thanks,

Mark.

Hi,

I’m trying to call with no success

GET /company/04731304 HTTP/1.1
Host: api.companieshouse.gov.uk
Authorization: (base 64 apikey)

I tried in the authorization

  • Bearer APIKEY
  • Bearer (base64 apikey)
  • Bearer (base64 apikey+:)
  • APIKEY
  • (base64 apikey)
  • (base64 apikey+:)

It worked the first 10 requests then, it stopped working.

Regards,
Sandro Maio

@sandro,

To confirm, if the client you are using does not perform the base64 encoding then you will need to take your api key, append a colon and then base64 encode. NOT base64 encode the api key and then add a colon. The header should be

Authorization: Basic <>

Thanks

@mfairhurst

Works perfectly.

Many thanks

@mfairhurst

Sorry to bother you on this old post but I am trying to pull info from the api to info path but am returning an error message saying my username or password is incorrect. I am encoding my api as instructed (with the colon pre-encode) and leaving the password blank, but no luck.

Only thing I have noticed is that my credits remaining = 0. could this be the issue? if so, why are my credits 0, where can I get more!

Thank for your help.

Tom

@t_roberts

Apologies but I’m not sure what you mean by credits remaining = 0? Is there any way you could provide some code snippets so we can assist further.

Thanks

@mfairhurst

Hello,
@mfairhurst I am trying to access the data using python and even after providing the API key I am getting 401 (Unauthorised error)
Could you please help me out with this
Here is how i am trying to access it

import requests
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()

url = “https://api.companieshouse.gov.uk/search/companies
headers={‘x-api-key’: ‘my key’}

print(url)
print(headers)

resp = requests.get(url,headers=headers)
print (resp.status_code)

@kruti1206

The simplest way to resolve is the use the authentication functionality built into the requests package. If you change the code to as follows the authorisation error should be resolved.

import requests
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()

url = "https://api.companieshouse.gov.uk/search/companies"

print(url)

resp = requests.get(url, auth=('api-key', ''))
print (resp.status_code)

Thanks

@mfairhurst

2 Likes