API documentation
The InsolvencyRadar API delivers insolvency filings in Australia as structured data: per day or per period, filterable by procedure type, with company, court, region and case reference. Plain HTTPS and JSON, CSV on request.
Last updated: 2026-09-29
Request access
Keys are issued by hand. Tell us briefly what you want to build and which volume to expect, and access is usually live within one business day.
Introduction
The data API is not yet enabled for Australia. Requests to /api/v1/filings on insolvencyradar.com.au currently return 501 country_not_enabled. This page describes the interface as it works in the live markets (United Kingdom, France, Switzerland). Write to us if you need Australia data, it helps us prioritise.
Insolvency proceedings in Australia are published in an official register that is built for looking up single cases, not for processing data. The InsolvencyRadar API is designed to turn such publications into one clean, filterable table per day.
Credit controllers, trade credit insurers, insolvency practitioners, lenders and journalists use the API in the markets where it is live to feed their own systems with new insolvency filings.
All requests go to https://insolvencyradar.com.au/api/v1. The API speaks HTTPS only and answers with JSON or CSV. There is no mandatory SDK: any language that can send an HTTP request is enough. The examples on this page use curl, Python and Node.
API access is part of a InsolvencyRadar subscription with the API enabled. Terms depend on volume and use case and are agreed individually.
Access
There is deliberately no self-service sign-up. We enable keys by hand because insolvency data can include personal data and we want to know what an integration is for. In practice that is one short message and one business day.
Use the contact form or write to [email protected] and mention four things:
- What you want to build, in two or three sentences.
- Which procedure types and regions you need.
- Roughly how many requests or checked companies per month.
- Whether you can receive webhooks or would rather poll.
You then receive a personal key that works immediately on every endpoint your contract covers. A key belongs to one market: a key issued on insolvencyradar.com.au works on insolvencyradar.com.au, not on the domains of other countries.
Authentication
Every request carries the key in the X-API-Key header. Alternatively the API accepts the same key as a bearer token in the Authorization header, which is handy for tools that only know that header.
X-API-Key: YOUR_API_KEY
# equivalent
Authorization: Bearer YOUR_API_KEY
Without a key the API answers 401 missing_api_key. A key that is unknown, disabled, or whose subscription has lapsed returns 403 invalid_api_key. The reason is always in the error field of the response.
Treat the key like a password: use it only on the server side, never in frontend code, never in a public repository. If a key leaks, tell us and we revoke it at once and issue a new one.
Quickstart
The most common request is also the simplest: every filing of one day, optionally narrowed to a few procedure types. One call, no pagination.
curl -H "X-API-Key: $INSOLVENCY_API_KEY" \
"https://insolvencyradar.com.au/api/v1/filings?date=2026-09-28&types=compulsory-liquidation,cvl"
Without any date the API returns yesterday. That makes a daily job trivial: a cron entry in the morning fetches yesterday's filings and writes them into your system.
For a historical backfill you walk through the period in windows of at most 31 days:
import os, datetime, requests
API = "https://insolvencyradar.com.au/api/v1"
HEAD = {"X-API-Key": os.environ["INSOLVENCY_API_KEY"]}
# Backfill a quarter in 31-day windows, then keep running daily.
start, end = datetime.date(2026, 7, 1), datetime.date(2026, 9, 28)
day = start
while day <= end:
stop = min(day + datetime.timedelta(days=30), end)
r = requests.get(API + "/filings", headers=HEAD, params={
"date_from": day.isoformat(),
"date_to": stop.isoformat(),
"types": "compulsory-liquidation,cvl",
}, timeout=60)
r.raise_for_status()
body = r.json()
if body.get("truncated"):
raise RuntimeError("narrow the window, 10,000 row ceiling reached")
for f in body["filings"]:
print(f["date"], f["case_number"], f["name"])
day = stop + datetime.timedelta(days=1)
Endpoints at a glance
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/filings | Filings for a day or a period, filterable by procedure type, as JSON or CSV. Live today. |
| GET | /v1/types | Procedure types of this market with key, codes and aliases. |
| GET | /v1/companies | Search companies that appear in at least one filing. |
| GET | /v1/companies/{number} | Company profile with current insolvency status. |
| GET | /v1/companies/{number}/filings | All filings of a company in chronological order. |
| GET | /v1/companies/{number}/financials | Published key figures from the accounts. |
| GET | /v1/practitioners | Search appointed insolvency practitioners. |
| GET | /v1/practitioners/{id} | One insolvency practitioner with active cases. |
| POST | /v1/check | Check up to 500 customers or suppliers in one call. |
| GET | /v1/watchlist | List watched companies. |
| POST | /v1/watchlist | Add a company to the watchlist. |
| DELETE | /v1/watchlist/{id} | Remove a company from the watchlist. |
| POST | /v1/webhooks | Register an endpoint for push notifications. |
| GET | /v1/stats | Aggregated counts by day, month, region or procedure type. |
| GET | /v1/regions | Valid values for the region filter. |
| GET | /v1/account | Key, contract scope, limits and current usage. |
Paths are relative to https://insolvencyradar.com.au/api. The full address of the first endpoint is therefore https://insolvencyradar.com.au/api/v1/filings. The filings endpoint is in production; the other endpoints follow the same conventions for keys, errors and limits and are enabled per contract.
Retrieve filings
GET /v1/filings is the core of the API. It returns every filing whose date falls into the requested period, newest first.
| Parameter | Format | Description |
|---|---|---|
| date | YYYY-MM-DD | A single day. Takes precedence over date_from and date_to. |
| date_from | YYYY-MM-DD | Start of a period, inclusive. If only date_from is given, the period is that one day. |
| date_to | YYYY-MM-DD | End of a period, inclusive. If only date_to is given, the period is that one day. At most 31 days including both ends. If date_from lies after date_to, the API answers 400 bad_range instead of guessing. |
| types | csv | Comma-separated list of procedure types: group key, alias or raw code, case-insensitive. Omit for all types. See the next section. |
| format | json | csv | json (default) or csv. |
Without date, date_from and date_to the period is yesterday.
Response
| Field | Type | Description |
|---|---|---|
| date_from | string | Effective start of the period. |
| date_to | string | Effective end of the period. |
| types | string[] | The group keys that were served, after resolving aliases and codes. |
| count | integer | Number of filings in the array. |
| filings | object[] | The filings, see the filing object. |
| truncated | boolean | Only present, and then true, if the response hit the ceiling of 10,000 rows. Narrow the period or the types and request again. |
{
"date_from": "2026-09-28",
"date_to": "2026-09-28",
"types": ["creditors-voluntary-liquidation", "compulsory-liquidation"],
"count": 57,
"filings": [
{
"date": "2026-09-28",
"type": "Compulsory liquidation",
"type_code": "compulsory-liquidation",
"name": "SAMPLEWORTH JOINERY LIMITED",
"address": "Unit 4 Canal Wharf, Leeds, LS11 5PS",
"court": "Companies House",
"case_number": "1",
"region": "Yorkshire and the Humber",
"notice": "Compulsory liquidation. Company: SAMPLEWORTH JOINERY LIMITED. Petitioned on: 2026-08-19. Wound up on: 2026-09-28. Practitioner(s): Official Receiver (official-receiver)."
}
]
}
A period always comes back in one piece: this endpoint has no pagination. Rows are sorted by date, newest first, and within a day by internal ID, newest first. The same request in Node, filtered on the client side to one region:
const url = new URL("https://insolvencyradar.com.au/api/v1/filings");
url.searchParams.set("date_from", "2026-09-01");
url.searchParams.set("date_to", "2026-09-28");
url.searchParams.set("types", "compulsory-liquidation");
const res = await fetch(url, {
headers: { "X-API-Key": process.env.INSOLVENCY_API_KEY },
});
if (!res.ok) throw new Error((await res.json()).error);
const { count, filings } = await res.json();
const local = filings.filter((f) => f.region === "Yorkshire and the Humber");
console.log(count, "filings,", local.length, "in Yorkshire and the Humber");
Procedure types
The filing types for Australia are published here as soon as the market is enabled. Until then an unknown types value is not the error you will see: every request answers 501 country_not_enabled.
The type field carries the readable name of the procedure, type_code the code used by the source register. An unknown value in types returns 400 bad_type together with allowed_types, the full list of accepted tokens. Agents and scripts should read that list instead of guessing.
The filing object
| Field | Type | Description |
|---|---|---|
| date | string | Date of the filing, YYYY-MM-DD: the latest dated event of the case that is not in the future. The date filter works on this field. |
| type | string | Readable name of the procedure type. |
| type_code | string | Machine key of the procedure type. Use this field for processing, it does not change. |
| name | string | Name of the debtor as published, including the legal form. |
| address | string | null | Registered address as one line. |
| court | string | null | Court or authority that issued the decision. |
| case_number | string | Case or publication reference from the source. |
| region | string | null | Region of the registered address, in the market's own administrative unit. |
| notice | string | null | Readable summary of the filing with the key dates. |
One row is one case as published by the source. A proceeding can produce several rows over time; group by company number to follow one company.
All text fields are UTF-8. Names are passed on as the source publishes them. Fields that the source does not provide are null, never an empty guess. Cases without a usable date cannot be placed on a day and are not served. Your client should ignore fields it does not know, because new fields may be added.
CSV export
With format=csv the API returns the same rows as a CSV file: header row, comma as separator, UTF-8, Content-Type: text/csv; charset=utf-8. The file comes with Content-Disposition: attachment and a file name containing the period.
curl -H "X-API-Key: $INSOLVENCY_API_KEY" \
-OJ "https://insolvencyradar.com.au/api/v1/filings?date_from=2026-09-01&date_to=2026-09-28&format=csv"
# saved as filings_2026-09-01_2026-09-28.csv
date,type,type_code,name,address,court,case_number,region,notice
2026-09-28,Compulsory liquidation,compulsory-liquidation,SAMPLEWORTH JOINERY LIMITED,"Unit 4 Canal Wharf, Leeds, LS11 5PS",Companies House,1,Yorkshire and the Humber,"Compulsory liquidation. Company: SAMPLEWORTH JOINERY LIMITED. Petitioned on: 2026-08-19. Wound up on: 2026-09-28. Practitioner(s): Official Receiver (official-receiver)."
The columns are exactly the fields of the filing object, in the same order. Fields containing commas are enclosed in quotes. Excel opens the file correctly via "Data, from text/CSV" with UTF-8 encoding; a plain double-click can mangle accented characters depending on the system settings.
Companies
Filings are about cases, but most use cases are about companies. GET /v1/companies searches every company that appears in at least one filing, by name, register number, town, region or status.
curl -G -H "X-API-Key: $INSOLVENCY_API_KEY" \
https://insolvencyradar.com.au/api/v1/companies \
--data-urlencode "q=SAMPLEWORTH JOINERY LIMITED" \
-d region=Yorkshire and the Humber -d limit=20
List endpoints return pages of at most 100 entries with a cursor:
{
"object": "list",
"data": [ { "company_number": "14839205", "object": "company", "...": "..." } ],
"has_more": true,
"next_cursor": "eyJpZCI6MTQ4MzkyMDV9"
}
As long as has_more is true, pass next_cursor as the cursor parameter of the next request. A cursor stays valid for 24 hours.
The company object
{
"company_number": "14839205",
"object": "company",
"name": "SAMPLEWORTH JOINERY LIMITED",
"status": "liquidation",
"address": "Unit 4 Canal Wharf, Leeds, LS11 5PS",
"region": "Yorkshire and the Humber",
"industry": "Construction",
"first_filing": "2026-09-01",
"last_filing": "2026-09-28",
"filings_count": 2,
"url": "https://insolvencyradar.com.au/company/14839205"
}
| Field | Type | Description |
|---|---|---|
| company_number | string | National company register number. |
| name | string | Name according to the most recent filing. |
| status | string | Current stage, derived from the most recent filing. A practical summary, not a legal assessment. |
| address | string | null | Registered address. |
| region | string | null | Region, same values as in filings. |
| industry | string | null | Industry according to our classification, if it can be determined. |
| first_filing | string | Date of the first known filing. |
| last_filing | string | Date of the most recent filing. |
| filings_count | integer | Number of filings linked to this company. |
| url | string | Public company page on insolvencyradar.com.au. |
GET /v1/companies/{number}/filings returns all filings of a company, oldest first, in the same shape as /v1/filings. This gives you the full history without searching by name yourself.
Financial figures
GET /v1/companies/{number}/financials returns published key figures per fiscal year where the national register makes accounts available.
{
"company_number": "14839205",
"currency": "GBP",
"statements": [
{
"period_end": "2025-03-31",
"total_assets": 1840000,
"net_assets": -212000,
"current_liabilities": 1395000,
"cash": 18400,
"employees": 23
},
{
"period_end": "2024-03-31",
"total_assets": 2105000,
"net_assets": 164000,
"current_liabilities": 1210000,
"cash": 96100,
"employees": 31
}
]
}
Fields that are not in a filing are null and never estimated.
Practitioners
GET /v1/practitioners searches the appointed practitioners or offices by name, firm or city; GET /v1/practitioners/{id} returns one with their active cases.
curl -G -H "X-API-Key: $INSOLVENCY_API_KEY" \
https://insolvencyradar.com.au/api/v1/practitioners \
-d city=Leeds -d limit=10
{
"id": "prc_4Rk8Wm2Qz",
"object": "practitioner",
"name": "Jane Example",
"firm": "Example Recovery LLP",
"city": "Leeds",
"active_cases": 41,
"total_cases": 318,
"last_appointment": "2026-09-28",
"url": "https://insolvencyradar.com.au/practitioners/"
}
Typical use: a creditor wants to know who to send a claim to. The company profile names the appointed insolvency practitioner, the practitioner endpoint adds address and caseload.
Counterparty check
POST /v1/check checks a whole list of customers or suppliers in one call. You send your own reference and whatever you know about the company: name, town or register number. The API returns a match and the insolvency status for each entry.
curl https://insolvencyradar.com.au/api/v1/check \
-H "X-API-Key: $INSOLVENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"since": "2024-01-01",
"items": [
{ "ref": "D-10023", "name": "SAMPLEWORTH JOINERY LIMITED", "city": "Leeds" },
{ "ref": "D-10024", "company_number": "09876543" },
{ "ref": "D-10025", "name": "HARBOUR LANE FOODS LIMITED" }
]
}'
{
"checked": 3,
"hits": 1,
"results": [
{
"ref": "D-10023",
"match": "exact",
"company_number": "14839205",
"status": "liquidation",
"last_filing": { "date": "2026-09-28", "type_code": "compulsory-liquidation", "case_number": "1" }
},
{ "ref": "D-10024", "match": "none" },
{ "ref": "D-10025", "match": "ambiguous", "candidates": 2 }
]
}
| match | Meaning |
|---|---|
| exact | Register number matches, or name and town match unambiguously. |
| probable | Name matches after normalisation (legal form, spelling), town plausible. Please check before acting on it. |
| ambiguous | Several companies fit. The response contains the number of candidates; add the town or the register number. |
| none | No filing in the period. That is good news, but not a credit rating. |
A call accepts up to 500 entries. since limits the search to filings from that date, default is three years back. For larger portfolios we recommend the watchlist: check once, then only receive changes.
Watchlist
The watchlist turns a one-off check into continuous monitoring. You add companies, and as soon as a new filing appears for one of them you receive a watchlist.match event by webhook.
curl https://insolvencyradar.com.au/api/v1/watchlist \
-H "X-API-Key: $INSOLVENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "company_number": "14839205", "ref": "D-10023" }'
{
"id": "wl_Q7m2Lx9Pd",
"object": "watchlist_entry",
"ref": "D-10023",
"company_number": "14839205",
"name": "SAMPLEWORTH JOINERY LIMITED",
"created_at": "2026-09-29T08:12:44Z",
"last_match": null
}
Companies that have never been insolvent can also be watched. The entry then waits for the first filing, which is exactly the point. Your own reference in ref comes back in every event, so you can map a hit to your customer number without an extra lookup.
GET /v1/watchlist lists all entries with the date of the last match, DELETE /v1/watchlist/{id} removes one. The same watchlist is visible in your InsolvencyRadar dashboard; changes are synchronised both ways.
Webhooks
Instead of polling you can have events pushed. Register an HTTPS endpoint and choose the events, optionally with a filter on procedure types and regions.
curl https://insolvencyradar.com.au/api/v1/webhooks \
-H "X-API-Key: $INSOLVENCY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/insolvency",
"events": ["watchlist.match", "filing.published"],
"filter": { "types": ["compulsory-liquidation"], "region": ["Yorkshire and the Humber", "London"] }
}'
| Event | When |
|---|---|
| filing.published | A new filing matches your filter. Arrives shortly after the daily ingest, usually in the morning. |
| watchlist.match | A new filing concerns a company on your watchlist. |
| stats.daily_ready | The daily figures for the previous day are complete. |
{
"id": "evt_5Tg8Nw2Ka",
"type": "watchlist.match",
"created_at": "2026-09-29T06:05:11Z",
"data": {
"watchlist_entry": { "id": "wl_Q7m2Lx9Pd", "ref": "D-10023" },
"filing": {
"date": "2026-09-28",
"type": "Compulsory liquidation",
"type_code": "compulsory-liquidation",
"name": "SAMPLEWORTH JOINERY LIMITED",
"court": "Companies House",
"case_number": "1",
"region": "Yorkshire and the Humber"
}
}
}
Every call is signed. The X-Webhook-Signature header contains a timestamp and an HMAC-SHA256 over timestamp and raw body, calculated with the secret you receive when registering.
X-Webhook-Signature: t=1790661911,v1=7f2c1d9a4b6e8035c1f7a29d4e5b0c8371a6d2f94e8b3c07a15d9e2f6b4c8a01
import hashlib, hmac, os, time
from flask import Flask, request, abort
app = Flask(__name__)
SECRET = os.environ["WEBHOOK_SECRET"].encode()
@app.post("/hooks/insolvency")
def hook():
header = request.headers.get("X-Webhook-Signature", "")
parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p)
signed = parts.get("t", "") + "." + request.get_data(as_text=True)
expected = hmac.new(SECRET, signed.encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, parts.get("v1", "")):
abort(400)
if abs(time.time() - int(parts["t"])) > 300:
abort(400) # replay protection
event = request.get_json()
if event["type"] == "watchlist.match":
ref = event["data"]["watchlist_entry"]["ref"]
print("Customer", ref, "has a new insolvency filing")
return "", 204
Answer with a 2xx status within ten seconds. If that fails, we retry with increasing intervals over 24 hours, eight times in total. Events can arrive twice, so use the id of the event to discard duplicates.
Statistics
GET /v1/stats returns counts instead of individual filings. This is the endpoint for dashboards, reports and journalism, because it does not require downloading and counting thousands of rows.
curl -G -H "X-API-Key: $INSOLVENCY_API_KEY" \
https://insolvencyradar.com.au/api/v1/stats \
-d date_from=2026-07-01 -d date_to=2026-09-28 \
-d group_by=month,region -d types=compulsory-liquidation
{
"date_from": "2026-07-01",
"date_to": "2026-09-28",
"group_by": ["month", "region"],
"rows": [
{ "month": "2026-07", "region": "Yorkshire and the Humber", "count": 118 },
{ "month": "2026-07", "region": "London", "count": 342 },
{ "month": "2026-08", "region": "Yorkshire and the Humber", "count": 104 }
],
"total": 3187
}
group_by accepts day, week, month, region, type and industry, up to two at once. types works as on /v1/filings. Unlike filings, the period may cover up to 24 months.
Our figures count published filings. They are not identical to official insolvency statistics, which usually count opened proceedings.
Reference data
GET /v1/types returns the procedure types of this market exactly as in the table above: key, label, codes and aliases. GET /v1/regions returns the valid region values in the spelling used in filings. Both change rarely and may be cached for a day.
GET /v1/account shows your contract scope, the active limits and the consumption in the current month.
Errors
Errors come back as JSON with a matching HTTP status. The error field is machine-readable and stable, message explains the problem for humans and may change.
{
"error": "range_too_large",
"message": "Range exceeds the 31-day maximum per request."
}
| error | HTTP | Meaning |
|---|---|---|
| bad_date | 400 | A date is not in the format YYYY-MM-DD. |
| bad_range | 400 | date_from lies after date_to. |
| range_too_large | 400 | Period longer than 31 days. |
| bad_format | 400 | format is neither json nor csv. |
| bad_type | 400 | Unknown value in types. The response additionally contains allowed_types. |
| invalid_request | 400 | Other invalid parameter or malformed JSON body. |
| missing_api_key | 401 | No key sent. |
| invalid_api_key | 403 | Key unknown, disabled, issued for another market, or subscription lapsed. |
| insufficient_scope | 403 | The key is not enabled for this endpoint. |
| not_found | 404 | Company, practitioner or watchlist entry unknown. |
| rate_limited | 429 | Too many requests, see limits. |
| server_error | 500 | Error on our side. Retry after a short wait, and tell us if it persists. |
| country_not_enabled | 501 | The data API is not enabled for this market yet. |
{
"error": "bad_type",
"message": "Unknown filing type(s): liquidaton.",
"allowed_types": ["administration", "admin", "creditors-voluntary-liquidation", "cvl", "creditors-voluntary", "members-voluntary-liquidation", "mvl", "..."]
}
{
"error": "country_not_enabled",
"message": "The data API is not available for Australia yet."
}
Limits
| Value | Limit |
|---|---|
| 120 / min | Requests per minute and key. Higher on request. |
| 31 | Maximum days per request on /v1/filings, both ends included. /v1/stats allows 24 months. |
| 10000 | Maximum rows per response on /v1/filings. Beyond that the response carries truncated: true. |
| 100 | Maximum entries per page on list endpoints. |
| 500 | Maximum entries per call on /v1/check. |
| 10000 | Watched companies per account in the standard contract. |
| 5 | Registered webhook endpoints per account. |
Responses carry the current state of the rate limit in their headers. If you exceed it you receive 429 rate_limited and a Retry-After header in seconds.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1790661960
Retry-After: 12
Versioning
The major version is part of the path (/v1/). Within a major version we only make additive changes: new endpoints, new optional parameters, new fields in responses. Your client should therefore ignore unknown fields instead of failing on them.
Changes that could break existing integrations only happen in a new major version. The previous version then keeps running for at least twelve months, and we inform every key holder by email beforehand. The version date is in the X-API-Version response header.
X-API-Version: 2026-09-01
Data sources and timeliness
Every market uses the official register of that country as its only source for filings. We do not add filings from other sources and do not change their content.
We ingest every day. New filings are usually served by the next morning.
Matching filings to companies is automated. With a register number it is reliable; without one (very common names, sole traders) mistakes are possible. That is why the counterparty check distinguishes between exact and probable.
Data protection and permitted use
Insolvency publications are public, but they can contain personal data. Their use is subject to the GDPR or the national data protection law.
Please mirror corrections and removals in your own systems. A regular comparison over the period you store is enough: whatever the API no longer returns should no longer be in your database either.
Permitted uses are credit risk, receivables management, supplier checks, professional advice, research and journalism. Not permitted: reselling the raw data and automated decisions about natural persons based solely on this data.
Support
Questions about the integration, higher limits or additional fields: [email protected] or the contact form. For technical problems please include the time of the request and the first characters of your key, then we can find the request in the logs straight away.
If you want to connect AI agents rather than write HTTP clients, the same data is available through a Model Context Protocol server, documented at MCP server. Both share keys, limits and contract.
Request access
Keys are issued by hand. Tell us briefly what you want to build and which volume to expect, and access is usually live within one business day.