Help with the API

Hi,
I’m trying to use the companies house API for the first time and I’m having some issues with it. Im getting an error 400 bad request which I think means I’ve understood the documentation wrong?

header_data = Map();
header_data.put(“Authorization: Basic”,“My_API_KEY”);
Company_Number = Map();
Company_Number.put(“13931909”, “0”);
response = invokeurl
[
url : “https://api.company-information.service.gov.uk/company/Company_Number
type : GET
headers : header_data
Parameters : Company_Number
connection : “companieshouse1”
];
return response;

I’m doing this is Deluge (Zoho CRM) and would like to get this working so I can pull in data like registered address, SIC code, accounting periods etc. Any assistance is greatly appreciated

Thanks
L

1 Like

Welcome! I don’t use either Zoho CRM or the Deluge script but:

  • The 400 response suggests there is an issue with the URL you’re sending. Other responses (according to the documentation for this endpoint) could be 404 (the URL made sense but data was not found), 401 (you weren’t authorised - normally an issue with the API key OR how you set up your “application” when you registered OR how you encoded the API key. (Also rate-limiting responses possible e.g. 429)

  • looking at the documentation Google found for the invokeurl task in Deluge also suggests that how you’re specifying the parameters for that may be the issue. I don’t know if that documentation is correct but there seem to be two possible issues:

  1. The “Parameters” part appears to be for returning e.g. Form data values (in one of a couple of encodings / formats). So per your code you would appear to be sending in a string of literal value:

https://api.company-information.service.gov.uk/company/Company_Number

… as well as a body with some form values (with the “13931909” as a key …)

What Companies House is expecting is the company number to appear in the URL after the “/company/” part. You need to build that string yourself (there may be a function for this in Deluge of course). I would then remove the “Parameters” part completely - Companies House does not expect you to send a body in this API.

  1. Unless you’re not showing it in full I think your Authorization header may not be correct either. Companies House uses http basic Authorization - that requires the following string to appear in the headers:

Authorization: Basic {B64_username:password}

…where the {B64_username:password} part is the http username plus the “:” character plus a password, all base-64 encoded. In this case, per Companies House documentation, the username is your API key, there is no password.

I don’t know how you’d do this in Deluge - you will need to check exactly how it generates the required header string. There appears to be a base-64 encoding function) if as suggested you need to do this yourself. (It is just possible that the system recognises this header and does this automatically but it doesn’t look like it). I’m guessing what you need is something like:

header_data = Map();
header_data.put(“Authorization”,“Basic {My_encoded_API_KEY_plus:}”);

e.g. the “key” part in this map is likely to be just “Authorization” (or possibly “Authorization:” - depends how Deluge uses the keys to generate header strings). The “value” part is everything after the “:” - again depending on Deluge you may or may not need to provide a space at the start of this string! The brackets ("{" and “}”) and the part between them you would replace with the base64-encoded version of your API key plus the “:” character.

If not sure about this check out Companies House documentation (linked above, they have an example) and / or general documentation on http Basic and http headers.

Good luck.

APIKEY = zoho.encryption.base64Encode(“Obviously this is private so I will censor”);
info APIKEY;
header_data = Map();
header_data.put(“Authorization”,“Basic” +"{"+APIKEY + “: }”);
info header_data;
Company_Number = Map();
Company_Number.put(“13065493”, " ");
Officers = invokeurl
[
url :“https://api.company-information.service.gov.uk/company/Company_Number/Officers
type :GET
parameters:Company_Number
headers:header_data
connection:“companieshouse1”
];
return Officers;

And then I get this error " * {“Authorization”:“Basic {APIKEY:}”}

Function executed successfully

  • {“error”:“Invalid Authorization header”,“type”:“ch:service”}"

Sorry I am new to using the CH API & Deluge so it may be something really stupid

The header I am sending is * {“Authorization”:“Basic{EncodedAPIKEY: }”}

Ah - I can see that this can be confusing (and my instructions weren’t as clear as should be).

Again your example is:
a) Not getting the Authorization part right. In your code you’re now missing a space between “Basic” and the user:pass part, you don’t need the “{” or “}” AND you need to base-64 encode the “:” as that is part of the username and password!

b) Possibly not substituting in a company number into the URL

c) Possibly adding some invalid url parameters (per Deluge docs this would seem to be as I described before e.g. creating an unnecessary body part to the message).

However you’ve provided some (presumably valid) code from Deluge so I think this might work for you (I’ve no way of trying this myself…). I don’t know how a comment is delimited in Deluge so I’ve just used // followed by text.

// I have renamed your "APIKEY" to "B64USERANDPASS"
// to reflect what this actually is
B64USERANDPASS = zoho.encryption.base64Encode("Obviously this is private so I will censor" + ":");
// I have no idea what the next line does so just copying...
info B64USERANDPASS;
header_data = Map();
// The "{" and "}" in my example were not literal
// I probably should have used italics or some other way of showing this.
// You need a space between "Basic" and the actual encoded user:pass string
header_data.put("Authorization","Basic" + " " + B64USERANDPASS );
// As before - I don't think your "Company_Number" part was being substituted into your url
// ... so I have indicated this via string concatenation (don't know how variables work in Deluge)
Officers = invokeurl
[
url :"https://api.company-information.service.gov.uk/company/" + "13065493" + "/Officers"
type :GET
// There should be no parameters for Officers in your example
// (the API does allow you to add parameters *to the URL* but that's another step)
headers:header_data
connection:"companieshouse1"
];
return Officers;

That should help with both the Invalid Authorization header and the 400. Again - if you ran this using e.g. curl with “verbose” mode switched on you’d be able to see exactly what is sent and the response - I found playing around with that most helpful.