# LEI Entity Resolver (`dataio/lei-entity-resolver`) Actor

Match a company across identifier systems — LEI, national registration number (SIREN, Companies House, HRB), BIC, MIC, OCID, S\&P Global — with legal address and corporate hierarchy.

- **URL**: https://apify.com/dataio/lei-entity-resolver.md
- **Developed by:** [Tom Awake](https://apify.com/dataio) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.00 / 1,000 company records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## LEI Entity Resolver

Match a company **across identifier systems** — LEI, national company number,
BIC, MIC, OpenCorporates, S\&P Global — with legal address, registration
status and corporate ownership.

**No login. No API key. No proxies.**

### The problem this actually solves

Finding a company is easy. *Matching the same company between two systems*
is not — your CRM has a name, your bank file has a BIC, your finance system
has an S\&P id, and the French registry has a SIREN.

GLEIF carries all of them on one record. This Actor exports them as plain
columns:

| Field | Example (Airbus) |
|---|---|
| `lei` | 529900FCMZ4LKXFD0R69 |
| `registeredAs` | **383 474 814** (the French SIREN) |
| `registeredAt` | the national registry that issued it |
| `bic` | AIRBFR22XXX |
| `mic`, `ocid`, `spglobal`, `qcc`, `gem` | other identifier systems |

In testing, **98 % of French entities carried a national registration
number** — so a country-wide export is effectively a LEI↔national-ID
mapping table.

### Whole corporate groups in one run

Give a parent's LEI in **Subsidiaries of this LEI** and you get its entire
ownership tree. Measured on NEOEN FRANCE: **116 owned entities**, against 68
direct subsidiaries — the filter reaches indirect holdings the direct-children
view misses, and it costs no extra lookups.

Add **parent company and subsidiary count** instead when you are going the
other way: for each entity, its direct parent, ultimate parent and how many
subsidiaries it has. That costs three API calls per row, so use it on a
narrow selection.

### Lapsed LEIs are a compliance signal

Set **LEI registration status** to `LAPSED` to list entities that failed to
renew. There are over 73,000 in France alone. A counterparty whose LEI has
lapsed is a flag worth raising before a transaction, and nobody surfaces it
as a list.

### Output

`lei`, `legalName`, `otherNames`, `entityStatus`, `jurisdiction`,
`legalForm`, `category`, `subCategory`, `creationDate`, `registeredAs`,
`registeredAt`, `registrationStatus`, `initialRegistrationDate`,
`lastUpdateDate`, `nextRenewalDate`, `managingLou`, `corroborationLevel`,
`bic`, `mic`, `ocid`, `spglobal`, `qcc`, `gem`, full legal and headquarters
addresses, `gleifUrl`, plus `directParentLei`, `directParentName`,
`ultimateParentLei`, `ultimateParentName` and `directChildrenCount` when
hierarchy is requested.

### Input

```json
{
  "country": "FR",
  "entityStatus": "ACTIVE",
  "maxItems": 500
}
```

| Field | Default | Notes |
|---|---|---|
| `country` | `FR` | Two-letter code of the legal address |
| `entityStatus` | `ACTIVE` | Excludes dissolved and merged entities |
| `legalName` | — | Full or partial legal name |
| `maxItems` | `500` | Up to 50,000 |
| `includeHierarchy` | `false` | Parent and subsidiary count, 3 calls per row |
| `ownedBy` | — | A parent LEI; returns its whole ownership tree |
| `fulltext` | — | Searched across the record, not just the name |
| `bic` | — | 11-character form, e.g. `AIRBFR22XXX` |
| `lei` | — | Exact 20-character LEI |
| `category` | — | Fund, branch, government entity, … |
| `jurisdiction` | — | Legal jurisdiction, which can differ from the address country |
| `registrationStatus` | — | `ISSUED`, `LAPSED`, … |

### Use cases

- **Entity resolution** — build a LEI↔SIREN↔BIC mapping table for a country.
- **KYC and onboarding** — ownership tree, registration status, renewal date.
- **Counterparty screening** — find lapsed or retired LEIs in a portfolio.
- **Fund administration** — every fund registered in a jurisdiction.
- **Data enrichment** — attach a stable global identifier to records that
  only carry a national one.

### Limits, honestly

- **GLEIF only accepts a fixed list of filters.** City, postcode, region and
  headquarters country are refused by the API. Country of legal address,
  jurisdiction, name, full text, category, status, BIC, LEI and `ownedBy`
  all work. This Actor exposes only the ones that do.
- **BIC is rare.** Only financial institutions carry one, so a BIC column is
  mostly empty on a general export — that is the source, not the export.
- A lapsed LEI means the registration was not renewed. It does not by itself
  mean the company is gone.
- Hierarchy is self-declared under GLEIF's reporting rules, and not every
  group reports completely.
- Requests are paced out of courtesy to a free public service.
- Not affiliated with GLEIF.

# Actor input Schema

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

Two-letter country code of the legal address, for example FR, DE, GB, US. Clear this field when looking up a LEI, a BIC or a whole corporate group, otherwise a multinational is silently cut down to one country.

## `entityStatus` (type: `string`):

ACTIVE excludes dissolved and merged entities. Clear it to include them — a dissolved counterparty is often exactly what you are looking for.

## `legalName` (type: `string`):

Full or partial legal name, for example "Airbus". Leave empty to list every entity matching the other filters.

## `maxItems` (type: `integer`):

One row per entity. Country-wide queries run into the hundreds of thousands, so set this deliberately.

## `includeHierarchy` (type: `boolean`):

Adds direct parent, ultimate parent and the number of direct subsidiaries. This costs three extra API calls per entity, so it is much slower — use it on a narrow selection, not on a whole country.

## `ownedBy` (type: `string`):

Give a parent company's LEI and get every entity it owns. This is the corporate-structure question — one group, all its registered subsidiaries — and it needs no hierarchy lookups.

## `fulltext` (type: `string`):

Searched across the whole record, not just the legal name. Useful when the name you have is a trading name or a former name.

## `bic` (type: `string`):

Find the entity behind a BIC — the reverse direction of the identifier problem. Use the full 11-character form, for example AIRBFR22XXX; the 8-character short form returns nothing.

## `lei` (type: `string`):

A single 20-character LEI, when you already have it and want the full record.

## `category` (type: `string`):

Leave empty for all.

## `jurisdiction` (type: `string`):

Legal jurisdiction code, which can differ from the address country — for example an entity registered in LU with a FR address.

## `registrationStatus` (type: `string`):

ISSUED means the LEI is current. LAPSED means it was not renewed, which is itself a compliance signal.

## Actor input object example

```json
{
  "country": "FR",
  "entityStatus": "ACTIVE",
  "maxItems": 500,
  "includeHierarchy": false
}
```

# Actor output Schema

## `results` (type: `string`):

Every row produced by the run, in JSON.

# 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 = {
    "country": "FR",
    "entityStatus": "ACTIVE",
    "maxItems": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("dataio/lei-entity-resolver").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 = {
    "country": "FR",
    "entityStatus": "ACTIVE",
    "maxItems": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("dataio/lei-entity-resolver").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 '{
  "country": "FR",
  "entityStatus": "ACTIVE",
  "maxItems": 500
}' |
apify call dataio/lei-entity-resolver --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dataio/lei-entity-resolver"
        }
    }
}
```

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/33LWg1NzIwdXjXMKJ/builds/938kE7CktBg0o2ry5/openapi.json
