# European Company Data API - Firmographics (`nabeelbaghoor/european-company-data-api`) Actor

Search a European company database by country, registry id, industry code, website keywords, detected technologies, employee count and filed financials such as turnover and profit. Pay per result. Bring your own API key.

- **URL**: https://apify.com/nabeelbaghoor/european-company-data-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Lead generation
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$12.00 / 1,000 company results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## European Company Data API - Firmographics

Search a European company database and export the matches as clean rows. Filter by country, registration number, domain, city, municipality, region and postal code, by official industry code or the provider's own industry model, by keywords found on the company website or in its filed financial statements, by the technologies detected on its website, and by real numbers from filed accounts: employee count, employee growth, turnover, turnover growth and profit. You pay only for the companies you actually receive.

This actor is built for building territory and ideal customer profile lists in the Nordics and wider Europe, enriching a CRM with registry-grade company data, and pulling incremental updates as company records change.

### What you can do with it

- Build a target list of every company in a country above a turnover or headcount threshold.
- Find companies running a given technology on their website, in a chosen market.
- Look up companies in bulk by national registration number or by domain.
- Filter by growth: companies whose headcount or turnover rose by at least a set amount.
- Pull only what changed since a date, for an incremental sync rather than a full re-export.
- Export everything as JSON, CSV or Excel, or push it into a CRM or warehouse.

### Features

- Filters are built from the provider's own field-plus-operator grammar, so each input maps to exactly one documented filter, for example an employee minimum becomes `staff_number__gte`.
- List filters accept several values and match any of them, entered as a list, a comma list or a newline list.
- `rawFilters` reaches the provider's several hundred remaining fields and every operator, including the decimal maturity scores and geographic radius search.
- A run without a country filter is allowed but logged as a warning, because the provider recommends always setting one for speed.
- Optional field selection trims the response to the columns you need, which makes large exports noticeably faster.
- Offset pagination is walked automatically, advancing by the number of records actually returned so a short page can never skip a match.
- Registry, contact, digital, industry and financial fields are flattened into flat sortable columns, with numbers kept as numbers.
- Duplicate companies are removed across pages, keyed on provider id, registration number and domain, before anything is charged.
- The untouched provider payload is kept under `raw`, so nothing is lost.
- Access tokens are exchanged from your long-lived token, cached for their 12 hour lifetime and refreshed automatically, including one silent retry if a token expires mid-run.
- Rate limits are handled with retry-after aware backoff, and a run that hits a limit keeps everything already collected.
- Pay-per-result pricing with a hard result cap so a run can never surprise you.

### Input

| Field | Type | Description |
| --- | --- | --- |
| `country` | array | Two-letter country codes. Recommended on every run. |
| `companyName` / `companyNameContains` | string | Exact name, or a case-insensitive substring. |
| `businessId` / `domain` / `vid` | array | Direct lookup by registration number, domain or provider id. |
| `city` / `municipality` / `region` / `postal` / `visitingCity` | array | Location filters. |
| `industryCodes` / `customIndustry` | array | Official industry codes, or the provider's own labels. |
| `companyKeywords` / `websiteKeywords` / `financialStatementKeywords` | array | Keyword filters. |
| `webTechnologies` | array | Technologies detected on the company website. |
| `formOfCompany` / `status` | array | Legal form and registry status. |
| `registrationDateFrom` / `registrationDateTo` | string | Registration date range, as YYYY-MM-DD. |
| `modifiedSince` | string | Only records changed on or after this date. |
| `staffNumberMin` / `staffNumberMax` / `staffNumberGrowthMin` | integer | Employee count and growth. |
| `turnOverMin` / `turnOverMax` / `turnOverGrowthMin` | integer | Turnover and turnover growth. |
| `profitMin` / `profitMax` | integer | Reported profit range. |
| `rawFilters` | object | Any extra field and operator, merged last. |
| `fields` | array | Restrict the response to these provider fields. |
| `maxResults` | integer | Stop after this many companies (1 to 50,000). |
| `pageSize` | integer | Companies per API call (1 to 100). |
| `apiKey` | string | Your API token. Required, stored securely. |
| `apiKeyIsAccessToken` | boolean | The token is already an access token, so skip the exchange. |

At least one filter is required.

### Example output

Each dataset item is one company. Fields are populated where the provider has data, and the untouched payload is kept under `raw`:

```json
{
  "vid": "987654321",
  "businessId": "1234567-8",
  "name": "Example Logistiikka Oy",
  "alternativeNames": ["Example Logistics Ltd"],
  "status": "Active",
  "formOfCompany": "OY",
  "registrationDate": "2012-03-19",
  "foundationDate": "2012-02-28",
  "deregistrationDate": null,
  "country": "FI",
  "address": "Esimerkkikatu 12",
  "postal": "00100",
  "city": "Helsinki",
  "municipality": "Helsinki",
  "region": "Uusimaa",
  "visitingAddress": "Esimerkkikatu 12 A",
  "visitingCity": "Helsinki",
  "coordinates": { "lat": 60.1699, "lon": 24.9384 },
  "phone": "+358 9 5550188",
  "email": "info@example.fi",
  "domain": "example.fi",
  "website": "https://www.example.fi",
  "verifiedDomains": ["example.fi"],
  "linkedinId": "example-logistiikka",
  "twitterLink": null,
  "facebookLink": null,
  "industryCodes": ["52290"],
  "customIndustry": ["Freight forwarding"],
  "companyKeywords": ["logistics", "freight"],
  "technologies": ["HubSpot", "Cloudflare"],
  "staffNumber": 84,
  "staffNumberEstimate": 88,
  "staffNumberGrowth": 12,
  "turnOver": 18400000,
  "turnOverEstimate": 18900000,
  "turnOverGrowth": 9,
  "profit": 1240000,
  "totalAssets": 9800000,
  "totalEquity": 4100000,
  "totalLiabilities": 5700000,
  "digitality": 0.72,
  "marketility": 0.55,
  "sociality": 0.41,
  "alexaRankGlobal": 842910,
  "lastModified": "2026-07-28",
  "raw": { "business_id": "1234567-8", "company_name": "Example Logistiikka Oy" }
}
```

### Pricing and the credit model

This actor uses pay-per-result pricing. You are charged a fixed price for each company delivered to the dataset, after duplicates are removed. A search that matches nothing costs nothing. Set `maxResults` to cap how many rows a run can collect, and set a run spending limit as a second safety net. Your own provider plan meters its own quota separately.

### Bring your own API key

This actor connects to a third-party European company data provider (Vainu) on your behalf and requires your own provider API token. Create a token in the provider's platform and paste it into the `apiKey` input. It is stored securely and never logged, and the actor never ships with or shares credentials.

### Frequently asked questions

#### What data does this actor return?

Provider company id and national registration number, company name and alternative names, registry status and legal form, registration, foundation and deregistration dates, the registered and visiting addresses with city, municipality, region, postal code and coordinates, phone, email, domain, website and verified domains, LinkedIn, Twitter and Facebook links, official industry codes and the provider's own industry labels, company and website keywords, detected web technologies, employee count with the provider's estimate and growth, turnover with estimate and growth, profit, total assets, equity and liabilities, digital, marketing and social maturity scores, global website rank, and the date the record last changed. Every record also carries the untouched provider payload.

#### Which countries are covered?

The provider's registry coverage is strongest in the Nordics and the Netherlands and extends across Europe, with the exact set depending on your own subscription. Filter with `country` using two-letter codes. If a country is not licensed on your plan the provider says so in its error, which the actor surfaces verbatim.

#### How do the filter operators work?

Each input maps to one documented field-and-operator pair. A minimum becomes `__gte`, a maximum becomes `__lte`, a list becomes `__in`, and the name substring filter becomes `__icontains`. For anything not modelled as an input, `rawFilters` takes the raw field name with any operator: `__gt`, `__gte`, `__lt`, `__lte`, `__ne`, `__in`, `__contains`, `__icontains`, `__startswith` and `__geo_within_sphere`.

#### How do I filter on the decimal maturity scores?

The digitality, marketility and sociality scores run from 0 to 1, which cannot be typed into a whole-number input field. Put them in `rawFilters` instead, for example `{"digitality__gte": 0.8}`.

#### How do I pull only what changed?

Set `modifiedSince` to the date of your last export. That maps to the provider's core-data change timestamp, so a nightly run collects only the records that actually moved rather than re-downloading and re-charging for the whole list.

#### Why should I always set a country?

The provider says so explicitly: a query without a country filter searches the whole database and is much slower. The actor still runs without one and logs a warning, so an intentionally global search is possible, just slower.

#### What does the fields input do?

It restricts the response to the provider fields you name, which cuts response size and speeds up large exports. Leave it empty to get the provider's default field set. Note that a column not requested arrives empty in the output row, so only trim once you know which columns you need.

#### How does authentication work?

The provider issues a long-lived refresh token and short-lived access tokens. The actor exchanges your token for an access token, caches it for its 12 hour lifetime, and refreshes it automatically. If a token is rejected mid-run it is refreshed once and the request is retried. If you already hold an access token, turn on `apiKeyIsAccessToken` and the exchange is skipped.

#### How does the actor handle rate limits?

It throttles requests, honours the retry-after signal on a rate-limited response, and backs off exponentially. A response saying the plan does not license a field or country stops the run early and keeps everything already collected.

#### How am I charged?

You pay a fixed price per company returned to the dataset. Duplicates are removed before charging and empty runs cost nothing. Use `maxResults` and the run spending limit to control cost.

#### What output formats are available?

The dataset can be exported as JSON, CSV, Excel, HTML or RSS, or read through the API for pushing into a CRM or warehouse.

### Keyword map

european company data api, nordic company database api, finnish company data api, swedish company register api, company firmographics api, business register api, company financials api, turnover and profit data, company registration number lookup, nace industry code search, technographic data api europe, website technology detection data, b2b prospecting data europe, ideal customer profile list builder, company enrichment api, crm data enrichment europe, incremental company data sync, company employee count data, european b2b database, business id lookup api.

# Actor input Schema

## `country` (type: `array`):

Two-letter country codes, for example FI, SE, NO, DK, NL. The provider recommends always setting a country, because a search without one is much slower.

## `companyName` (type: `string`):

Match this company name exactly.

## `companyNameContains` (type: `string`):

Match company names containing this text, ignoring case.

## `businessId` (type: `array`):

National registration numbers to look up directly.

## `domain` (type: `array`):

Company website domains to look up directly.

## `vid` (type: `array`):

The provider's own company identifiers.

## `city` (type: `array`):

Registered city names.

## `municipality` (type: `array`):

Municipality names.

## `region` (type: `array`):

Region names.

## `postal` (type: `array`):

Postal codes.

## `visitingCity` (type: `array`):

Cities of the visiting address, which differs from the registered address for many companies.

## `industryCodes` (type: `array`):

Official industry classification codes, for example NACE codes.

## `customIndustry` (type: `array`):

The provider's own industry labels, which are more granular than official codes.

## `companyKeywords` (type: `array`):

Keywords describing what the company does.

## `websiteKeywords` (type: `array`):

Keywords found on the company website.

## `webTechnologies` (type: `array`):

Technologies detected on the company website.

## `financialStatementKeywords` (type: `array`):

Keywords found in filed financial statements.

## `formOfCompany` (type: `array`):

Legal form of the company, for example a limited company or a partnership.

## `status` (type: `array`):

Registry status values to include, for example active.

## `registrationDateFrom` (type: `string`):

Only companies registered on or after this date, as YYYY-MM-DD.

## `registrationDateTo` (type: `string`):

Only companies registered on or before this date, as YYYY-MM-DD.

## `modifiedSince` (type: `string`):

Only companies whose core data changed on or after this date, as YYYY-MM-DD. Use this to pull an incremental update instead of a full list.

## `staffNumberMin` (type: `integer`):

Only companies with at least this many employees.

## `staffNumberMax` (type: `integer`):

Only companies with at most this many employees.

## `staffNumberGrowthMin` (type: `integer`):

Only companies whose employee count grew by at least this much.

## `turnOverMin` (type: `integer`):

Only companies with at least this much annual turnover.

## `turnOverMax` (type: `integer`):

Only companies with at most this much annual turnover.

## `turnOverGrowthMin` (type: `integer`):

Only companies whose turnover grew by at least this much.

## `profitMin` (type: `integer`):

Only companies reporting at least this much profit.

## `profitMax` (type: `integer`):

Only companies reporting at most this much profit.

## `rawFilters` (type: `object`):

Any additional filter, merged over the ones above, written as the provider's field name plus an operator suffix. Use this for the decimal scores, which cannot be entered as whole numbers above: {"digitality\_\_gte": 0.8}, {"marketility\_\_gte": 0.5}, {"sociality\_\_gte": 0.5}. Other examples: {"turn\_over\_\_gt": 500000}, {"city\_\_startswith": "Hel"}, {"alexa\_rank\_global\_\_lte": 100000}. Operators are \_\_gt, \_\_gte, \_\_lt, \_\_lte, \_\_ne, \_\_in, \_\_contains, \_\_icontains, \_\_startswith and \_\_geo\_within\_sphere.

## `fields` (type: `array`):

Restrict the response to these provider field names, which makes large exports faster. Leave empty for the provider's default field set.

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

Stop after this many company records (1 to 50,000). You are charged per result returned.

## `pageSize` (type: `integer`):

How many companies to request per API call (1 to 100). Larger pages mean fewer calls.

## `apiKey` (type: `string`):

Your own API token for the data provider. Required. This is the long-lived refresh token, which the actor exchanges for a short-lived access token automatically. Stored securely and never logged.

## `apiKeyIsAccessToken` (type: `boolean`):

Turn this on if the value above is already a short-lived access token rather than a refresh token. The actor will then use it as is and skip the exchange.

## Actor input object example

```json
{
  "country": [
    "FI"
  ],
  "rawFilters": {},
  "maxResults": 100,
  "pageSize": 100,
  "apiKeyIsAccessToken": false
}
```

# 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 = {
    "country": [
        "FI"
    ],
    "rawFilters": {},
    "maxResults": 100,
    "pageSize": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/european-company-data-api").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 = {
    "country": ["FI"],
    "rawFilters": {},
    "maxResults": 100,
    "pageSize": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/european-company-data-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "country": [
    "FI"
  ],
  "rawFilters": {},
  "maxResults": 100,
  "pageSize": 100
}' |
apify call nabeelbaghoor/european-company-data-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nabeelbaghoor/european-company-data-api",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QaOEwYgchisTv5cPB/builds/9I0ZiJqGD6fiaagNK/openapi.json
