# LEI Lookup - Bulk GLEIF LEI Search, Validation & Parents (`tinyrex/gleif-lei-lookup`) Actor

Bulk LEI lookup from the official GLEIF API (CC0): LEI codes, company names, BIC or ISIN to legal name, address, status, renewal date and parent companies. $1 per 1,000 records; not-found and invalid LEIs free.

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

## Pricing

from $0.80 / 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.
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

## LEI Lookup: bulk GLEIF LEI search, validation and parent companies

**Check hundreds of LEI codes, or find the LEI for a list of company names, in one run** — for KYB/KYC onboarding, counterparty checks, MiFIR/EMIR reporting and CRM clean-up. The Actor queries the official GLEIF API (open CC0 data) and returns the legal name, addresses, register number, LEI status, renewal date and the direct and ultimate parent company. **$1 per 1,000 LEI records found; invalid, unknown and not-found inputs are free.** No API key, no login.

### What you get from the LEI Lookup

- **Validate LEIs in bulk** — ISO 17442 check digits are verified before any request, so typos are flagged instantly (`found: false`, free). Lapsed and overdue LEIs show up via `registrationStatus` and `renewalOverdue`.
- **Find the LEI from a company name, BIC or ISIN** — name search matches legal-form suffixes both ways (AG / Aktiengesellschaft, Ltd / Limited, Inc / Incorporated), prefers the head office over foreign branches and gives a `matchScore` (1 = exact legal name). BIC and ISIN use GLEIF's official mappings.
- **Corporate ownership** — `directParent` and `ultimateParent` (LEI, name, country), or the reason reported to GLEIF when there is none (`NATURAL_PERSONS`, `NO_KNOWN_PERSON`, `NON_CONSOLIDATING`…).

### Sample output (JSON)

```json
{
  "query": "Siemens AG",
  "queryType": "companyName",
  "found": true,
  "matchScore": 1,
  "lei": "W38RGI023J3WT1HWRP32",
  "legalName": "Siemens Aktiengesellschaft",
  "entityStatus": "ACTIVE",
  "registrationStatus": "ISSUED",
  "category": "GENERAL",
  "legalFormId": "6QQB",
  "jurisdiction": "DE",
  "registeredAs": "HRB 6684",
  "legalAddress": { "lines": "Werner-von-Siemens-Str. 1", "city": "München", "region": "DE-BY", "postalCode": "80333", "country": "DE" },
  "initialRegistrationDate": "2012-06-06T15:52:00Z",
  "nextRenewalDate": "2027-10-25T12:49:24Z",
  "renewalOverdue": false,
  "corroborationLevel": "FULLY_CORROBORATED",
  "bic": ["SIEMDEMMXXX"],
  "directParent": { "lei": null, "name": null, "country": null, "exception": "NO_KNOWN_PERSON" },
  "ultimateParent": { "lei": null, "name": null, "country": null, "exception": "NO_KNOWN_PERSON" },
  "checksumValid": true,
  "gleifUrl": "https://search.gleif.org/#/record/W38RGI023J3WT1HWRP32",
  "error": null
}
```

Export as **CSV, Excel or JSON**, or send it to Google Sheets, Make, Zapier, n8n, webhooks or the Apify API. A `SUMMARY` record in the key-value store has run totals.

### How to configure the LEI Lookup

1. Paste **LEI codes**, **company names**, **BICs** or **ISINs** (any mix, one per line).
2. Optional: set a **country** (ISO code like `DE`) to narrow name searches, and **results per name** (default 1 = best match).
3. Run. Each found LEI record is one charge; rows with `found: false` are free.

#### Example input

```json
{
  "leis": ["HWUPKR0MPOU8FGXBT394", "7LTWFZYICNSX8D621K86"],
  "companyNames": ["Siemens AG"],
  "country": "",
  "maxResultsPerName": 1,
  "includeParents": true
}
```

#### Example input: fast bulk LEI validation (no parents)

```json
{
  "leis": ["HWUPKR0MPOU8FGXBT394", "7LTWFZYICNSX8D621K86", "W38RGI023J3WT1HWRP32"],
  "includeParents": false,
  "maxRecords": 5000
}
```

#### Example input: BIC and ISIN to LEI

```json
{
  "bics": ["SIEMDEMMXXX"],
  "isins": ["DE0007236101"],
  "includeParents": true
}
```

| Setting | Default | Notes |
|---|---|---|
| leis | — | LEIs to validate/look up (batched 200 per request) |
| companyNames | — | Legal names to resolve to an LEI |
| bics / isins | — | Official BIC→LEI and ISIN→LEI mappings |
| country | — | 2-letter code, filters name searches by legal address |
| maxResultsPerName | 1 | Best N matches per name (max 50) |
| includeParents | true | Direct + ultimate parent; no extra charge, slower |
| maxRecords | 1000 | Hard cap on charged rows per run |

**Speed:** GLEIF asks clients to stay under about 60 requests per minute, and the Actor respects that. LEI lists are fast (200 per request); each name, BIC or ISIN takes one request, plus two to four per record for parents. Roughly 1,000 LEIs without parents finish in under a minute; with parents allow about 5 minutes per 100 records (turn parents off for big validation jobs).

### Pricing

Pay per event: **$0.001 per LEI record found** ($1 per 1,000), with Bronze/Silver/Gold discounts. Invalid LEIs, unknown LEIs and names with no match are free. A tiny Actor-start fee applies per run.

### FAQ — LEI Lookup

**What is an LEI?** A Legal Entity Identifier is a 20-character code (ISO 17442) that identifies a legal entity taking part in financial transactions. It's required for MiFID II/MiFIR and EMIR reporting and is widely used for KYB.

**How do I check if an LEI is valid?** Paste it into *LEI codes*. The Actor checks the check digits and then whether GLEIF lists it. A `registrationStatus` of `ISSUED` means it's current; `LAPSED` or `renewalOverdue: true` means it wasn't renewed on time.

**How do I find a company's LEI by name?** Put the legal name into *Company names*, optionally with a country. Check `matchScore`: 1 means the legal name matched exactly (after normalising legal-form suffixes).

**How long is an LEI valid?** An LEI has to be renewed every year with its issuer (LOU). If it isn't, GLEIF marks the record `LAPSED`; the code itself never changes. Use `nextRenewalDate` and `renewalOverdue` to find counterparties whose LEI is about to lapse.

**Can I look up LEIs in bulk for free?** GLEIF's own search is free for single lookups. This Actor is for lists: hundreds or thousands of LEIs, names, BICs or ISINs in one run with one CSV out. Invalid or unknown codes cost nothing, so you only pay for records actually found.

**Can I find the parent company of an LEI?** Yes, `directParent` and `ultimateParent` come from GLEIF Level 2 relationship data. When there's no parent, the `exception` field shows the reason the entity reported.

**Is the data free to reuse?** GLEIF publishes LEI data under the CC0 1.0 licence, so you can reuse it commercially. The data is as reported to GLEIF; always check critical decisions against the record at `gleifUrl`.

**Is this an official GLEIF product?** No. This Actor is independent and not affiliated with, endorsed or supported by GLEIF or any LEI issuer. It only uses GLEIF's public API.

### Related actors

- [Website Contact Details Extractor](https://apify.com/tinyrex/contact-details-extractor) — company emails, phones and social links from a list of domains.
- [UK Companies House Lookup](https://apify.com/tinyrex/uk-companies-house-lookup) — UK company profiles, officers and PSC for KYB.
- [Tech Stack Detector](https://apify.com/tinyrex/tech-stack-detector) — technologies used by any website.
- [TED EU Tenders Scraper](https://apify.com/tinyrex/ted-tenders-scraper) — public tenders and contract awards across the EU.
- [EU Grants & Funding Scraper](https://apify.com/tinyrex/eu-grants-scraper) — open EU funding calls.

# Actor input Schema

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

20-character Legal Entity Identifiers to look up or validate. Check digits (ISO 17442) are verified first; invalid or unknown LEIs come back as free rows with found=false.

## `companyNames` (type: `array`):

Legal names to find the LEI for (e.g. "Siemens AG", "Apple Inc"). Legal-form suffixes like AG/Aktiengesellschaft, Ltd/Limited and Inc/Incorporated are matched both ways. Each result carries a matchScore (1 = exact name).

## `bics` (type: `array`):

Bank BIC codes to map to their LEI (official GLEIF BIC-to-LEI mapping).

## `isins` (type: `array`):

Security ISINs to map to the issuer's LEI (official GLEIF ISIN-to-LEI mapping).

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

Optional 2-letter ISO country code (legal address) to narrow company-name searches, e.g. DE, GB, US.

## `maxResultsPerName` (type: `integer`):

How many best matches to return per company name. 1 = best match only.

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

Add the direct and ultimate parent company (LEI, name, country) or the reported reason why there is none (e.g. NATURAL_PERSONS). Costs nothing extra but makes runs slower, because GLEIF allows about 60 requests per minute.

## `maxRecords` (type: `integer`):

Hard cap on found LEI records (charged rows) in this run.

## Actor input object example

```json
{
  "leis": [
    "HWUPKR0MPOU8FGXBT394",
    "7LTWFZYICNSX8D621K86"
  ],
  "companyNames": [
    "Siemens AG"
  ],
  "maxResultsPerName": 1,
  "includeParents": true,
  "maxRecords": 1000
}
```

# Actor output Schema

## `records` (type: `string`):

Legal entity data per LEI.

## `summary` (type: `string`):

Totals for the run.

# 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": [
        "HWUPKR0MPOU8FGXBT394",
        "7LTWFZYICNSX8D621K86"
    ],
    "companyNames": [
        "Siemens AG"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tinyrex/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": [
        "HWUPKR0MPOU8FGXBT394",
        "7LTWFZYICNSX8D621K86",
    ],
    "companyNames": ["Siemens AG"],
}

# Run the Actor and wait for it to finish
run = client.actor("tinyrex/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": [
    "HWUPKR0MPOU8FGXBT394",
    "7LTWFZYICNSX8D621K86"
  ],
  "companyNames": [
    "Siemens AG"
  ]
}' |
apify call tinyrex/gleif-lei-lookup --silent --output-dataset

```

## MCP server setup

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