Axios Get Request in NodeJS Application Returning 401 Error

Hi there,

I’ve read everything I can about this issue on these forums and on Stack Exchange, however, I cannot see where I am going wrong, or why my key isn’t being accepted.

I am desperate for help and feel like I’m just majorly overlooking something here

My goal is to visit localhost:3000/api/hello and have this send an axios.get request to the public data API’s ‘search all’ section using the q param “Just” while having my Rest API Key in the header for authorisation.
I have done the hosts file local host workaround mentioned here like so:
127.0.0.1 application.com

And have ensured “http://application.com” is in the Javascript Domains section of my key

I have attempted to do this in 3 different ways now.

  1. Setting global axios auth & content-type headers for all requests and sending just params via axios.get to https://api.company-information.service.gov.uk/search
    (Result: Authorization & Content-Type properly shown in err.equest._header, but error code 400)

  2. Setting axiosinstance config via axios.create with auth & content-type headers & q param then via axiosinstance.get to https://api.company-information.service.gov.uk/search
    (Result: Authorization & Content-Type properly shown in err.request._header, but error code 400)

  3. Sending whole request, params & headers in a one-liner:
    axios.get(apiUrl, {params: { q: searchterm }}, {headers: { ‘Authorization’: Basic ${apiKey}:, ‘Content-Type’: ‘application/json’}})
    (Result: Authorization & Content-Type NOT shown in err.request._header, & error code 401)

For #3, apiUrl = “https://api.company-information.service.gov.uk/search
And searchterm = “Just”
I have tried base64 encoding my key first, btoa’ing it and tried it without the “:” to no avail.

I have attached an image of option 3 as that seems to have gotten me the closest so far.

Any help at all would be appreciated, I feel incredibly lost

When you created an application at CH, was it a test / sandbox one or a live one? I think the test ones are best avoided, just use “live”.

I’m not a node / axios user but the docs suggest you can also avoid any confusion about http basic authorization by getting axios to do that for you - instead of passing the headers member in the config object parameter (you don’t need to specify Content-Type, you’re not sending JSON to Companies House) use the auth member:

      axios.get(apiUrl, {params: { q: searchterm }}, {
      // `auth` indicates that HTTP Basic auth should be used, and supplies credentials.
      // This will set an `Authorization` header, overwriting any existing
      // `Authorization` custom headers you have set using `headers`.
      auth: {
        // Note no terminal ":" needed as long as axios / node is doing this correctly...
        username: 'MY_RAW_API_KEY_HERE',
        // For Companies House the password is always the empty string
        password: ''
      }
});

Good luck.

1 Like

Hey man,

Thanks so much for the advice, my key is set to live and I’ve used the auth tactic you suggested, however, I am still getting 401’s :confused:
Authorisation isn’t showing in the response headers either, which is strange, as this seems like the specified way to send auth via Axios.

In your message you mention “As long as Axios / node is doing this correctly”, Is this something I have to specify previously in my index.js file? Or were you referring to it more as a default thing Axios should just do?

I’ll read through more of the docs tonight and see if I can find anything else to help. Regardless, thank you so much for helping so far

Not being an axois / node developer I can’t help further on that unfortunately. I did find this article the first time round (about getting a request element when you make a request and it fails). Of course you may already have got to that point…

We have always used very simple tools like curl on the command line as this allows you to get some of the raw comms. I’m not sure that is an option for you here - but presumably other things you can apply (Wireshark or similar)?

Silly as it seems but a previous issue or two of this kind were resolved when people realised they were using the wrong API key e.g. one out of several they had registered…

Good luck.

1 Like

Thank you so much, I finally got it working!

To make it work, I used the auth method you mentioned but used it in option 2 of the “3 different ways” I had tried in my original post here.

What I believe the issue could have possibly been was that I was setting the base URL to “https://api.company-information.service.gov.uk/search”?
I’m not sure why this would be an issue, but setting the base URL to just “https://api.company-information.service.gov.uk/” and instead, after setting the params and auth stuff previously using axios.create, sending the get request to ‘search’ worked.

Quite odd, and I may not be explaining it well, so if anyone does see this in future and has the same issue, I hope this code here helps! Thanks so much @voracityemail

Don’t know why 3 didn’t work for you, but a 400 code generally means you’ve mangled the URL (and or query parameters).

I’m assuming that use of the axios baseURL here means that when you do a get with e.g. the “search” string it will tack that on to the base url - so presumably before in method (2) (depending on exactly what code you had) you were requesting something like:

https://api.company-information.service.gov.uk/search/search?q=...
or (if you did e.g .axiosInstance.get(’’) ) perhaps
https://api.company-information.service.gov.uk/search/?q=...

Anyway - glad you’ve got this working.