# UBO Ownership Tree — UK PSC Beneficial Ownership Chains (`vhsgreed/ubo-ownership-tree`) Actor

Extract beneficial-ownership chains from the official UK Companies House PSC register, no API key. Walk corporate persons-with-significant-control up the chain: owner names, nature of control, direct vs indirect, chain level, source URLs. Flat records for KYB, compliance and lead enrichment.

- **URL**: https://apify.com/vhsgreed/ubo-ownership-tree.md
- **Developed by:** [Karl Sundström](https://apify.com/vhsgreed) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.38 / 1,000 ownership records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## UBO Ownership Tree — UK PSC Beneficial Ownership Chains

> Independent tool built on public UK Companies House (GOV.UK) data. Not affiliated with, endorsed by, or connected to Companies House or GOV.UK.

Extract beneficial-ownership chains straight from the official UK Companies House persons-with-significant-control (PSC) register — no API key, no login, no scraping of paid data feeds — and turn any UK company into a complete ownership tree. Give the actor a company name or number and it walks the corporate PSC chain level by level, returning flat one-record-per-owner output: owner name, owner kind (individual or corporate), nature of control, direct vs indirect ownership, chain level, and a source URL for every record — exported to CSV, Excel, or JSON.

### Why UBO Ownership Tree?

- 🔎 **Verify who really owns a UK company** — walk corporate PSCs up the chain instead of stopping at the first layer, the way compliance teams and analysts need it.
- 🛡️ **KYB/UBO checks from the official register** — auditors, banks, insurers and fintechs get source URLs on every record for audit trails.
- 💼 **Flat one-record-per-owner output** — import straight into Excel, your CRM, or a KYB pipeline with zero post-processing.
- ⚡ **No API key, no login** — reads the public Companies House PSC pages directly; cap the bill with `maxResults`.
- 🔗 **Source URLs on every record** — click through to the exact PSC page the record came from.

### Use cases

- **KYB / compliance**: beneficial-ownership verification, sanctions-adjacent screening, audit-ready evidence with source URLs.
- **Lead generation**: map who owns target accounts before outreach — account managers and SaaS sellers chase the real decision-maker.
- **M\&A / market research**: understand group structures behind UK companies at a glance.
- **Journalism / due diligence**: trace indirect ownership through holding companies.

### What data you get

| Field | Description |
| ----- | ----------- |
| 🏢 `companyNumber` / `companyName` | Subject company the chain starts from |
| 👤 `ownerName` | Person or corporate entity with significant control |
| 🏷️ `ownerKind` | `individual` or `corporate` |
| 🔢 `ownerRegistrationNumber` | UK company number of corporate owners (enables the chain walk) |
| 🔀 `ownershipType` | `direct` (level 1) or `indirect` (upper levels) |
| 📊 `level` | Hops from the subject company (1 = direct PSC) |
| ⚖️ `natureOfControl` | e.g. Ownership of shares – 75% or more, Right to appoint or remove directors |
| 📅 `notifiedOn` / `ceasedOn` | PSC notification dates (ceased PSCs included) |
| 🌍 `nationality` / `countryOfResidence` | Individual owners, if shown |
| 📄 `governingLaw` / `legalForm` | Legal form of corporate owners, if shown |
| 🔗 `sourceUrl` | Official PSC page the record was extracted from |

### How to use

1. Run the actor.
2. Enter a company name (`query`) and/or UK company numbers (`companyNumbers`).
3. Set `maxDepth` (default 3) to control how far corporate owners are followed up the chain.
4. Get flat ownership records in the dataset — export to CSV, Excel, or JSON.

### Input

```json
{
  "country": "uk",
  "query": "arup",
  "companyNumbers": ["02461313"],
  "maxDepth": 3,
  "maxResults": 100
}
```

| Field | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| `country` | string | `uk` | Registry country. Currently supported: `uk`. Denmark (datacvr.virk.dk) and Finland (PRH omistajat) beneficial-ownership registers are not available keyless and are not supported — the actor fails with a clear error if selected. |
| `query` | string | — | Company name searched in the official Companies House index |
| `companyNumbers` | array | — | Direct list of UK company numbers |
| `maxDepth` | integer | `3` | Chain depth cap (1 = direct PSCs only, max 3) |
| `maxResults` | integer | `100` | Cap on ownership records returned (max 100) |

### Output

Real excerpt (Arup Limited, direct PSC):

```json
{
  "country": "uk",
  "companyNumber": "02461313",
  "companyName": "ARUP LIMITED",
  "ownerName": "Ove Arup Holdings Limited",
  "ownerKind": "corporate",
  "ownerRegistrationNumber": "7804146",
  "ownershipType": "direct",
  "level": 1,
  "natureOfControl": [
    "Ownership of shares – 75% or more",
    "Ownership of voting rights – 75% or more",
    "Right to appoint or remove directors"
  ],
  "pscStatus": "Active",
  "notifiedOn": "6 April 2016",
  "ceasedOn": null,
  "governingLaw": "Companies Act 2006",
  "legalForm": "Private Company Limited By Shares",
  "nationality": null,
  "countryOfResidence": null,
  "sourceUrl": "https://find-and-update.company-information.service.gov.uk/company/02461313/persons-with-significant-control"
}
```

### Support

Open an issue in the actor's repository tab — feedback and source-coverage requests are welcome.

# Actor input Schema

## `country` (type: `string`):

Registry to resolve against. Currently supported: uk (Companies House PSC). Denmark (datacvr.virk.dk) and Finland (PRH omistajat) beneficial-ownership data are not available keyless and are not supported.

## `query` (type: `string`):

Company name searched in the official Companies House index, e.g. 'arup' or 'bakery london'

## `companyNumbers` (type: `array`):

Direct list of UK company numbers (e.g. 02461313) to resolve ownership chains for

## `maxDepth` (type: `integer`):

How many levels of corporate owners to walk up (1 = direct PSCs only, default 3, max 3)

## `maxResults` (type: `integer`):

Cap on ownership records returned (default 100, max 100)

## Actor input object example

```json
{
  "country": "uk",
  "maxDepth": 3,
  "maxResults": 100
}
```

# Actor output Schema

## `defaultDataset` (type: `string`):

One record per beneficial owner per company, including chain level, nature of control and source URL.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("vhsgreed/ubo-ownership-tree").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("vhsgreed/ubo-ownership-tree").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call vhsgreed/ubo-ownership-tree --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vhsgreed/ubo-ownership-tree"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/FeHwsAbDV8DdKVSic/builds/a4vU5yVSrp2toeqAP/openapi.json
