403 Forbidden - I get 403

I am an experienced RESTful developer, years of experience developing MTD products but new to CH platform. Everything looks straightforward until you start getting 403 for no apparent reason.

I have recently signed up, created an app, generated keys, configured redirect urls localhost and ports. Any calls coming back with 403. Cannot create a test company so nothing testing.

Any wise words?

Can you try this:

curl -v -u 'YOUR_API_KEY:' \
  https://api.company-information.service.gov.uk/company/00000006

And if it fails, can you post the 403 body with the key redacted and maybe that might reveal more.

Additionally:
Have a gander at this and see if it’s relevant to you: Issues with creating test company in sandbox API
And this: Reports of invalid auth when using key in test.

  • Host api-sandbox.company-informati on.service. gov 443 was resolved.
  • IPv6: (none)
  • IPv4: 35.178.252.20, 13.135.146.127, 13.135.229.221
  • Trying 35.178.252.20:443…
  • schannel: disabled automatic use of client certificate
  • ALPN: curl offers http/1.1
  • ALPN: server accepted http/1.1
  • Established connection to …gov.uk (35.178.252.20 port 443) from 192.168.50.3 port 56085
  • using HTTP/1.x

GET /company/00000006 HTTP/1.1
Host: api-sandbox.c…gov.uk
User-Agent: curl/8.21.0
Accept: /
Authorization: Basic tMWIzYi00NTAxLWE5YjktNGY

  • Request completely sent off
  • schannel: remote party requests renegotiation
  • schannel: renegotiating SSL/TLS connection
  • schannel: SSL/TLS connection renegotiated
  • schannel: remote party requests renegotiation
  • schannel: renegotiating SSL/TLS connection
  • schannel: SSL/TLS connection renegotiated
    < HTTP/1.1 403 Forbidden
    < Date: Tue, 22 Sep 2026 00:18:32 GMT
    < Content-Length: 0
    < Connection: keep-alive

Help appreciated

You originally mentioned you wanted to create a new test company, the header/response you posted mentions http://api-sandbox.company-information.service.gov but the CH docs [Different URI for create] state POST https://test-data-sandbox.company-information.service.gov.uk/test-data/company should be used, have you tried this URI yet?

Yes I have. Still getting ‘Forbidden’. Is it just the 2 APIkeys : test and live or there are some other keys one requires?

There are three client credential types, not just “test and live keys”:

  • API key - Basic Auth, used for public-data GETs and also the Test Data Generator.
  • Stream key - for Streaming API connections.
  • OAuth web client - client ID/secret plus OAuth flow, used for filing/change APIs requiring user/company authorisation. Company Information Developer Hub

However, you only need a TEST REST API KEY to create a test company in the sandbox.

I’ve just tested this myself today using a Test application API key and the endpoint is working.

This exact request returned HTTP/2 201 Created:

curl -v \
  -u 'MY-TEST-APPLICATION-API-KEY-HERE-FOLLOWED-BY-A-COLON:' \
  -H 'Content-Type: application/json' \
  -d '{}' \
  'https://test-data-sandbox.company-information.service.gov.uk/test-data/company'

So I think we can rule out the Test Data Generator endpoint itself.

I’d now concentrate on the credential. In Developer Hub, make sure you have:

Application: Test
Client type: API key

rather than a Live API key, Stream key, OAuth client ID or OAuth client secret. This is a screenshot of the test application page where I got my API key from to perform this test:

Also check whether the API key has an IP restriction configured. For diagnosis I’d create a new Test API key with no IP restriction and try exactly the command above.

You don’t need OAuth or your localhost redirect URLs for this particular request, the Test Data Generator authenticates using the Test API key.

If a newly-created unrestricted Test API key (give it 5 minutes to propagate) still produces a bare 403, I’d send Companies House support the timestamp and request details because the identical request is currently returning 201 for another Test application.

This is the output from the CURL statement above, it shows a HTTP/2 201 response, identifies x-ratelimit-remain: 599 because this was my first test against the API during the last 5 minutes.

Thank you for being patient :slight_smile: It was the restriction on the ip address. I have removed it for now as my focus is to write code that works in the first place.

1 Like

I’m glad you made progress with it :+1: