Company Registry API: Lookup by LEI, VAT Number, CIK or Org ID
Pricing
from $2.80 / 1,000 gleif lei matches
Company Registry API: Lookup by LEI, VAT Number, CIK or Org ID
Company lookup by LEI, VAT number, CIK, Norwegian or Finnish business ID, or France SIREN for a list of identifiers, without an API key. Verify a vendor before paying an invoice, screen a CRM list, clean a column of mixed company IDs. GLEIF, SEC EDGAR, Brønnøysund, PRH, SIRENE, VIES VAT validation.
Pricing
from $2.80 / 1,000 gleif lei matches
Rating
0.0
(0)
Developer
Adrian Voss
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Company Registry Unified Lookup
Give it a company identifier — an LEI code, a stock ticker or SEC CIK, a Norwegian organization number, a Finnish business ID, a French SIREN or SIRET, or an EU VAT number — and it routes the lookup automatically to the matching official registry: GLEIF for LEIs, SEC EDGAR for U.S. tickers/CIKs, Brønnøysund for Norway, PRH for Finland, SIRENE for France, or EU VIES for VAT numbers. You get one row back per identifier with a normalized legal name, status, and jurisdiction, plus registry-specific detail. No API keys, no scraping — every one of the six sources is an official, free, public registry API, queried directly.
Make.com: copy this scenario to turn a company domain into a one-paragraph account-research brief alongside hiring, ad-spend and tech-stack data.
Who it's for
The accountable_eel catalogue sells company intelligence columns for outbound. Each actor takes a list of domains or company identifiers and returns one flat, stably-named row per input — firmographics, registry IDs, tech stack, email route, hiring activity — the shape a Clay table, an n8n workflow, or an AI agent can consume without post-processing. Pricing is pay-per-event and per-domain: a few tenths of a cent for a row that was actually found, and nothing for a miss, so a list that doesn't enrich costs you next to nothing. Where an official source exists — VIES, GLEIF, SEC EDGAR, Brønnøysund, PRH, RDAP — it is queried directly instead of scraped. No seat licence, no monthly minimum, no credit system to decode.
For this actor, the input identifier's own shape — 20 characters ending in two digits, a bare ticker, nine digits, a hyphenated Finnish ID, a checksum-valid SIREN/SIRET, a two-letter country prefix — is what decides whether GLEIF, SEC EDGAR, Brønnøysund, PRH, SIRENE, or VIES gets called, so you can paste a mixed list of LEIs, tickers, and VAT numbers without sorting it first.
Why this one
- Shape-based auto-routing. You don't pick which of six registries to check — the identifier's own format decides, before any network call is made.
- One input field for six identifier types. LEI, SEC ticker/CIK, Norwegian org number, Finnish business ID, French SIREN/SIRET, EU VAT number — mixed lists work in a single run.
- Almost always one network call per identifier. A shape check runs first, so a registry that clearly doesn't match the identifier's format is never queried, and never billed.
- Same field names regardless of source. Legal name, status, and jurisdiction come back in a consistent shape whether the answer came from GLEIF, EDGAR, Brønnøysund, PRH, SIRENE, or VIES.
- No API keys, no scraping. All six sources are official, free, public registry APIs — nothing to sign up for, nothing that can get blocked as a bot.
What you get
Every row carries these fields regardless of which registry matched:
| Field | Type | Description |
|---|---|---|
query | string | The identifier exactly as submitted |
found | boolean | true if any of the six registries returned a match |
status | string | "OK" on a match, or a short reason string on a miss |
sourcesFound | array of strings | Which registry keys (below) actually returned data |
sourcesTried | array of strings | Every registry key considered for this identifier — each source checks the identifier's shape first, so this reflects which sources were shape-eligible, not necessarily which fired a network request |
scrapedAt | ISO 8601 datetime | When the lookup ran |
Then one object per registry — null if the identifier's shape doesn't match that
registry's format, or if the shape matches but no record was found:
lei — GLEIF LEI Registry match
| Field | Type | Description |
|---|---|---|
lei | string | The 20-character LEI code |
legalName | string | null | Registered legal entity name |
status | string | null | LEI record status (e.g. ISSUED) |
jurisdiction | string | null | Registered jurisdiction code |
country | string | null | Country of the legal address |
secEdgar — SEC EDGAR match
| Field | Type | Description |
|---|---|---|
cik | string | Zero-padded 10-digit SEC Central Index Key |
name | string | Registered company name |
tickers | array of strings | Ticker symbols on file for this filer |
sicDescription | string | null | SEC industry classification (SIC) description |
stateOfIncorporation | string | null | State/jurisdiction of incorporation |
noRegistry — Brønnøysund (Norway) match
| Field | Type | Description |
|---|---|---|
organizationNumber | string | 9-digit Norwegian organization number |
name | string | null | Registered entity name |
organizationForm | string | null | Legal form (e.g. AS, ENK) |
industryDescription | string | null | Primary industry code description |
fiRegistry — PRH (Finland) match
| Field | Type | Description |
|---|---|---|
businessId | string | Finnish business ID (NNNNNNN-N) |
name | string | null | Registered entity name |
companyForm | string | null | Legal form description |
mainBusinessLine | string | null | Primary business line description |
frRegistry — SIRENE (France) match
| Field | Type | Description |
|---|---|---|
organizationNumber | string | 9-digit SIREN of the company |
siret | string | null | 14-digit SIRET: the head office for a SIREN or VAT input, the exact establishment for a SIRET input |
name | string | null | Registered name |
status | string | null | ACTIVE or CEASED (the company) |
establishmentStatus | string | null | ACTIVE or CEASED for the establishment. Only present on a SIRET input |
country | string | Always FR |
address | string | null | Full address of the establishment in siret, postcode and commune included |
latitude, longitude | number | null | Coordinates of that establishment |
incorporationDate | string | null | Company creation date (YYYY-MM-DD), not the head office's opening date |
legalFormCode | string | null | INSEE legal-form code (e.g. 5599). The API sends the code only, not a label |
nafCode | string | null | Primary activity, NAF rev. 2 (e.g. 70.10Z) |
establishmentCount | number | null | Establishments ever registered, closed ones included |
openEstablishmentCount | number | null | Establishments currently open |
euVat — EU VIES VAT Registry match
| Field | Type | Description |
|---|---|---|
vatNumber | string | null | The VAT number as confirmed by VIES |
countryCode | string | 2-letter EU country code |
name | string | null | Registered name, if the member state publishes it |
address | string | null | Registered address, if the member state publishes it |
Not every member state publishes name and address through VIES — some return only a
valid/invalid flag, in which case name and address come back null even though
found is true.
France: SIREN, SIRET and FR VAT numbers
A checksum-valid 9-digit SIREN, 14-digit SIRET, or a French VAT number
(FR + 2-character key + SIREN) is looked up in the French company registry
(Recherche d'entreprises, built on INSEE's
SIRENE database). Spaces and dots as printed on French invoices are fine
(552 032 534, 552.032.534).
{"companyCodes": ["552032534", "55203253400679", "FR27552032534"]}
One row per identifier. For the SIREN 552032534:
{"query": "552032534","found": true,"status": "OK","frRegistry": {"organizationNumber": "552032534","siret": "55203253400703","name": "DANONE","status": "ACTIVE","country": "FR","address": "59-61 RUE LA FAYETTE 75009 PARIS","latitude": 48.8763540066087,"longitude": 2.34353640229216,"incorporationDate": "1955-01-01","legalFormCode": "5599","nafCode": "70.10Z","establishmentCount": 19,"openEstablishmentCount": 3},"sourcesFound": ["frRegistry"]}
- A SIREN identifies the company, a SIRET one establishment. Give a SIRET and the
siret,address, coordinates andestablishmentStatusare that establishment's, not the head office's;organizationNumber,name,nafCodeand the counts stay the company's. - The identifier is checked before anything is called. A number that fails the SIREN/SIRET checksum, or a VAT number whose key doesn't match its SIREN, never reaches the registry, so a typo costs nothing and is reported as not found.
- A French VAT number also runs the EU VIES check. Both registries answer, so one
FR…input that is found in both is billed for both (euVatandfrRegistry). Usecolumnsto keep onlyfrRegistryif you want the registry data alone. legalFormCodeis a code, not a label. The registry sends the INSEE legal-form code only (5599,5710, …); this actor does not translate it.- Lookup by company name is not offered. The registry's name search is fuzzy (a search for "danone" also returns an unrelated person's sole proprietorship), which cannot be auto-routed from the shape of an input the way an identifier can.
Price
- GLEIF LEI match: $5.6 per 1,000 company codes
- SEC EDGAR match: $5.6 per 1,000 company codes
- Brønnøysund (Norway) match: $5.6 per 1,000 company codes
- PRH (Finland) match: $5.6 per 1,000 company codes
- EU VIES VAT match: $5.6 per 1,000 company codes
- SIRENE (France) match: $5.6 per 1,000 company codes
Plus a $0.00005 start fee per run. Each event above is billed independently, only when it actually returns data — misses (found:false) are never charged.
That's $0.0056 per registry matched at the FREE tier ($0.0028 on GOLD), plus a $0.00005 per
run start fee. This is a composite actor, so billing is per source that returns data —
but because every source is shape-gated, a given identifier almost never matches more
than one registry. There are two exceptions. A bare 9-digit input is checked against
Brønnøysund, SEC EDGAR, and, if it passes the SIREN checksum, the French registry (the SEC
branch almost always comes back null for a real Norwegian number; a Norwegian number that
also happens to be a live SIREN would match both and be billed $0.0112 instead of
$0.0056). And a French VAT number (FR…) is answered by both VIES and the French
registry, so it is billed for both: $0.0112. Every other identifier shape reaches exactly
one registry. Use columns to keep only the registries you want.
1,000 identifiers through this actor: ~$5.60 if every one is found and matches exactly one registry, which is the common case. The same 1,000 rows through a credit-based enrichment platform: $80–$400.
How to use
- In the Apify Console. Open the actor page and click Start — the
companyCodesfield is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found. - Via the API. Call it directly with a POST request — no Console needed once you have an API token:
curl "https://api.apify.com/v2/acts/accountable_eel~company-registry-unified-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"companyCodes":["5493001KJTIIGC8Y1R12"]}'
- On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.
- Paste your identifiers into
companyCodes— one per line, mixed types are fine. - Turn on
testRunto check the first 5 against your list before running the full batch. - Run the actor. Each identifier gets shape-checked against all six formats, and only the registries it plausibly matches get queried.
- Read the dataset: one row per identifier,
found: truerows carry data in the matching registry field,found: falserows are still there for completeness but were never charged. - If you only care about certain registries, set
columnsto that subset — the actor skips querying (and billing for) any registry you didn't select.
Input
{"companyCodes": ["5493001KJTIIGC8Y1R12"]}
One code per line — an LEI code, a stock ticker or SEC CIK, a Norwegian org number, a Finnish business ID, a French SIREN or SIRET, or an EU VAT number. Routed automatically to the matching registry. Accepted formats: 5493001KJTIIGC8Y1R12, AAPL, 923609016, 0112038-9, IE6388047V, 552032534, FR27552032534.
{"companyCodes": ["5493001KJTIIGC8Y1R12"],"testRun": false,"onlyFound": false,"maxConcurrency": 5}
companyCodes is a list of identifiers — mix and match freely: an LEI
(5493001KJTIIGC8Y1R12), a stock ticker (AAPL) or SEC CIK, a 9-digit Norwegian org
number (923609016), a Finnish business ID (0112038-9), a French SIREN
(552032534) or SIRET, or an EU VAT number (IE6388047V). One dataset row is returned per identifier; rows with "found": false
are never charged. Turn on testRun to try your list against just the first 5
identifiers before running the full batch. Optional includeKeywords /
excludeKeywords filter rows by content, maxResults caps the run early, and columns
lets you pick which of the six registries to include.
Sample output
| query | found | status | lei | secEdgar | noRegistry | fiRegistry | euVat | frRegistry | scrapedAt |
|---|---|---|---|---|---|---|---|---|---|
| 5493001KJTIIGC8Y1R12 | true | OK | {"lei":"5493001KJTIIGC8Y1R12","legalName":"Bloomberg Finance L.P.","status":"ACTIVE","jurisdiction":"US-DE","country":"US"} | <brønnøysund (norway) match> | <prh (finland) match> | <sirene (france) match> | 2026-10-04T06:10:12.808Z |
One row per identifier, for example:
{"query": "5493001KJTIIGC8Y1R12","found": true,"status": "OK","lei": {"lei": "5493001KJTIIGC8Y1R12","legalName": "APPLE INC.","status": "ISSUED","jurisdiction": "US-CA","country": "US"},"secEdgar": null,"noRegistry": null,"fiRegistry": null,"euVat": null,"sourcesFound": ["lei"],"sourcesTried": ["lei", "secEdgar", "noRegistry", "fiRegistry", "euVat"],"scrapedAt": "2026-08-21T10:00:00.000Z"}
Each registry that the identifier's shape doesn't match returns null immediately
without a network call. An identifier that matches no registry's format, or matches the
shape but isn't found in that registry, still gets a row ("found": false), so you
always get one row per input — but you're never charged for those.
Use it from Clay, n8n, Make, or an AI agent
This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.
curl "https://api.apify.com/v2/acts/accountable_eel~company-registry-unified-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \-X POST \-H "Content-Type: application/json" \-d '{"companyCodes":["5493001KJTIIGC8Y1R12"]}'
n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~company-registry-unified-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"companyCodes":["5493001KJTIIGC8Y1R12"]} (swap in an expression from an earlier node for a real value).
Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~company-registry-unified-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"companyCodes":["{{company code}}"]}, mapping the row's company code into the companyCodes array.
MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Company Registry API: Verify LEI, VAT, CIK, France SIREN" — the agent will find and run this actor.
Tips
- Narrow with
columnsif you only care about one or two registries. Unselected registries are neither queried nor billed, so this is a real way to cut cost, not just a display filter. - Don't pre-sort your list by identifier type. The whole point of this actor is that
mixed lists work — an LEI, a ticker, and a VAT number can sit in the same
companyCodesarray. - Ticker resolution depends on SEC's own mapping, refreshed at actor startup. A
ticker that was delisted or renamed since the last refresh may resolve to
"found": false"even if the company still exists. - Run
testRunfirst on an unfamiliar list. It's the cheapest way to confirm your identifiers are shaped the way you think they are before committing to the full batch. - A bare 9-digit number can be checked against up to three registries. If you have a
list of purely Norwegian org numbers, expect the
secEdgarfield to come backnullon nearly every row — that's the SEC branch correctly finding nothing, not a bug. About one Norwegian number in ten also passes the SIREN checksum and is looked up in France too; that returns nothing unless it happens to be a real SIREN, in which casesourcesFoundlists both registries. If your list is only Norwegian, setcolumnstonoRegistry.
vs. alternatives
| What it costs | What you get | Trade-off | |
|---|---|---|---|
This actor (company-registry-unified-lookup) | $0.0056 per registry matched (FREE tier, $0.0028 on GOLD), $0.00005 actor start, nothing for a miss | One row per identifier — legal name, status, and jurisdiction from whichever of six official registries (GLEIF, SEC EDGAR, Brønnøysund, PRH, SIRENE, EU VIES) matches the identifier's shape | Six registries, but each identifier almost always routes to the one it actually matches by shape — it won't find a company you only know by name, and it doesn't cover registries outside these countries/schemes |
| Clay | $0.08–$0.40 per enriched row in credits, on top of a seat | A whole enrichment workspace — waterfalls across dozens of providers, plus the table and the sequencing around it | If you want one place that does everything and you're not counting rows, that's Clay. This is one column, priced per column, callable from Clay via its HTTP step. |
| The official portals (GLEIF, EDGAR, Brønnøysund, PRH, VIES) directly | Free | The same data, from the same source | It's the same source — this actor exists for the batch: identifiers in, rows out, with the right registry picked automatically and retries handled. One identifier, once? Use the portal. |
| Doing it yourself | Your time + six different APIs, six different auth/rate-limit/response shapes, and the shape-detection logic to route each identifier correctly | The same data | This actor is that routing logic and those six integrations, already written and already handling the edge cases (delisted tickers, VIES member states that don't publish name/address, the 9-digit overlap) |
Prices for third-party tools are their published list prices as of August 2026 and are not tracked here — check the vendor before relying on the comparison.
FAQ
What happens if an identifier doesn't match any registry's shape, or matches but isn't
found?
It's still returned as a row, with "found": false and every registry field null.
Neither case is billed — you only pay for a registry that actually returned data.
How does the actor decide which registry to check?
Purely by the identifier's shape: 20-character alphanumeric strings are tried as an
LEI, all-letter strings as a ticker, all-digit strings as an SEC CIK or (if exactly 9
digits) also as a Norwegian org number, NNNNNNN-N as a Finnish business ID, a 9-digit
or 14-digit number that passes the SIREN/SIRET checksum as a French company, and a
2-letter country prefix followed by digits/letters as an EU VAT number. Most inputs
only match one shape, so only one registry is ever actually called.
Why does a 9-digit number sometimes get checked against more than one registry? A bare 9-digit string is a plausible Norwegian organization number, also technically fits the SEC CIK pattern (which allows up to 10 digits), and is a French SIREN whenever it passes the SIREN checksum. There's no reliable way to distinguish them by digits alone, so all the plausible ones are tried — in practice, real SEC CIKs are far smaller once zero-padded, so the SEC branch almost always returns null for a genuine Norwegian number, and the French branch only answers if the number is a real SIREN.
Do I need API keys for any of the six registries? No. GLEIF, SEC EDGAR, Brønnøysund, PRH, SIRENE, and EU VIES are all free and public — none of them requires credentials on your end, and the actor doesn't need any either.
Are stock ticker lookups reliable, and how fresh is the ticker list?
Tickers are resolved against SEC's own ticker-to-CIK mapping, refreshed once at actor
startup. A ticker not in SEC's current listing — delisted, foreign-only, or a typo —
resolves to "found": false" for the secEdgar field rather than a guess.
Does this route through a proxy, and will a large batch get rate-limited?
No proxy — this actor talks to each registry's public API directly rather than
scraping, so there's nothing to route through Apify Proxy for. maxConcurrency
controls how many identifiers are processed in parallel; lower it if you see failed
requests on a very large batch, since these are still live third-party APIs with their
own fair-use limits. The French registry does not publish its limit in its response
headers, so the actor paces those requests itself (at most 5 per second, whatever
maxConcurrency is) and retries a 429 or a 5xx up to three times. If it still can't get an
answer, the row comes back with the status REQUEST_FAILED rather than NOT_FOUND, and
is not charged.
Is this personal data under GDPR? The fields returned here are public company-registration facts — legal entity name, status, jurisdiction, registry ID — published by government or regulatory registries, not personal data about individuals. If your own use of the output involves EU residents' data elsewhere in your pipeline, that's a question for your own DPO, not something this actor's output introduces on its own.
Can I schedule this to run automatically, and can an AI agent call it directly? Yes to both. Apify's built-in Scheduler can re-run this actor on a cron schedule against a saved input (useful for periodically re-checking a vendor or counterparty list), and because it exposes a synchronous HTTP endpoint, any MCP client with the Apify MCP server connected can find and run it by name — see the integrations section above.
Related actors
- EU VAT Validator — single-purpose VIES lookup, if VAT numbers are all you need
- GLEIF LEI Lookup — single-purpose LEI registry lookup
- SEC EDGAR Company Lookup — single-purpose ticker/CIK lookup against SEC EDGAR