The data
Three sources, one registration number
The register says who exists. The accounts say what they are worth. Geocoding says where they are. Fortuna holds all three against one company number, so a question that spans them is a single request.
The register
Company status, registered office and SIC codes, taken from the monthly Free Company Data Product rather than the REST API, which would take about 64 days of continuous calling to cover once.
The accounts
Every XBRL fact in every filing, stored whole. The daily feed lands Tuesday to Saturday, matching the days Companies House actually publishes, and the archive reaches back to 2008.
The geography
Companies geocoded to postcode level and measured on the WGS84 spheroid, so radius, district and county searches are answered by a spatial index rather than filtered after the fact.
Why every fact
A figure without its dimensions is not a figure
A filing reports the same concept many times: once undimensioned as the balance sheet
total, then again per share class, per asset class, per movement, and for the
consolidated group. Across 4,212 real filings, 45% carried more than one distinct
Equity value for a single period.
| Dimensional context | Equity |
|---|---|
| None company, undimensioned | 2,898,598 |
| ShareCapital | 100 |
| SharePremium | 412,000 |
| RetainedEarnings | 2,486,498 |
| ConsolidatedGroup | 3,140,220 |
Highlighted is the one Fortuna projects into share_holder_funds.
Selection ranks by selector priority, then company before consolidated, then fewest
dimensions, then latest period.
A breakdown is never a total
The class dimensions carry genuine components only, with no Total
member to fall back on. A filing that reports a figure solely by class therefore
yields null, not an arbitrary component picked out of the breakdown.
Concept identity ignores the prefix
A census of 400 documents from one daily file found core:,
frs-core:, uk-core: and d: all bound to the
same FRC namespace across four taxonomy years. Prefixes are document local, so
identity is the namespace family and the local name.
FRS 102 renamed most of it
Checked against current filings, 16 of the legacy 27 concept mappings no longer match. Both the modern and the legacy spelling are held per field, so a 2009 filing and a 2026 filing answer in the same shape.
A specimen
What one answer looks like
Two of the shapes the API returns, with the request that produced each. Every field
is snake_case, matching the column names the data has.
JKL Limited
Net assets and employees come from the most recent filing. Status comes from the register. Distance is measured from the origin postcode on the spheroid.
GET /api/search/area?postcode=DT11+7ST&radiusMiles=20 &minNetAssets=1000000&minEmployees=20&status=active { "items": [ { "company_registration": "03364921", "name": "JKL Limited", "post_code": "BH22 9NH", "admin_district": "Dorset", "admin_county": null, "distance_miles": 11.81, "net_assets": 2898598, "employees": 43, "period_end": "2025-03-31", "company_status": "Active", "status_code": 1, "sic_codes": ["82990"], "domain": null } ], "total": 37, "limit": 50, "offset": 0, "has_more": false }
Balance sheet, one period
creditors_due_within_one_year requires the maturities dimension.
Undimensioned Creditors is the total, and reporting it as the current
portion would be wrong by definition.
GET /api/companyfiling/03364921/between/2020-01-01/2025-12-31 { "items": [ { "company_registration": "03364921", "company_name": "JKL Limited", "legal_form_of_company": "PrivateLimitedCompanyLtd", "currency_used_in_report": "GBP", "start_date_for_period_covered_by_report": "2024-04-01", "end_date_for_period_covered_by_report": "2025-03-31", "fixed_assets": 1204310, "current_assets": 2411880, "creditors_due_within_one_year": 717592, "net_assets_liabilities": 2898598, "share_holder_funds": 2898598, "average_employees": 43, "officers": ["A Director", "B Director"] } ], "total": 6, "limit": 50, "offset": 0, "has_more": false }
API
Nine keyed routes, three open
Everything under /api takes an X-Api-Key header.
/health, /progress and the OpenAPI document do not, so a
probe never needs a credential. Everything below is also at
/docs, where you can paste a key in and send the requests.
# A first request curl -H "X-Api-Key: $FORTUNA_KEY" \ "https://fortuna.mythic.software/api/companyfiling/00005775"
Endpoints
Area search parameters
Either a postcode with a radius, or a district or county, is required. Supplying both narrows to the intersection. Query parameters are camelCase even though response fields are snake_case.
| Parameter | Type | Meaning |
|---|---|---|
| postcode | string | Origin postcode to measure a radius from, for example DT1 1XJ |
| radiusMiles | number | Radius around the origin, up to 500 |
| district | string | Administrative district. Prefer this to a radius for a named area: a 20 mile circle on Dorchester spills into Somerset and still misses east Dorset |
| county | string | Administrative county, where the area has one |
| status | string | Companies House status, for example active. Needs enrichment to have run, since it comes from the register rather than the accounts |
| minNetAssets | number | Minimum net assets on the most recent filing |
| minEmployees | number | Minimum average employees on the most recent filing |
| sicCode | string | SIC code the company is registered under |
| limit | int | Page size, 1 to 200. Defaults to 50 |
| offset | int | How many results to skip. Defaults to 0 |
Paging
Filing and area responses wrap their results in an envelope. The four simple search
routes return a bare array of companies and take the same limit and
offset parameters.
{ "items": [ … ], "total": 37, "limit": 50,
"offset": 0, "has_more": false }
Filing response fields
Identity 5 fields
company_registrationcompany_namelegal_form_of_company
company_tradingcompany_dormant
Period 5 fields
start_date_for_period_covered_by_report
end_date_for_period_covered_by_report
made_up_tobalance_sheet_datecurrency_used_in_report
Balance sheet 9 fields
fixed_assetsfixed_assets_cost_or_value
fixed_assets_cost_or_value_depreciationcurrent_assets
debtorscash_at_bank
net_current_assets_liabilities
total_assets_less_current_liabilitiesnet_assets_liabilities
Creditors 3 fields
creditors_due_within_one_yearcreditors_due_after_one_year
creditors_total
Equity and shares 7 fields
share_holder_fundscalled_up_share_capital
profit_loss_account_reserveshare_type
par_value_shareshares_allotted
shares_allotted_called_up_paid
Address and people 5 fields
principal_place_of_businessaddress_line1
address_line2post_codeofficers
Other 1 field
average_employees
officers is a JSON array, and records who signed that particular filing,
which is a different fact from who is a director today.
Status codes
| 200 | Results, possibly an empty page |
| 400 | An invalid range, or an area search with neither a radius nor an area |
| 401 | Missing or unrecognised X-Api-Key |
| 404 | No filings for that company, or an origin postcode no company is registered at, which is a different answer from no companies nearby |
| 429 | Daily or monthly quota spent, or the burst limit hit. Carries Retry-After |