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 (??).
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).
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.
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:
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
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):
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.
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
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!
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
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.