# GLEIF LEI Search — Legal Entities, Owners, Subsidiaries (`dalbian/gleif-lei-register-search`) Actor

Search the global LEI register by company name, country, national company number or LEI, and get back the legal entity behind the identifier: registered name, legal and headquarters address, legal form, registration status, plus its declared parent and subsidiaries. Official GLEIF data, no key.

- **URL**: https://apify.com/dalbian/gleif-lei-register-search.md
- **Developed by:** [Benjamin Jerez](https://apify.com/dalbian) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 search runs

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GLEIF LEI Search — Legal Entity Identifiers, Owners and Subsidiaries

Search the global register of **Legal Entity Identifiers** — roughly 2.7 million legal entities, the identifier that MiFID II, EMIR and most KYC files are built on — by company name, country, national company number or LEI, and get back the entity behind the code together with its declared parent and its subsidiaries.

Official GLEIF data, queried live. No key, no scraping, no licence per lookup.

### What a record returns

`MINO79WLOO247M1IL051`:

| Field | Value |
| --- | --- |
| `lei`, `legalName` | MINO79WLOO247M1IL051 · AIRBUS SE |
| `legalAddressLines`, `legalAddressCity`, `legalAddressPostalCode` | MENDELWEG 30 · LEIDEN · 2333CS |
| `country`, `jurisdiction` | NL · NL |
| `otherNames` | AIRBUS GROUP SE |
| `entityCategory`, `legalFormCode` | GENERAL · BBEB |
| `entityStatus`, `registrationStatus` | ACTIVE · ISSUED |
| `registeredAs`, `registrationAuthority` | 24288945 · RA000463 |
| `initialRegistrationDate`, `lastUpdateDate`, `nextRenewalDate` | 2012-06-06 · 2025-10-23 · 2026-12-12 |
| `managingLou`, `corroborationLevel` | 213800WAVVOPS85N2205 · FULLY\_CORROBORATED |
| `bic`, `ocid` | AIRBNL22XXX · nl/24288945 |
| `hasDirectParent`, `hasChildren` | false · true |
| `gleifUrl` | https://search.gleif.org/#/record/MINO79WLOO247M1IL051 |

Headquarters address comes back as a separate set of fields, because for holding companies and funds it is routinely a different place from the legal address.

### How name matching actually works

This is the part that surprises people, so it is worth being exact. `filter[entity.legalName]` matches **whole words, case-insensitively, in any order, all of them required**. It is not a prefix search and not fuzzy.

| You search | Entities returned |
| --- | --- |
| `Airbus` | 99 |
| `AIRBUS SE` | 1 |
| `airbus se` | 1 |
| `Airbus Operations` | 4 |
| `Operations Airbus` | 4 — word order is irrelevant |
| `airbu` | 0 — partial words never match |
| `Airbus Operations GmbH` | 0 — no single entity carries all three words |

So adding a word narrows, removing a word widens, and a truncated word finds nothing. If a search comes back empty, the most likely cause is a word that is not in the registered legal name — `GmbH` where the register says `AG`, or a trading name where the register holds the legal one.

### Filters combine

Filters are ANDed by the API, not merged or dropped:

| Query | Matches |
| --- | --- |
| `Deutsche Bank` | 382 |
| `Deutsche Bank` + country `DE` | 11 |
| `Deutsche Bank` + country `DE` + status `ISSUED` | 10 |

`Airbus` alone returns 99; `Airbus` with entity status ACTIVE returns 87 and with INACTIVE returns 12 — the two halves add up, which is the check that the filter is genuinely being applied.

**City is the exception.** The GLEIF API has no city filter — sending one is refused outright — so this Actor applies the city to the rows it has already fetched. It narrows what you get; it does not reach further into the register. Pair it with a country and a specific name, and raise the result cap.

### Parents and subsidiaries

Turn on **Include parent companies** and every entity gets a row for its direct parent and a row for its ultimate parent. Turn on **Include subsidiaries** and every entity that names it as direct parent comes back as a row. AIRBUS SE returns 31 direct subsidiaries across thirteen countries — 11 in France, 7 in Germany, 3 in the UK, the rest in Canada, Spain, Ireland, Luxembourg, Hungary, Denmark, Finland, Japan, Korea and Singapore. Rows are linked by `parentOfLei` and `childOfLei`.

#### "No parent" is an answer, not an error

GLEIF does not leave the parent field blank. An entity that has no parent has to **say so**, with a category and a reason, and the Actor returns that statement as a row with `relationType` `NO_PARENT_DECLARED`:

| Entity | Reason | What it means |
| --- | --- | --- |
| AIRBUS SE | `NO_KNOWN_PERSON` | Nobody consolidates it — it is the top of the tree |
| AIRBUS DEFENCE AND SPACE GMBH | `NON_CONSOLIDATING` | It has an owner, but no one files consolidated accounts that include it |

Other reasons you will meet are `NATURAL_PERSONS` (owned by individuals, who have no LEI) and `NO_LEI` (the parent exists but never obtained an identifier). For due diligence the distinction matters: `NO_KNOWN_PERSON` on a counterparty means you have reached the ultimate owner, `NATURAL_PERSONS` means the beneficial owner is a person and the register will not name them.

This also means **the tree is much thinner than reality**. Of sixty consecutive UK entities sampled from the register, exactly one had a parent LEI on file; the other fifty-nine had filed an exception — 26 `NATURAL_PERSONS`, 21 `NON_CONSOLIDATING`, 11 `NO_KNOWN_PERSON`, 1 `NO_LEI`. AIRBUS DEFENCE AND SPACE GMBH is wholly owned by Airbus and does not appear as its child, because it filed `NON_CONSOLIDATING`. GLEIF records who reports what, not who owns what. Treat an absent link as unreported, never as independence.

### Who uses this

Compliance and KYC teams resolving a counterparty name to a verifiable identifier before onboarding. Banks and brokers filling the LEI field on MiFID II, EMIR and SFTR reports. Data teams matching an internal customer table to a national company number through `registeredAs`. Corporate-intelligence and sanctions-screening products that need the ownership layer under a name. Anyone checking whether a counterparty's identifier is still ISSUED rather than quietly LAPSED.

### Scope and limits

**The register only holds entities that applied for an identifier.** Roughly 2.7 million worldwide, heavily weighted towards the financial sector and towards jurisdictions where an LEI is mandatory for trading. A small private company with no market activity will usually not be in it at all.

**LAPSED is common and is not an error.** An LEI must be revalidated every twelve months; a large share of the register is past due. The record stays visible and still identifies the entity, but the underlying data has not been reconfirmed. Only `ISSUED` means recently checked. Filter on registration status if that matters to you.

**Entity status and registration status are independent.** AIRBUS SECURE LAND COMMUNICATIONS GMBH is an ACTIVE company holding a LAPSED identifier. An INACTIVE company can hold an ISSUED one. Neither implies the other.

**Addresses are registered addresses.** For funds and holding companies that is frequently a fund administrator's office, not an operating site.

### Source and licence

**GLEIF** — the Global Legal Entity Identifier Foundation — through `api.gleif.org/api/v1`. GLEIF publishes the register under CC0, free for any use including commercial, with no attribution requirement. The data comes from the LEI issuers (LOUs) that validate each record against the national business register named in `registrationAuthority`. Queried live on every run; the response carries the golden-copy publication date of that day.

### Frequently asked

**Why did my search return nothing when the company clearly exists?**
Two likely reasons. Either the company has no LEI — most do not — or a word in your search is not in its registered legal name. Try the distinctive word alone: `Airbus` rather than `Airbus Operations GmbH`.

**How do I get exactly one entity instead of ninety-nine?**
Use the LEI if you have it, or the national company number, which is exact. `775724792` returns AIRBUS GROUP and nothing else. Failing that, type the full registered name including the legal form — `AIRBUS SE` returns one row.

**What is `registeredAs`?**
The company's number in its home business register: SIREN in France, `HRB 171306` in Germany, the Companies House number in the UK. `registrationAuthority` says which register that is, as a GLEIF RA code. It is the most reliable join key between an LEI and a record you already hold.

**Does the name search look at trading names and former names?**
No. It searches the registered legal name only. The `otherNames` field on the returned row carries the alternatives the entity declared — AIRBUS SE also files as AIRBUS GROUP SE — but you cannot search on them, so a former name may find nothing even though it is on the record.

**How many results can one search return?**
The register is paged 200 at a time and the Actor pages through it, so the cap is whatever you set, up to 10 000 per name. A search for `Bank` matches tens of thousands, which is what the cap is there to stop.

**Is an invalid or unknown LEI charged?**
No. Malformed codes are rejected before any request is made, and codes that are well formed but absent from the register are reported in the search summary. You are billed per entity returned.

**Are parent and subsidiary rows charged separately?**
No. They are included with the entity they hang off. A search that returns one entity and its 31 subsidiaries is charged as one entity.

# Actor input Schema

## `names` (type: `array`):

Legal entity names to search, one per line — for example Airbus, Deutsche Bank. Matching is whole-word and case-insensitive: every word you type must appear as a complete word somewhere in the name, in any order. 'Airbus' returns 99 entities including AIRBUS IFC and AIRBUS OPERATIONS LIMITED; 'AIRBUS SE' returns exactly 1. Partial words do not match — 'airbu' returns nothing. Add words to narrow, remove words to widen.

## `leis` (type: `array`):

20-character LEI codes to look up directly, one per line — for example MINO79WLOO247M1IL051. Faster and exact where you already have the identifier, and the only way to be certain which of several similarly named entities you got. Codes are fetched in batches, so a few thousand is one run. Direct lookups ignore the country, city and status filters below: you asked for that exact identifier, so you get it.

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

ISO 3166-1 alpha-2 code of the legal address — DE, FR, US, GB. Combines with the name search: 'Airbus' alone returns 99 entities, 'Airbus' plus DE returns 25. This is the registered legal address, not the headquarters.

## `city` (type: `string`):

City of the legal address — Suresnes, Frankfurt am Main. The GLEIF API has no city filter, so this Actor applies it to the rows it has already fetched. That means it narrows the results but does not reach deeper into the register: pair it with a country and a reasonably specific name, and raise the result cap. Matching is case-insensitive and ignores accents.

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

Whether the legal entity itself is still in existence. This is about the company, not about its LEI: an ACTIVE company can hold a LAPSED identifier and vice versa.

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

State of the identifier itself. ISSUED is the only status that means the record was revalidated within the last twelve months, which is what most counterparty checks require. LAPSED records stay in the register and are still returned here.

## `registeredAs` (type: `string`):

The company's number in its home business register — SIREN in France, Handelsregisternummer in Germany, Companies House number in the UK. 775724792 returns AIRBUS GROUP. This is the cleanest way to attach a LEI to a record you already hold, because the number is exact where a name is not.

## `includeParents` (type: `boolean`):

Add a row for the direct parent and the ultimate parent of every entity found. Where an entity declares that it has no parent, the row carries GLEIF's own reason instead — NO\_KNOWN\_PERSON, NON\_CONSOLIDATING, NATURAL\_PERSONS — which is information, not a failure.

## `includeChildren` (type: `boolean`):

Add a row for every entity that names one of your results as its direct parent. AIRBUS SE returns 31. Large groups have hundreds, so this is the setting that drives run time.

## `maxResultsPerSearch` (type: `integer`):

Cap on entities returned for each name you search. The register holds 2.7 million entities and a common word such as 'Bank' matches tens of thousands, so this is what stops a broad search becoming a long run.

## Actor input object example

```json
{
  "names": [
    "Airbus"
  ],
  "country": "FR",
  "entityStatus": "ANY",
  "registrationStatus": "ANY",
  "includeParents": false,
  "includeChildren": false,
  "maxResultsPerSearch": 100
}
```

# Actor output Schema

# 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 = {
    "names": [
        "Airbus"
    ],
    "country": "FR"
};

// Run the Actor and wait for it to finish
const run = await client.actor("dalbian/gleif-lei-register-search").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 = {
    "names": ["Airbus"],
    "country": "FR",
}

# Run the Actor and wait for it to finish
run = client.actor("dalbian/gleif-lei-register-search").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 '{
  "names": [
    "Airbus"
  ],
  "country": "FR"
}' |
apify call dalbian/gleif-lei-register-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dalbian/gleif-lei-register-search"
        }
    }
}
```

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/IUjfxtZSzefb12MeZ/builds/6wrC871DlaNjVyLQQ/openapi.json
