# Resolve an entity's ultimate beneficial owners

`GET /entities/{entity_uuid}/ubos`

- Base: `GET https://portal.watcheye.com.au/api/v1/entities/{entity_uuid}/ubos`

Resolves the ultimate beneficial owners (UBOs) of a business entity by tracing its
shareholding relationships (the relationship types that carry an ownership percentage) out to
the natural persons behind it. Indirect ownership through other companies is followed and each
person's stake is aggregated across every chain before the `threshold` is applied.

Every business that could not be fully traced - because it has no recorded shareholders, a
shareholder with an unknown percentage, or recorded shareholdings that do not add up to 100% -
is returned in `data_gaps` regardless of its stake, so the disclosure is complete. The
`threshold` only filters the confirmed `ubos` list.

Only `business` entities can be resolved; for any other entity type `applicable` is `false`
and both lists are empty.

## Parameters

| Name | In | Type | Description |
|------|----|------|-------------|
| `entity_uuid` | path | string (uuid) | **Required.** The entity UUID |
| `threshold` | query | number (float) | The minimum ownership percentage for an owner to be returned (0-100, default 25). Example: `25` |
| `as_of` | query | string (date) | Evaluate ownership as at this date (YYYY-MM-DD, defaults to today). Example: `2025-01-01` |

## Responses

### 200 Ultimate beneficial owner analysis

Content type: `application/json`

| Field | Type | Description |
|-------|------|-------------|
| `data` | object | The ultimate beneficial owner (UBO) analysis for a business entity. Ownership is traced through the entity's shareholding relationships out to the natural persons behind it, with each person's stake aggregated across every chain before the threshold is applied. Every business that could not be fully traced is reported in `data_gaps`, regardless of its stake. |
| `data.applicable` | boolean | False when the entity is not a business (UBO tracing only applies to businesses). Example: `true` |
| `data.threshold` | number (float) | The minimum ownership percentage used to filter the `ubos` list. Example: `25` |
| `data.as_of` | string (date) | The date the ownership was evaluated as at (YYYY-MM-DD). Example: `2025-01-01` |
| `data.fully_traced` | boolean | True when there are no data-quality gaps. Example: `false` |
| `data.circular_detected` | boolean | True when a loop was found in the ownership structure. Example: `false` |
| `data.ubos` | array of objects | Confirmed beneficial owners at or above the threshold. |
| `data.ubos[].uuid` | string (uuid) | UUID of the beneficial owner entity. Example: `7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f` |
| `data.ubos[].name` | string | Name of the beneficial owner. Example: `Alice Smith` |
| `data.ubos[].entity_type` | string | The owner's entity type (typically `individual`). Example: `individual` |
| `data.ubos[].percentage` | number (float) | Aggregated direct and indirect ownership of the subject entity. Example: `30` |
| `data.ubos[].paths` | array of objects | The ownership chains contributing to this owner's stake. |
| `data.ubos[].paths[].percentage` | number (float) | The ownership contributed by this chain. Example: `30` |
| `data.ubos[].paths[].via` | array of objects | The intermediary businesses on this chain, from the subject outwards. |
| `data.ubos[].paths[].via[].uuid` | string (uuid) |  |
| `data.ubos[].paths[].via[].name` | string | Example: `Coral Bay Investments Pty Ltd` |
| `data.data_gaps` | array of objects | Businesses whose ownership could not be fully traced, regardless of stake. |
| `data.data_gaps[].uuid` | string (uuid) | UUID of the business whose ownership could not be fully traced. Example: `7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f` |
| `data.data_gaps[].name` | string | Name of the business. Example: `Coral Bay Investments Pty Ltd` |
| `data.data_gaps[].percentage` | number (float) | The effective ownership of the subject entity that flows through this business (its total stake, traced or not). Example: `100` |
| `data.data_gaps[].untraced_percentage` | number (float) | The effective ownership of the subject entity that is actually unaccounted for via this business - the stake reaching it multiplied by its unresolved fraction. This is the figure shown in the UI and the most meaningful measure of the gap. Example: `40` |
| `data.data_gaps[].reason` | string | Why the business could not be fully traced - one of `no_ownership_data`, `unknown_percentage`, `incomplete_ownership`, `circular_ownership`, `max_depth_reached`. Example: `no_ownership_data` |
| `data.data_gaps[].remainder` | number (float) or null | The unresolved fraction (percentage) of this business's own ownership, where known. Example: `40` |
| `api_reference` | string (uuid) |  |

**Sample response**

```json
{
    "data": {
        "applicable": true,
        "threshold": 25,
        "as_of": "2025-01-01",
        "fully_traced": false,
        "circular_detected": false,
        "ubos": [
            {
                "uuid": "7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f",
                "name": "Alice Smith",
                "entity_type": "individual",
                "percentage": 30,
                "paths": [
                    {
                        "percentage": 30,
                        "via": []
                    }
                ]
            }
        ],
        "data_gaps": [
            {
                "uuid": "7c1c0a8e-2b9f-4f0e-8d1a-1e2b3c4d5e6f",
                "name": "Coral Bay Investments Pty Ltd",
                "percentage": 100,
                "untraced_percentage": 40,
                "reason": "no_ownership_data",
                "remainder": 40
            }
        ]
    },
    "api_reference": "00000000-0000-0000-0000-000000000000"
}
```

Standard error responses: 400, 401, 403, 404, 429, 5XX (see [Common error responses](/docs/reference/general/common-error-responses.md))

