# GLEIF LEI Lookup - Legal Entity Identifier API (`dataio/gleif-lei-lookup`) Actor

Look up Legal Entity Identifiers (LEI) from GLEIF and match a company across identifier systems: LEI, national number (SIREN, Companies House, HRB), BIC, MIC, OCID and S\&P Global, with legal address and corporate hierarchy. KYC and entity resolution, no key.

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

## Pricing

from $4.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.
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?

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

### What does GLEIF LEI Lookup do?

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.

### How much does it cost?

You pay per company record returned: **$0.006 each**, that is $6.00 per 1,000. There is no start fee, and subscription plans pay less per company record.

The example input below asks for up to 200 company records, so it costs **$1.20 at most**.

If a run reaches the spending limit you set, the output stops at that limit and never goes past it. You are never charged for rows that were not delivered.

### Use GLEIF LEI Lookup as an API

Call it from your own code with the Apify client, here in Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("DataIO/gleif-lei-lookup").call(run_input={'country': 'FR', 'entityStatus': 'ACTIVE', 'maxItems': 200})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

It also works from JavaScript, Make, Zapier, n8n, and from AI agents through the Apify MCP server.

### Other actors you might like

- [BODACC Scraper](https://apify.com/DataIO/bodacc-french-insolvencies-sales): French Insolvencies & Sales
- [SEC XBRL Screener](https://apify.com/DataIO/sec-edgar-xbrl-financial-screener): Company Financials Data
- [IRS 990 Scraper](https://apify.com/DataIO/irs-990-nonprofit-financials): Nonprofit Financials & Revenue

### FAQ

#### Is it legal to use this data?

The actor reads public data from its official source, without logging in and without bypassing any access control. What you do with the data, for example contacting people listed in it, is your responsibility under the laws that apply to you, such as GDPR in Europe.

#### Can I run it on a schedule?

Yes. Create a schedule in Apify Console, daily or weekly for example, and each run delivers a fresh dataset, which you can send by email, webhook or integration.

#### Can AI agents use it?

Yes. It is available through the Apify MCP server, and every input field is described in its input schema, so an agent can call it directly.

# 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/gleif-lei-lookup").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/gleif-lei-lookup").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/gleif-lei-lookup --silent --output-dataset

```

## MCP server setup

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

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/hyJgvXo6HOoUNWp0n/openapi.json
