Company Registry API: Lookup by LEI, VAT Number, CIK or Org ID avatar

Company Registry API: Lookup by LEI, VAT Number, CIK or Org ID

Pricing

from $2.80 / 1,000 gleif lei matches

Go to Apify Store
Company Registry API: Lookup by LEI, VAT Number, CIK or Org ID

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

Adrian Voss

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

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:

FieldTypeDescription
querystringThe identifier exactly as submitted
foundbooleantrue if any of the six registries returned a match
statusstring"OK" on a match, or a short reason string on a miss
sourcesFoundarray of stringsWhich registry keys (below) actually returned data
sourcesTriedarray of stringsEvery 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
scrapedAtISO 8601 datetimeWhen 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

FieldTypeDescription
leistringThe 20-character LEI code
legalNamestring | nullRegistered legal entity name
statusstring | nullLEI record status (e.g. ISSUED)
jurisdictionstring | nullRegistered jurisdiction code
countrystring | nullCountry of the legal address

secEdgar — SEC EDGAR match

FieldTypeDescription
cikstringZero-padded 10-digit SEC Central Index Key
namestringRegistered company name
tickersarray of stringsTicker symbols on file for this filer
sicDescriptionstring | nullSEC industry classification (SIC) description
stateOfIncorporationstring | nullState/jurisdiction of incorporation

noRegistry — Brønnøysund (Norway) match

FieldTypeDescription
organizationNumberstring9-digit Norwegian organization number
namestring | nullRegistered entity name
organizationFormstring | nullLegal form (e.g. AS, ENK)
industryDescriptionstring | nullPrimary industry code description

fiRegistry — PRH (Finland) match

FieldTypeDescription
businessIdstringFinnish business ID (NNNNNNN-N)
namestring | nullRegistered entity name
companyFormstring | nullLegal form description
mainBusinessLinestring | nullPrimary business line description

frRegistry — SIRENE (France) match

FieldTypeDescription
organizationNumberstring9-digit SIREN of the company
siretstring | null14-digit SIRET: the head office for a SIREN or VAT input, the exact establishment for a SIRET input
namestring | nullRegistered name
statusstring | nullACTIVE or CEASED (the company)
establishmentStatusstring | nullACTIVE or CEASED for the establishment. Only present on a SIRET input
countrystringAlways FR
addressstring | nullFull address of the establishment in siret, postcode and commune included
latitude, longitudenumber | nullCoordinates of that establishment
incorporationDatestring | nullCompany creation date (YYYY-MM-DD), not the head office's opening date
legalFormCodestring | nullINSEE legal-form code (e.g. 5599). The API sends the code only, not a label
nafCodestring | nullPrimary activity, NAF rev. 2 (e.g. 70.10Z)
establishmentCountnumber | nullEstablishments ever registered, closed ones included
openEstablishmentCountnumber | nullEstablishments currently open

euVat — EU VIES VAT Registry match

FieldTypeDescription
vatNumberstring | nullThe VAT number as confirmed by VIES
countryCodestring2-letter EU country code
namestring | nullRegistered name, if the member state publishes it
addressstring | nullRegistered 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 and establishmentStatus are that establishment's, not the head office's; organizationNumber, name, nafCode and 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 (euVat and frRegistry). Use columns to keep only frRegistry if you want the registry data alone.
  • legalFormCode is 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

  1. In the Apify Console. Open the actor page and click Start — the companyCodes field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. 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"]}'
  3. 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.
  1. Paste your identifiers into companyCodes — one per line, mixed types are fine.
  2. Turn on testRun to check the first 5 against your list before running the full batch.
  3. Run the actor. Each identifier gets shape-checked against all six formats, and only the registries it plausibly matches get queried.
  4. Read the dataset: one row per identifier, found: true rows carry data in the matching registry field, found: false rows are still there for completeness but were never charged.
  5. If you only care about certain registries, set columns to 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

queryfoundstatusleisecEdgarnoRegistryfiRegistryeuVatfrRegistryscrapedAt
5493001KJTIIGC8Y1R12trueOK{"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 columns if 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 companyCodes array.
  • 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 testRun first 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 secEdgar field to come back null on 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 case sourcesFound lists both registries. If your list is only Norwegian, set columns to noRegistry.

vs. alternatives

What it costsWhat you getTrade-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 missOne 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 shapeSix 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 seatA whole enrichment workspace — waterfalls across dozens of providers, plus the table and the sequencing around itIf 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) directlyFreeThe same data, from the same sourceIt'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 yourselfYour time + six different APIs, six different auth/rate-limit/response shapes, and the shape-detection logic to route each identifier correctlyThe same dataThis 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.