# GLEIF LEI Lookup API: Bulk Verify, Parents & Match (`crawlwren/gleif-lei-lookup`) Actor

Verify LEIs in bulk, find direct and ultimate parents, match company names to LEIs with a score, and track new or changed LEIs, all from the official GLEIF API and golden-copy files. Check digits validated first; not-found rows free. CC0 data. $1.50 per 1,000.

- **URL**: https://apify.com/crawlwren/gleif-lei-lookup.md
- **Developed by:** [Chordio, Inc.](https://apify.com/crawlwren) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 lei 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?

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

**Check, find and enrich companies with their Legal Entity Identifier (LEI). It uses the official GLEIF API and daily golden-copy files.** In our pre-launch tests, 9 of 9 live runs succeeded. Paste LEIs to verify them, search the 3.4 million-record global LEI index by name, country or status, match a list of company names to LEIs, or pull every LEI record that changed today.

Use it for:

- **KYB / KYC and onboarding.** Check that a counterparty's LEI exists, is `ISSUED` (not lapsed) and belongs to an active entity, and get its registered and headquarters addresses.
- **Entity resolution and data cleaning.** Match a CRM, supplier or customer list to LEIs, with a match score you can threshold.
- **Corporate ownership.** Optionally add each entity's direct and ultimate parent (GLEIF Level 2 relationship data).
- **Monitoring.** Run daily in `changes` mode to get new and updated LEI records for the countries you care about, e.g. newly registered German companies.

### Why this LEI actor

| | This actor | Typical LEI scrapers |
|---|---|---|
| Data access | **Official GLEIF REST API + golden-copy files.** No HTML, no browser, no login | Often scrape search.gleif.org pages |
| Reliability | 100% of our live test runs succeeded (see below). Retries with back-off and honours `Retry-After`. Every input gets an answer row | The most-used LEI actor on the Store currently succeeds on ~13% of runs |
| Not found / invalid | Explicit `found: false` row with a reason (`invalid_checksum`, `not_in_gleif`...), **free of charge** | Silent gaps |
| Checksum | ISO 17442 check-digit validation before any request | Rare |
| Name matching | Legal name → legal-form-expanded name → full text → fuzzy, ranked by score, then main entity before branches/funds, then active and issued | Plain full-text search |
| Bulk | `changes` mode reads GLEIF's daily delta files (or the full file), with no API paging limits | Paging through 10k max |
| Price | **$1.50 per 1,000 records** | $3–$10 per 1,000 |

### Modes

| `mode` | Input | What you get |
|---|---|---|
| `lookup` (default) | `leis`: up to thousands of LEIs (spaces/dashes ignored) | One row per input, in input order. Found records are charged, not-found and invalid rows are free |
| `search` | `query` (full text or legal name) and/or filters: `countries`, `headquartersCountries`, `entityStatus`, `registrationStatuses`, `entityCategories`, `legalFormCodes` | All matching records (cursor paging, no 10,000 cap), up to `maxResults` |
| `match` | `names`: a list of company names, optional `countries` | Best match(es) per name with `matchScore` (0–1). Names below `minMatchScore` return a free `found: false` row |
| `changes` | `changesPeriod`: `IntraDay`, `LastDay`, `LastWeek`, `LastMonth` or `Full`, plus the same filters and `registeredSince` | Records from GLEIF's official golden-copy delta (or full) file |

#### Input examples

```json
{ "mode": "lookup", "leis": ["W38RGI023J3WT1HWRP32", "5299005CHJZ14D4FDJ62"], "includeParents": true }
```

```json
{ "mode": "match", "names": ["Siemens AG", "BNP Paribas", "Banco Santander S.A."], "matchesPerName": 1, "minMatchScore": "0.6" }
```

```json
{ "mode": "search", "countries": ["LU"], "entityCategories": ["FUND"], "registrationStatuses": ["ISSUED"], "maxResults": 5000 }
```

```json
{ "mode": "changes", "changesPeriod": "LastDay", "countries": ["DE"], "registeredSince": "2026-10-06", "maxResults": 0 }
```

#### Daily monitoring

Schedule `changes` mode with `changesPeriod: "LastDay"` every morning. GLEIF publishes delta files several times a day. Connect Google Sheets, Slack, a webhook or your warehouse through Apify integrations, or call the actor from an AI agent through Apify's MCP server (*"Look up the LEI and parent company of Siemens Energy"*).

### Output

One row per entity, same fields in every mode. Here's a sample from a real run:

```json
[
  {
    "lei": "W38RGI023J3WT1HWRP32",
    "found": true,
    "legalName": "Siemens Aktiengesellschaft",
    "legalNameLanguage": "de",
    "otherNames": [],
    "transliteratedNames": [],
    "entityStatus": "ACTIVE",
    "entityCategory": "GENERAL",
    "entitySubCategory": null,
    "legalFormCode": "6QQB",
    "legalFormOther": null,
    "jurisdiction": "DE",
    "registrationAuthorityId": "RA000304",
    "registeredAs": "HRB 6684",
    "legalCountry": "DE",
    "legalCity": "München",
    "hqCountry": "DE",
    "legalAddress": {
      "addressLines": [
        "Werner-von-Siemens-Str. 1"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "80333"
    },
    "headquartersAddress": {
      "addressLines": [
        "Werner-von-Siemens-Str. 1"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "80333"
    },
    "entityCreationDate": "1996-08-27T22:00:00Z",
    "entityExpirationDate": null,
    "entityExpirationReason": null,
    "successorLei": null,
    "associatedEntityLei": null,
    "registrationStatus": "ISSUED",
    "initialRegistrationDate": "2012-06-06T15:52:00Z",
    "lastUpdateDate": "2026-09-01T15:35:21Z",
    "nextRenewalDate": "2027-10-25T12:49:24Z",
    "managingLou": "5299000J2N45DDNE4Y28",
    "corroborationLevel": "FULLY_CORROBORATED",
    "validationAuthorityId": "RA000304",
    "validatedAs": "HRB 6684",
    "conformityFlag": "CONFORMING",
    "bic": [
      "SIEMDEMMXXX"
    ],
    "mic": [],
    "openCorporatesId": null,
    "spGlobalIds": [
      "394038"
    ],
    "parentsChecked": true,
    "directParent": null,
    "ultimateParent": null,
    "gleifUrl": "https://search.gleif.org/#/record/W38RGI023J3WT1HWRP32",
    "dataSource": "gleif-api",
    "goldenCopyDate": "2026-10-07T16:00:00Z",
    "licence": "CC0 1.0. Source: Global Legal Entity Identifier Foundation (GLEIF), https://www.gleif.org/en/meta/lei-data-terms-of-use",
    "scrapedAt": "2026-10-08T01:38:21.253610+00:00",
    "query": "W38RGI023J3WT1HWRP32"
  },
  {
    "lei": "5299005CHJZ14D4FDJ62",
    "found": true,
    "legalName": "Siemens Energy AG",
    "legalNameLanguage": "de",
    "otherNames": [],
    "transliteratedNames": [],
    "entityStatus": "ACTIVE",
    "entityCategory": "GENERAL",
    "entitySubCategory": null,
    "legalFormCode": "6QQB",
    "legalFormOther": null,
    "jurisdiction": "DE",
    "registrationAuthorityId": "RA000304",
    "registeredAs": "HRB 252581",
    "legalCountry": "DE",
    "legalCity": "München",
    "hqCountry": "DE",
    "legalAddress": {
      "addressLines": [
        "Otto-Hahn-Ring 6"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "81739"
    },
    "headquartersAddress": {
      "addressLines": [
        "Otto-Hahn-Ring 6"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "81739"
    },
    "entityCreationDate": "2019-11-05T23:00:00Z",
    "entityExpirationDate": null,
    "entityExpirationReason": null,
    "successorLei": null,
    "associatedEntityLei": null,
    "registrationStatus": "ISSUED",
    "initialRegistrationDate": "2017-06-07T12:49:03Z",
    "lastUpdateDate": "2026-05-20T11:33:54Z",
    "nextRenewalDate": "2027-06-07T12:49:03Z",
    "managingLou": "5299000J2N45DDNE4Y28",
    "corroborationLevel": "FULLY_CORROBORATED",
    "validationAuthorityId": "RA000304",
    "validatedAs": "HRB 252581",
    "conformityFlag": "CONFORMING",
    "bic": [],
    "mic": [],
    "openCorporatesId": null,
    "spGlobalIds": [
      "612920998"
    ],
    "parentsChecked": true,
    "directParent": null,
    "ultimateParent": null,
    "gleifUrl": "https://search.gleif.org/#/record/5299005CHJZ14D4FDJ62",
    "dataSource": "gleif-api",
    "goldenCopyDate": "2026-10-07T16:00:00Z",
    "licence": "CC0 1.0. Source: Global Legal Entity Identifier Foundation (GLEIF), https://www.gleif.org/en/meta/lei-data-terms-of-use",
    "scrapedAt": "2026-10-08T01:38:21.253610+00:00",
    "query": "5299005CHJZ14D4FDJ62"
  },
  {
    "lei": "529900F0AEX3776C0J76",
    "found": true,
    "legalName": "Siemens Energy Global GmbH & Co. KG",
    "legalNameLanguage": "de",
    "otherNames": [],
    "transliteratedNames": [],
    "entityStatus": "ACTIVE",
    "entityCategory": "GENERAL",
    "entitySubCategory": null,
    "legalFormCode": "8Z6G",
    "legalFormOther": null,
    "jurisdiction": "DE",
    "registrationAuthorityId": "RA000304",
    "registeredAs": "HRA 111200",
    "legalCountry": "DE",
    "legalCity": "München",
    "hqCountry": "DE",
    "legalAddress": {
      "addressLines": [
        "Otto-Hahn-Ring 6"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "81739"
    },
    "headquartersAddress": {
      "addressLines": [
        "Otto-Hahn-Ring 6"
      ],
      "city": "München",
      "region": "DE-BY",
      "country": "DE",
      "postalCode": "81739"
    },
    "entityCreationDate": "2019-08-27T22:00:00Z",
    "entityExpirationDate": null,
    "entityExpirationReason": null,
    "successorLei": null,
    "associatedEntityLei": null,
    "registrationStatus": "ISSUED",
    "initialRegistrationDate": "2019-09-11T07:54:18Z",
    "lastUpdateDate": "2026-08-04T11:42:40Z",
    "nextRenewalDate": "2027-09-11T07:54:18Z",
    "managingLou": "5299000J2N45DDNE4Y28",
    "corroborationLevel": "FULLY_CORROBORATED",
    "validationAuthorityId": "RA000304",
    "validatedAs": "HRA 111200",
    "conformityFlag": "CONFORMING",
    "bic": [
      "SNRGDEMMXXX"
    ],
    "mic": [],
    "openCorporatesId": null,
    "spGlobalIds": [
      "637829554"
    ],
    "parentsChecked": true,
    "directParent": {
      "lei": "5299005CHJZ14D4FDJ62",
      "legalName": "Siemens Energy AG",
      "country": "DE",
      "entityStatus": "ACTIVE"
    },
    "ultimateParent": {
      "lei": "5299005CHJZ14D4FDJ62",
      "legalName": "Siemens Energy AG",
      "country": "DE",
      "entityStatus": "ACTIVE"
    },
    "gleifUrl": "https://search.gleif.org/#/record/529900F0AEX3776C0J76",
    "dataSource": "gleif-api",
    "goldenCopyDate": "2026-10-07T16:00:00Z",
    "licence": "CC0 1.0. Source: Global Legal Entity Identifier Foundation (GLEIF), https://www.gleif.org/en/meta/lei-data-terms-of-use",
    "scrapedAt": "2026-10-08T01:38:21.253610+00:00",
    "query": "529900F0AEX3776C0J76"
  }
]
```

Key fields: `lei`, `found`, `legalName`, `otherNames`, `legalFormCode`, `entityStatus`, `entityCategory`, `registrationStatus` (ISSUED / LAPSED / RETIRED...), `nextRenewalDate`, `legalAddress` / `headquartersAddress` (plus `legalCountry`, `legalCity`, `hqCountry`), `registeredAs` (company number) and `registrationAuthorityId` (registry), `managingLou`, `bic`, `directParent` / `ultimateParent` (with `includeParents`), `matchScore` (match mode), `gleifUrl`, `dataSource`, `licence`.

### Pricing

Pay-per-event. You pay for records delivered. Not-found, invalid and withheld rows are free.

| Event | Price | What it is |
|---|---|---|
| Run start | $0.0005 | Charged once per run at up to 1 GB memory (Apify charges one more per extra GB, e.g. 4 for a 4 GB full-file run). |
| Daily-file scan | $0.01 | Changes mode only: download and scan one GLEIF delta file (last 8 h / day / week / month). |
| Full-register scan | $0.1 | Changes mode with 'Full register' only: download and scan the whole 3.4M-record golden copy. |
| LEI record | $0.0015 ($1.50 per 1,000) | One LEI record delivered to the dataset. Not-found and invalid inputs are free. |

**Examples:**

- Verify 1,000 supplier LEIs: about **$1.50**.
- Daily new-LEI feed for one country (~150 records/day): about **$0.24/day**.
- Export all ~23,800 issued Luxembourg funds: about **$35.70**.

Set a **maximum cost per run** in Apify, and the actor stops cleanly when it reaches it.

### Data source and licence

All data comes from the **Global Legal Entity Identifier Foundation (GLEIF)**. GLEIF publishes LEI data under **CC0 1.0** (public domain dedication), so commercial reuse is allowed with no attribution required ([GLEIF data terms of use](https://www.gleif.org/en/meta/lei-data-terms-of-use)). Every row still carries `licence` and `dataSource` so your lineage stays clear. This actor is not affiliated with or endorsed by GLEIF.

### FAQ

**Do I need a GLEIF account or API key?** No. The GLEIF API and golden-copy files are public and keyless.

**How fast is it?** The actor stays under GLEIF's published rate limit (about 1 request/second). A lookup checks 100 LEIs per request, so 1,000 LEIs take roughly 10–15 seconds. Search returns 200 records per request.

**Why was a record "withheld"?** Some LEIs belong to sole proprietors, whose legal name is a person's name. By default we don't output them (`excludeSoleProprietors: true`). Turn the option off if you have a legitimate need.

**What does `matchScore` mean?** It runs from 0 to 1. A score of 1.0 is an exact legal name. 0.97 means the same name apart from the legal form (e.g. "Siemens" vs "Siemens AG"). Lower scores are fuzzy matches. Keep `minMatchScore` at 0.8 or higher for automated pipelines and check lower scores by hand.

**What happens if GLEIF is down?** We retry with back-off. If a lookup batch still fails, each LEI in it gets a free `found: false` row with `notFoundReason: gleif_error_http_<code>`, so nothing silently disappears. If every request fails, or the golden-copy file can't be read, the run fails with a clear message.

**Full file?** `changesPeriod: "Full"` downloads the complete golden copy (~0.5 GB zipped) and filters it locally. Give the run 4 GB of memory and use filters. One full-file scan is a single $0.10 event plus the records you keep. At 4 GB the $0.0005 run-start fee is charged 4 times (Apify bills it per GB of memory), so $0.002 in total.

### Support

Found a bug or need a field? Open an issue on the actor's **Issues** tab or email hello@crawlwren.com. Built and maintained by **Crawlwren**.

# Actor input Schema

## `mode` (type: `string`):

Look up LEIs, search the register, match company names to LEIs, or get new/changed LEIs from GLEIF's daily files.

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

20-character LEI codes. Malformed codes and bad check digits are flagged without an API call. Every input gets a row; not-found rows are free.

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

One company name per line. Each name returns its best LEI candidate(s) with a 0-1 match score.

## `matchesPerName` (type: `integer`):

How many LEI candidates to return per name.

## `minMatchScore` (type: `string`):

0 to 1. Candidates below this are not returned (and not charged); you get a free 'not found' row with the best candidate instead.

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

Search mode: GLEIF full-text search (names, addresses, identifiers) or legal-name search. Changes mode: legal name contains this text.

## `queryField` (type: `string`):

Full text (names, addresses, registration numbers) or the legal name only.

## `countries` (type: `array`):

ISO 3166 alpha-2 codes, e.g. DE, FR, US. Empty = all. In match mode this narrows candidates.

## `headquartersCountries` (type: `array`):

ISO alpha-2 codes for the headquarters address. Empty = all.

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

ACTIVE = the legal entity exists; INACTIVE = dissolved, merged, etc.

## `registrationStatuses` (type: `array`):

ISSUED = up to date; LAPSED = not renewed. Empty = all.

## `entityCategories` (type: `array`):

Empty = all.

## `legalFormCodes` (type: `array`):

ISO 20275 entity legal form codes, e.g. 2HBR (German GmbH). Empty = all.

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

Adds the parent company LEI and name where GLEIF has reported one (lookup/search/match). Costs 1-2 extra API calls per record, so runs are slower; no extra charge.

## `changesPeriod` (type: `string`):

Which GLEIF golden-copy file to scan. Deltas are small and fast; Full is the whole register (~500 MB zip, give the run 2 GB memory).

## `registeredSince` (type: `string`):

YYYY-MM-DD. Turns the change feed into a 'newly registered entities' feed.

## `excludeSoleProprietors` (type: `boolean`):

Sole-proprietor LEIs are usually named after a private person. They are withheld by default.

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

Stop after this many charged records (0 = no limit). Not-found rows don't count and are free.

## Actor input object example

```json
{
  "mode": "lookup",
  "leis": [
    "W38RGI023J3WT1HWRP32",
    "5299005CHJZ14D4FDJ62",
    "529900F0AEX3776C0J76"
  ],
  "matchesPerName": 1,
  "minMatchScore": "0.6",
  "query": "Siemens Energy",
  "queryField": "fulltext",
  "entityStatus": "any",
  "includeParents": false,
  "changesPeriod": "LastDay",
  "excludeSoleProprietors": true,
  "maxResults": 1000
}
```

# Actor output Schema

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

One row per LEI record (or per not-found/invalid input) from the GLEIF API and golden-copy files, each with its licence.

## `runStats` (type: `string`):

JSON summary of the run: results delivered, items filtered, request success per source, skipped sources and any errors.

# 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 = {
    "leis": [
        "W38RGI023J3WT1HWRP32",
        "5299005CHJZ14D4FDJ62",
        "529900F0AEX3776C0J76"
    ],
    "query": "Siemens Energy"
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlwren/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 = {
    "leis": [
        "W38RGI023J3WT1HWRP32",
        "5299005CHJZ14D4FDJ62",
        "529900F0AEX3776C0J76",
    ],
    "query": "Siemens Energy",
}

# Run the Actor and wait for it to finish
run = client.actor("crawlwren/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 '{
  "leis": [
    "W38RGI023J3WT1HWRP32",
    "5299005CHJZ14D4FDJ62",
    "529900F0AEX3776C0J76"
  ],
  "query": "Siemens Energy"
}' |
apify call crawlwren/gleif-lei-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawlwren/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/JRRtQaPOzodTyyQ3V/builds/jppuP0ur8hy2db7XM/openapi.json
