How to use Companies House in n8n: a scheduled workflow that flags status changes and overdue filings
Is there an n8n Companies House node?
No, not an official one. The built-in nodes in the n8n repository (packages/nodes-base/nodes) include the generic HTTP Request node but nothing for Companies House, as of 21 October 2026. A few community nodes are published on npm by independent developers. They are not maintained by n8n or Companies House, so installing one means trusting and updating third-party code yourself.
The HTTP Request node does the job with less risk: the Companies House API is plain REST with Basic auth, and you keep full control of the URL, retries and batching. The rest of this page builds a workflow with it.
What the workflow does
The workflow checks a list of company numbers every morning and passes on only the companies that need attention. It has five nodes:
- Schedule Trigger: runs once a day at 07:00.
- Code: outputs your list of company numbers, one item each.
- HTTP Request: gets each company profile from Companies House.
- Code: compares the status with yesterday's and checks the overdue flags.
- HTTP Request (optional): fetches balance sheet history from our API for flagged companies only.
You add the delivery step yourself: Slack, Microsoft Teams, email or a row in a spreadsheet, connected after node 4 or 5.
Step 1: get a Companies House API key
Register on the Companies House Developer Hub, create a live application and add a REST API key. Leave Restricted IPs empty unless your n8n server has a fixed outgoing IP, because a mismatch returns 403 (see 401 and 403 errors). A stream key will not work here; that is for the Streaming API.
Step 2: set up Basic auth in n8n
Companies House uses HTTP Basic auth with the API key as the username and an empty password. In n8n:
- Open Credentials, create a Basic Auth credential.
- Put the API key in User and leave Password empty.
- In the HTTP Request node, set Authentication to "Generic Credential Type", Generic Auth Type to "Basic Auth" and pick the credential.
To test it, set the URL to https://api.company-information.service.gov.uk/company/00445790 and run the node. You should get "company_name": "TESCO PLC" and "company_status": "active". A 401 means the key or auth type is wrong. You can also paste a curl command with Import cURL, for example curl -u "YOUR_KEY:" https://api.company-information.service.gov.uk/company/00445790.
Step 3: the fields to watch
The company profile endpoint (/company/{company_number}) returns everything a daily check needs. We confirmed these field names against the live API on 21 October 2026:
| Field | Example | Use |
|---|---|---|
company_status | active, liquidation, administration, dissolved | Alert on any change |
accounts.overdue | false | Accounts past their due date |
accounts.next_due | 2027-08-26 | Next accounts deadline |
confirmation_statement.overdue | false | Confirmation statement late |
confirmation_statement.next_due | 2027-07-02 | Next confirmation statement deadline |
has_insolvency_history | false | Any insolvency case on record |
has_charges | false | Any charges registered |
Overdue accounts are the most common trigger. On 1 October 2026, 93,785 active companies (1.8%) were past their accounts due date (overdue accounts statistics). An overdue confirmation statement is a similar warning sign, covered in confirmation statement overdue.
The importable workflow
Copy the JSON below, then in n8n open a new workflow and paste it onto the canvas (or use Import from File). Credentials are not part of the JSON, so after importing, select your Basic Auth credential on "Companies House profile" and a Header Auth credential on "Financials (UK Company Data)".
{
"name": "Companies House watch",
"nodes": [
{"parameters": {"rule": {"interval": [{"triggerAtHour": 7}]}}, "name": "Every day at 07:00", "type": "n8n-nodes-base.scheduleTrigger", "typeVersion": 1.2, "position": [0, 0]},
{"parameters": {"jsCode": "const numbers = ['00445790', '00519500'];\nreturn numbers.map((n) => ({ json: { company_number: n } }));"}, "name": "Company list", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [220, 0]},
{"parameters": {"url": "=https://api.company-information.service.gov.uk/company/{{ $json.company_number }}", "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "options": {"batching": {"batch": {"batchSize": 1, "batchInterval": 600}}}}, "name": "Companies House profile", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [440, 0]},
{"parameters": {"jsCode": "const state = $getWorkflowStaticData('global');\nstate.status = state.status || {};\nconst alerts = [];\nfor (const item of $input.all()) {\n const c = item.json;\n if (!c.company_number) continue;\n const reasons = [];\n const before = state.status[c.company_number];\n if (before && before !== c.company_status) {\n reasons.push(`status changed: ${before} to ${c.company_status}`);\n }\n if (c.company_status !== 'active' && !before) {\n reasons.push(`status is ${c.company_status}`);\n }\n if (c.accounts?.overdue) {\n reasons.push(`accounts overdue, due ${c.accounts.next_due}`);\n }\n if (c.confirmation_statement?.overdue) {\n reasons.push(`confirmation statement overdue, due ${c.confirmation_statement.next_due}`);\n }\n state.status[c.company_number] = c.company_status;\n if (reasons.length) {\n alerts.push({ json: { company_number: c.company_number, company_name: c.company_name, company_status: c.company_status, reasons } });\n }\n}\nreturn alerts;"}, "name": "Check changes", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [660, 0]},
{"parameters": {"url": "=https://data.globalmindsetmarketing.co.uk/v1/company?number={{ $json.company_number }}&format=json", "authentication": "genericCredentialType", "genericAuthType": "httpHeaderAuth", "options": {}}, "name": "Financials (UK Company Data)", "type": "n8n-nodes-base.httpRequest", "typeVersion": 4.2, "position": [880, 0]}
],
"connections": {
"Every day at 07:00": {"main": [[{"node": "Company list", "type": "main", "index": 0}]]},
"Company list": {"main": [[{"node": "Companies House profile", "type": "main", "index": 0}]]},
"Companies House profile": {"main": [[{"node": "Check changes", "type": "main", "index": 0}]]},
"Check changes": {"main": [[{"node": "Financials (UK Company Data)", "type": "main", "index": 0}]]}
}
}
Replace the two numbers in "Company list" with your own, as 8-character strings with leading zeros (see company number formats). For a longer list, read the numbers from a Google Sheets or database node instead and connect it in the same place.
What we tested. The JSON parses, and node types and parameter names match the n8n source for the HTTP Request (version 4.2), Schedule Trigger (1.2) and Code (2) nodes. We ran the "Check changes" code outside n8n against live Companies House responses for 00445790 and 00519500 on 21 October 2026: the first run stored the statuses and returned nothing; a second run with a simulated status change and overdue flag returned one alert with both reasons. We did not run the workflow inside an n8n instance.
How the change detection works
The "Check changes" node stores yesterday's status per company in workflow static data and compares it with today's. Two things to know from the n8n documentation:
- Static data is not saved when you test a workflow manually. It only persists when the workflow is published and runs from its trigger. During testing every run looks like the first one.
- n8n warns that static data can be unreliable for high-frequency executions. For a daily check this is fine; for many runs an hour, store state in a data table or database.
Overdue flags fire every day while the company stays overdue. If that is too noisy, store the last alerted due date and alert only when it changes.
If a company number does not exist, Companies House returns 404 and the HTTP Request node stops the run. Set the node's On Error setting to continue so one bad number does not block the rest.
Rate limits and batching
Companies House allows 600 requests per five-minute window per key and returns 429 for the rest of the window once you exceed it (rate limiting guide). The workflow makes one request per company per run, and the HTTP Request node's Batching option (1 item per batch, 600 ms interval) keeps it below two requests a second, so even a list of several hundred companies stays inside the limit. Other workflows that use the same key share the same allowance. More detail, including the response headers that show what is left, is in Companies House API rate limits.
Adding financial figures
The Companies House profile tells you dates and flags, not money. The public API returns filing history and document links, but not balance sheet figures as data, so a "net assets went negative" alert needs parsed accounts.
The last node calls our REST API for flagged companies only, which keeps usage low. Create a Header Auth credential with name Authorization and value Bearer ukcd_your_key. The node calls /v1/company?number=...&format=json, which returns the register record and up to 20 machine-readable accounts filings, newest first, with net_assets, cash and other figures in accounts[].figures. Field names and examples are in the API quickstart.
If you would rather not maintain the comparison logic, our watchlist does it on the server: POST /v1/watchlist/add once, then one HTTP Request node calling GET /v1/alerts?format=json each morning. Alerts cover status changes, overdue accounts, newly published accounts, new charges, negative net assets and falls of 30% or more in net assets or cash. The free plan gives 50 requests a month and watches 5 companies; API Pro is £39 a month for 5,000 requests and 50 companies (pricing). Get a free key on the developer docs page.
When n8n is the wrong tool
A scheduled n8n workflow suits tens or hundreds of companies checked daily. If you need every change on the whole register within minutes, use the Streaming API with a dedicated process. If you want an AI assistant to run the checks and write the summary, see how to build a KYB agent.
Sources
- Companies House API: rate limiting
- Companies House API: authorisation guide
- n8n docs: HTTP Request node
- n8n docs: getWorkflowStaticData
- n8n source: built-in nodes
FAQ
Does n8n have a Companies House node?
Not an official one. n8n's built-in nodes do not include Companies House, though some independent developers publish community nodes on npm. The HTTP Request node with a Basic Auth credential works well: put the API key in the User field, leave Password empty and call api.company-information.service.gov.uk directly.
How do I authenticate to Companies House in n8n?
Create a Basic Auth credential with your REST API key as the user and an empty password, then choose Generic Credential Type and Basic Auth in the HTTP Request node. Do not use Bearer or Header Auth with the raw key, which returns 401. A stream key will not work on the REST API.
How many companies can an n8n workflow check without hitting the rate limit?
Companies House allows 600 requests per five minutes per key. One profile request per company with a 600 ms batch interval stays under that, so several hundred companies a day is comfortable. If other workflows or scripts share the key, add up their usage, and back off on 429.
Can n8n get company accounts figures from Companies House?
Not directly as numbers. The Companies House API returns filing history and links to documents, so you would have to download and parse the iXBRL accounts yourself. Calling an API that has already parsed the filings, such as our /v1/company endpoint, returns net assets, cash and other figures as JSON.
Try it with a free key. 50 requests a month, REST and MCP, no card. Company register, iXBRL financial history since 2008 and watchlist alerts.
Get a free API key