# GLEIF LEI Lookup: Legal Entity Identifier Search and Check (`nightwave-owner/gleif-lei-lookup`) Actor

LEI records from the open GLEIF register: look up codes or search by name and country. Legal name, status, jurisdiction, legal form, addresses, national register number, BIC and parent LEIs for companies, funds and branches worldwide. Sole proprietors are left out.

- **URL**: https://apify.com/nightwave-owner/gleif-lei-lookup.md
- **Developed by:** [Viktor Wiberg](https://apify.com/nightwave-owner) (community)
- **Categories:** Developer tools, AI, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 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

## GLEIF LEI Lookup (legal entity identifiers worldwide)

A Legal Entity Identifier (LEI) is a 20 character code that identifies a company, fund or other legal entity in financial transactions, defined in ISO 17442. GLEIF, the Global Legal Entity Identifier Foundation, publishes every LEI with the entity's legal name, addresses, register number and ownership links as open data.

This actor looks up LEI codes you already have, or searches the register by legal name and country, and returns one clean row per entity. Use it to verify the LEIs of counterparties before a trade report (EMIR, MiFIR), to enrich a customer list with the national register number and legal form, to find the parent of a subsidiary, or to keep track of LEIs that are about to lapse.

### Example from a real run

Run `dNoMxaynCe6Hx9DeS` on Apify on 4 October 2026, with this input:

```json
{
  "legalName": "Volvo",
  "countries": ["SE"],
  "onlyNew": true
}
```

It returned 20 records in 10 seconds of run time. The first three rows from the dataset, with some fields left out here to keep it short:

```json
[
  {
    "lei": "549300P5JZ7GDEJQ8R74",
    "legalName": "Volvo Lastvagnar Aktiebolag",
    "legalJurisdiction": "SE",
    "entityCategory": "GENERAL",
    "legalForm": { "code": "XJHM", "name": "Aktiebolag" },
    "entityStatus": "ACTIVE",
    "registeredAs": "556013-9700",
    "registrationStatus": "ISSUED",
    "lastUpdateDate": "2026-10-02T04:36:00Z",
    "nextRenewalDate": "2027-11-29T00:18:00Z"
  },
  {
    "lei": "549300VDEAR86G5V3S61",
    "legalName": "IF Metall Volvo Olofström",
    "legalJurisdiction": "SE",
    "entityCategory": "GENERAL",
    "legalForm": { "code": "1TN0", "name": "Ideell förening (som bedriver näringsverksamhet)" },
    "entityStatus": "ACTIVE",
    "registeredAs": "836200-5962",
    "registrationStatus": "ISSUED",
    "lastUpdateDate": "2026-09-21T06:19:00Z",
    "nextRenewalDate": "2027-09-24T08:04:00Z"
  },
  {
    "lei": "636700XHCLW8419O1812",
    "legalName": "Volvo Jubileumsstiftelse",
    "legalJurisdiction": "SE",
    "entityCategory": "GENERAL",
    "legalForm": { "code": "E9BI", "name": "stiftelse" },
    "entityStatus": "ACTIVE",
    "registeredAs": "802482-6037",
    "registrationStatus": "ISSUED",
    "lastUpdateDate": "2026-08-28T05:21:00Z",
    "nextRenewalDate": "2027-10-25T06:51:00Z"
  }
]
```

The same input run again a few seconds later (run `pPu58Id4kXVP3Xnku`) returned 0 records, since nothing had changed in between. See "Monitoring and scheduling".

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `leis` | array | | LEI codes to look up. Invalid codes (wrong length, characters or check digits) are skipped with a warning in the log. Up to 10 000 per run. |
| `legalName` | string | | Search term for the legal name. Matches names that contain the term, for example `Volvo` finds `Aktiebolaget Volvo` and `Volvo Car AB`. |
| `countries` | array | | Country of the legal address, ISO 3166 alpha-2 codes such as `SE`, `NO`, `DE`. |
| `entityStatus` | string | `ACTIVE` | `ACTIVE`, `INACTIVE` (the entity has ceased, for example after a merger) or `any`. |
| `registrationStatus` | string | `any` | `ISSUED` (current), `LAPSED` (not renewed in time), `RETIRED` or `any`. |
| `entityCategory` | string | `any` | `GENERAL`, `BRANCH`, `FUND`, `INTERNATIONAL_ORGANIZATION` or `any`. |
| `includeParents` | boolean | `false` | Adds `directParentLei` and `ultimateParentLei`. Costs up to two extra requests per record. |
| `maxResults` | integer | `50` | Maximum number of records, 1 to 10 000. |
| `onlyNew` | boolean | `false` | Return only records that are new or changed since earlier runs with the same input. See "Monitoring and scheduling". |

The filters combine, so `legalName` with `countries` searches within those countries. With empty input the actor returns the 50 most recently updated active records in the whole register, newest first (49 seconds of run time in a test on 4 October 2026, run `omfTkBCq9fdvq4U6k`), which is a quick way to see what the output looks like.

Example input: active Swedish entities with Volvo in the name, with parent LEIs.

```json
{
  "legalName": "Volvo",
  "countries": ["SE"],
  "entityStatus": "ACTIVE",
  "includeParents": true,
  "maxResults": 50
}
```

Example input: check a list of LEIs.

```json
{
  "leis": ["549300HGV012CNC8JD22", "5299003QF94FZCIIRP54"],
  "entityStatus": "any"
}
```

### Output

| Field | Description |
|---|---|
| `lei` | The LEI code |
| `legalName`, `legalNameLanguage` | Legal name as registered, and its language |
| `otherNames` | Other registered names, for example trading names or earlier names |
| `legalJurisdiction` | Jurisdiction the entity is registered under, for example `SE` or `US-DE` |
| `entityCategory` | `GENERAL`, `BRANCH`, `FUND` or another GLEIF category |
| `legalForm` | `code` (ISO 20275 ELF code) and `name` in the local language, for example `XJHM` and `Aktiebolag` |
| `entityStatus` | `ACTIVE` or `INACTIVE` |
| `legalAddress`, `headquartersAddress` | `lines`, `city`, `region`, `postalCode`, `country`. `null` when GLEIF has no address |
| `registeredAs` | The entity's number in its national register, for example the Swedish organisationsnummer |
| `registrationAuthority` | `id` (GLEIF RA code) and `name` of the register, for example Swedish Companies Registration Office |
| `registrationStatus` | `ISSUED`, `LAPSED`, `RETIRED` and a few rarer values |
| `initialRegistrationDate`, `lastUpdateDate`, `nextRenewalDate` | Dates of the LEI registration |
| `managingLou` | LEI of the issuer (Local Operating Unit) that manages the record |
| `bic` | BIC codes mapped to the LEI, empty when there are none |
| `directParentLei`, `ultimateParentLei` | Only with `includeParents`. `null` when the entity reports no parent or an exception |
| `source`, `license` | Attribution for the data |

```json
{
  "lei": "549300P5JZ7GDEJQ8R74",
  "legalName": "Volvo Lastvagnar Aktiebolag",
  "legalNameLanguage": "sv",
  "otherNames": [],
  "legalJurisdiction": "SE",
  "entityCategory": "GENERAL",
  "legalForm": { "code": "XJHM", "name": "Aktiebolag" },
  "entityStatus": "ACTIVE",
  "legalAddress": {
    "lines": ["C/O Volvo Lastvagnar Aktiebolag"],
    "city": "Göteborg",
    "region": "SE-O",
    "postalCode": "405 08",
    "country": "SE"
  },
  "headquartersAddress": {
    "lines": ["C/O Volvo Lastvagnar Aktiebolag"],
    "city": "Göteborg",
    "region": "SE-O",
    "postalCode": "405 08",
    "country": "SE"
  },
  "registeredAs": "556013-9700",
  "registrationAuthority": { "id": "RA000544", "name": "Swedish Companies Registration Office" },
  "registrationStatus": "ISSUED",
  "initialRegistrationDate": "2022-12-15T15:33:00Z",
  "lastUpdateDate": "2026-10-02T04:36:00Z",
  "nextRenewalDate": "2027-11-29T00:18:00Z",
  "managingLou": "549300O897ZC5H7CY412",
  "bic": [],
  "source": "GLEIF (Global Legal Entity Identifier Foundation)",
  "license": "CC0 1.0"
}
```

The run above had `includeParents` set to `false`, so the row has no parent fields. With `includeParents: true` each row also gets `directParentLei` and `ultimateParentLei`, filled with the parent's LEI or `null` when the entity reports no parent or an exception.

### Monitoring and scheduling

Set `onlyNew` to `true` to watch a set of LEIs or a search over time. The actor then remembers which record versions it has delivered for the same input, in a named key-value store in your Apify account (`nightwave-state-gleif-lei-lookup`, one record per input). A record version is the LEI together with its `lastUpdateDate`, so a record comes again when GLEIF publishes a change to it, for example a renewal, a new address or a status change to `LAPSED`. Each run returns and charges only records that are new or changed since earlier runs. The first run returns everything in the selection. A run without news finishes successfully with 0 rows.

With `onlyNew` a search is read with the most recently updated records first, in full pages of 200, and at most 10 000 records are read per run. Records already delivered do not count toward `maxResults`. When there are more new records than `maxResults`, the rest come in the next run.

`onlyNew` and `maxResults` are not part of the remembered input, so you can change them without starting over. Changing any other field starts a fresh state. To start over with the same input, delete the record in the key-value store.

Example: a daily check at 07:00 Swedish time of your counterparties' LEIs, which reports any LEI that was renewed, lapsed or changed. In Apify Console, open **Schedules**, create a schedule with the cron expression `0 7 * * *` and add this actor with the input below.

```json
{
  "leis": ["549300HGV012CNC8JD22", "5299003QF94FZCIIRP54"],
  "entityStatus": "any",
  "onlyNew": true
}
```

The same schedule through the Apify API:

```sh
curl -X POST "https://api.apify.com/v2/schedules?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"name": "daily-lei-check", "cronExpression": "0 7 * * *", "timezone": "Europe/Stockholm", "isEnabled": true, "isExclusive": true,
       "actions": [{"type": "RUN_ACTOR", "actorId": "nightwave-owner~gleif-lei-lookup",
                    "runInput": {"contentType": "application/json; charset=utf-8", "body": "<the input above as a JSON string>"}}]}'
```

The first run returns both records. Later runs return a record only on a day GLEIF has published a change to it.

### Good to know

- **Sole proprietors are always left out.** The register also holds LEIs of sole proprietors (category `SOLE_PROPRIETOR`), whose legal name and address are those of a private person. The actor drops these records before anything is stored, also when you ask for their LEI directly, and the log tells how many were left out. No names of people are returned.
- **GLEIF's rate limit is followed.** The [API documentation](https://documenter.getpostman.com/view/7679680/SVYrrxuU) sets the limit at 60 requests per minute per user. The actor sends at most one request per second. Names of legal forms and registration authorities come from GLEIF's own code lists, bundled with the actor, so they cost no extra requests. A search returns 200 records per request, so 10 000 records take about a minute. With `includeParents` each record with a reported parent needs up to two more requests, so 1 000 records with parents can take half an hour.
- **One search returns at most 10 000 records.** That is the limit of GLEIF's page based API. For larger sets, split the run by country, status or category.
- The legal name search matches names that contain the term. It does not correct spelling. Use the LEI code when you have it.
- Legal form and register names are looked up once per code in GLEIF's code lists and reused within the run.
- Requests are retried three times on network errors, rate limits (429) and server errors. A response in an unexpected format stops the run with a clear message instead of storing broken rows. A search without matches ends successfully with 0 rows.
- The API serves GLEIF's Golden Copy, which is published several times a day. A change made by an issuer usually shows up within a day.

### Data source and license

The data comes from the [GLEIF API](https://www.gleif.org/en/lei-data/gleif-api) (`https://api.gleif.org/api/v1`), which needs no key. GLEIF publishes LEI data under [Creative Commons CC0 1.0](https://www.gleif.org/en/meta/lei-data-terms-of-use), so it can be used, shared and resold without restriction. Every row still carries `source` and `license` so you can credit GLEIF.

This actor is not affiliated with or endorsed by GLEIF.

### Pricing

Pay per event: 0.002 USD per LEI record returned (event `lei-record`), which is 2.00 USD per 1 000 records. Platform usage is included, so you pay only per result. A search without matches costs nothing per record. `maxResults` caps how many records, and therefore how much, a run can charge.

Rows are delivered only after they have been charged. If you set a maximum cost per run (maxTotalChargeUsd), the run stops there and its status message says how many rows were delivered.

### Contact

Built and maintained by Nightwave AB. Questions, bugs and feature requests: kontakt@nightwave.se

### På svenska

Actorn slår upp och söker i GLEIF:s öppna register över LEI-koder (Legal Entity Identifier), den 20 tecken långa kod som identifierar bolag, fonder och andra juridiska personer i finansiella transaktioner. Ange LEI-koder eller sök på namn och land, och få en rad per juridisk person.

- Fält: juridiskt namn, andra namn, jurisdiktion, kategori, juridisk form (ELF-kod och namn), status, säte och huvudkontor, nationellt registreringsnummer (för svenska bolag organisationsnumret), registermyndighet, registreringsdatum, förnyelsedatum, BIC och, om du vill, LEI för direkt och yttersta moderbolag.
- Filter: LEI-koder, namn, land, status för bolaget och för registreringen samt kategori. Standard är 50 poster per körning, högst 10 000. Utan filter ges de 50 senast uppdaterade aktiva posterna i hela registret.
- Bevakning: med `onlyNew` kommer ihåg actorn vilka poster den redan har levererat för samma input (key-value store `nightwave-state-gleif-lei-lookup`). Varje körning levererar och debiterar bara poster som är nya eller har ändrats sedan förra körningen, till exempel en förnyad eller förfallen LEI. Lägg actorn på ett dagligt schema i Apify under Schedules, se avsnittet "Monitoring and scheduling".
- Enskilda näringsidkare tas alltid bort, eftersom namn och adress där är en privatpersons. Inga personnamn lämnas ut.
- Actorn följer GLEIF:s gräns på cirka 60 anrop per minut och skickar högst ett anrop per sekund.
- Källa: GLEIF (Global Legal Entity Identifier Foundation). Licens: CC0 1.0, fri att använda.
- Pris: 0,002 USD per LEI-post (2,00 USD per 1 000). Plattformsanvändningen ingår.
- Kontakt: kontakt@nightwave.se

# Actor input Schema

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

LEI codes to look up, 20 characters each, for example \["549300HGV012CNC8JD22"] (AB Volvo). Invalid codes are skipped with a warning in the log. With no LEI codes, name or country the actor lists the most recently updated records worldwide.

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

Search term for the legal name, for example "Volvo". Matches names that contain the term, so Volvo finds Aktiebolaget Volvo and Volvo Car AB.

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

Country of the legal address as ISO 3166 alpha-2 codes, for example \["SE", "NO"]. Empty means all countries.

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

ACTIVE for entities that exist, INACTIVE for entities that have ceased (for example after a merger), any for both. Defaults to ACTIVE.

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

ISSUED for LEIs that are renewed and current, LAPSED for LEIs past their renewal date, RETIRED for retired LEIs, any for all. Defaults to any. Use LAPSED to find counterparties whose LEI needs renewal.

## `entityCategory` (type: `string`):

Limit to one kind of entity, for example FUND. Defaults to any. Sole proprietors are never returned.

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

Adds the LEI of the direct and the ultimate parent, for example true. Costs up to two extra requests per record, so large runs take longer. Defaults to false.

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

Maximum number of records to return, for example 50. Each record is one billable result. 1 to 10 000, defaults to 50.

## `onlyNew` (type: `boolean`):

For scheduled runs. When true, records that an earlier run with the same input already delivered are skipped and not charged, so a daily run returns only LEIs that are new or that GLEIF has updated since the last run. The first run returns everything in the selection. Defaults to false.

## Actor input object example

```json
{
  "leis": [
    "549300HGV012CNC8JD22",
    "5299003QF94FZCIIRP54"
  ],
  "legalName": "Volvo",
  "countries": [
    "SE",
    "NO"
  ],
  "entityStatus": "ACTIVE",
  "registrationStatus": "LAPSED",
  "entityCategory": "FUND",
  "includeParents": true,
  "maxResults": 50,
  "onlyNew": true
}
```

# Actor output Schema

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

All rows produced by the run, as JSON. Open in Apify Console or download via the dataset API.

# 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": [],
    "legalName": "Volvo",
    "countries": [
        "SE"
    ],
    "entityStatus": "ACTIVE",
    "registrationStatus": "any",
    "entityCategory": "any",
    "includeParents": false,
    "maxResults": 50,
    "onlyNew": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("nightwave-owner/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": [],
    "legalName": "Volvo",
    "countries": ["SE"],
    "entityStatus": "ACTIVE",
    "registrationStatus": "any",
    "entityCategory": "any",
    "includeParents": False,
    "maxResults": 50,
    "onlyNew": False,
}

# Run the Actor and wait for it to finish
run = client.actor("nightwave-owner/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": [],
  "legalName": "Volvo",
  "countries": [
    "SE"
  ],
  "entityStatus": "ACTIVE",
  "registrationStatus": "any",
  "entityCategory": "any",
  "includeParents": false,
  "maxResults": 50,
  "onlyNew": false
}' |
apify call nightwave-owner/gleif-lei-lookup --silent --output-dataset

```

## MCP server setup

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