# Belgium KBO Company Registry (New Companies, NACE, Addresses) (`goobertje/belgium-kbo-company-registry`) Actor

Look up Belgian companies from the official KBO/BCE public search by enterprise number, or discover new companies by start date, NACE code and postcode. Returns legal form, status, address and activities. Delta mode returns only companies not seen before.

- **URL**: https://apify.com/goobertje/belgium-kbo-company-registry.md
- **Developed by:** [goober](https://apify.com/goobertje) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 company scrapeds

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

## Belgian company data API: KBO/BCE lookup and new-company feed

Find out who is behind a Belgian enterprise number, or get a list of newly registered Belgian companies in your sector and region. For each company you get legal name, legal form, status, start date, registered address and NACE-BEL activities from the official KBO/BCE register (Kruispuntbank van Ondernemingen / Banque-Carrefour des Entreprises). Built for sales teams, KYB/onboarding checks, data teams and AI agents.

### Why use this Actor

- Official source: the FPS Economy's KBO/BCE Public Search, not a third-party copy.
- Two modes: look up known enterprise numbers, or discover companies by NACE-BEL code, postal code or name.
- Delta mode: schedule it weekly and receive (and pay for) only companies you have not received before.
- Plain HTTP, no proxies, no browser, no login. About 40 companies per minute.
- Every field comes from the register. Unknown values are `null`, nothing is guessed.

### Quick start

Click **Start** with the prefilled input. It looks up three well-known enterprises:

```json
{
  "enterpriseNumbers": ["0403.199.702", "0202.239.951", "0200.065.765"],
  "maxItems": 3
}
```

In about 4 seconds you get 3 dataset items (BNP Paribas Fortis, Proximus, Veneco) with name, legal form, address and NACE activities.

Weekly feed of new IT companies in Ghent:

```json
{
  "naceCodes": ["62.100", "62.200"],
  "postalCodes": ["9000", "9030", "9040", "9050"],
  "startedWithinDays": 14,
  "onlyNewCompanies": true,
  "stateStoreName": "kbo-it-ghent",
  "maxItems": 200
}
```

### What you get

| Field | Meaning |
|---|---|
| `enterpriseNumber`, `status`, `startDate` | Number (0000.000.000), Active/Stopped, enterprise start date (ISO) |
| `name`, `abbreviation`, `names[]` | Legal name, abbreviation, all names with language and date |
| `legalForm`, `legalFormSince`, `entityType` | Legal form (KBO English wording), legal person or natural person |
| `address` | Registered seat: street, postalCode, city, since |
| `phone`, `email`, `website`, `capitalEur` | When KBO has them, else `null` |
| `activities[]` | NACE-BEL code, description, VAT/NSSO, version 2025/2008/2003, start date |
| `characteristics[]`, `authorisations[]` | Employer, VAT liable, contracting authority, licences |
| `establishments[]` | Optional: branch units with number, name, start date, address |
| `functions[]` | Optional: directors and other functions (personal data, see Legal) |
| `gazettePublicationsUrl`, `annualAccountsUrl` | Links as given by KBO (not crawled) |
| `kboDataDate`, `scrapedAt` | Date of the KBO database situation, your scrape time |

Real sample item from a discovery run:

```json
{
  "enterpriseNumber": "0542.874.950",
  "sourceUrl": "https://kbopub.economie.fgov.be/kbopub/toonondernemingps.html?lang=en&ondernemingsnummer=0542874950",
  "status": "Active",
  "juridicalSituation": "Normal situation",
  "juridicalSituationSince": "2013-12-10",
  "startDate": "2013-12-10",
  "name": "AED SICAD-SIGGIS",
  "abbreviation": null,
  "names": [{ "kind": "name", "value": "AED SICAD-SIGGIS", "language": "nl", "since": "2013-12-10" }],
  "entityType": "Legal person",
  "legalForm": "Company or association without legal personality",
  "legalFormSince": "2013-12-10",
  "address": { "street": "Bisdomplein 3", "postalCode": "9000", "city": "Gent", "since": "2021-12-27" },
  "phone": null,
  "fax": null,
  "email": null,
  "website": null,
  "establishmentCount": 0,
  "capitalEur": null,
  "annualAssembly": null,
  "fiscalYearEnd": null,
  "characteristics": [{ "name": "Subject to VAT", "since": "2014-01-01" }],
  "authorisations": [],
  "activities": [
    { "classification": "VAT", "naceVersion": "2025", "code": "62.100", "description": "Computer programming activities", "since": "2025-01-01" },
    { "classification": "VAT", "naceVersion": "2025", "code": "62.200", "description": "Computer consultancy and computer facilities management activities", "since": "2025-01-01" }
  ],
  "functions": null,
  "establishments": null,
  "establishmentsTruncated": null,
  "gazettePublicationsUrl": "https://www.ejustice.just.fgov.be/cgi_tsv/list.pl?language=fr&btw=0542874950&page=1&view_numac=0542874950#SUM",
  "annualAccountsUrl": "https://consult.cbso.nbb.be/consult-enterprise/0542874950",
  "kboDataDate": "2026-10-17",
  "scrapedAt": "2026-10-18T22:22:11.341617Z"
}
```

### Modes and filters

1. **Lookup**: `enterpriseNumbers` in any format (`0403.199.702`, `BE0403199702`). Numbers with a wrong check digit are ignored locally; numbers not in the register are skipped.
2. **Discovery by activity**: `naceCodes` + `postalCodes` (NACE-BEL 2025). Matches the registered seat or any establishment at that postal code.
3. **Discovery by name**: `searchTerm` (+ optional `searchPostalCode`), phonetic, includes old names.
4. **Filters** (discovery): `startedSince`, `startedWithinDays`, `legalForms`, `onlyActive`.
5. **Delta mode**: `onlyNewCompanies` stores delivered companies in the named key-value store `stateStoreName` and skips them on later runs. The first run returns everything that matches.

Public Search returns at most 200 hits per query (10 pages of 20). Bigger queries log a warning; narrow them with specific NACE codes or fewer postal codes. Discovery has to read each hit's detail page to know its start date (the list does not show it): about 1.5 seconds per candidate. Candidates that fail the date filter are not billed; in delta mode their start dates are remembered, so later runs skip them without a request.

### Pricing

Pay per event: **`company-scraped`, $3.00 per 1,000 companies** ($0.003 each). One event is charged per company item written to the dataset.

Free: enterprise numbers that are invalid or not in the register, companies that fail your filters, companies already delivered in delta mode, pages that cannot be parsed.

`maxItems` is a hard cap on billed companies per run (default 50). Example: a weekly run with `maxItems` 200 that finds 37 new companies costs 37 x $0.003 = $0.11. Platform usage is separate and small.

### Use with AI agents (MCP, Claude, Cursor, n8n, Make)

AI agents can call this Actor through the Apify MCP server.

```json
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=goobertje/belgium-kbo-company-registry" } } }
```

Sign in with OAuth in the browser on first use. Example prompts and the input each maps to:

- "Look up Belgian enterprise 0403.199.702 and tell me its legal form and address." ->
  `{ "enterpriseNumbers": ["0403.199.702"], "maxItems": 1 }`
- "Which Belgian software companies started in Antwerp in the last 30 days?" ->
  `{ "naceCodes": ["62.100", "62.200"], "postalCodes": ["2000", "2018", "2060"], "startedWithinDays": 30, "maxItems": 50 }`
- "Find Belgian private limited companies named Delhaize in Brussels." ->
  `{ "searchTerm": "delhaize", "searchPostalCode": "1000", "legalForms": ["private limited company"], "maxItems": 20 }`

In n8n, Make or Zapier use the Apify node/module, pick this Actor and paste the same JSON.

### Use cases

- Weekly lead list of newly registered Belgian companies by NACE code and region.
- KYB / onboarding: is this enterprise number active, what is its legal form and seat.
- Enrich CRM or invoice data with legal name, legal form and activities.
- Market sizing by NACE code and postal code.
- Let an AI agent verify a Belgian company on the fly.

### FAQ

**Where does the data come from, and is it allowed?** From the KBO Public Search of the FPS Economy. The FPS states its web content is not protected by copyright and may be reused, including commercially (CC0). robots.txt was checked on 2026-10-19: no robots.txt rules (404). The Actor uses a plain HTTP client at a low rate.

**How fresh is it?** The Public Search shows the KBO database as of the previous day. Each item has `kboDataDate`.

**What does a typical run cost?** 100 companies cost $0.30. The prefilled run costs $0.009.

**What if the source blocks or changes?** A CAPTCHA, or three 403/429 answers in a row, stops the whole run. The Actor never tries to solve or bypass it; it keeps what it delivered, saves the delta state and ends with a clear error. If five detail pages in a row cannot be parsed, it stops instead of delivering broken items.

**Can I schedule it and get only new companies?** Yes: schedule weekly, set `onlyNewCompanies` and a `stateStoreName` per feed.

**What is not included?** Financial statements, turnover, owners (UBOs) and Belgian Official Gazette contents. The Gazette is not scraped because its robots.txt disallows the publication search paths; only the link KBO publishes is passed through.

### Limits and honest caveats

- The English interface is an unofficial translation; legal forms and descriptions are KBO's English wording. Only the Dutch, French and German versions are official.
- Speed is about one request every 1.5 seconds on purpose (minimum 1 second).
- KBO throttles heavy use from one IP address with a CAPTCHA page. Retry later, raise `requestDelaySecs`, or lower `maxCandidates`.
- The activity search needs postal codes. Legal form is filtered after the fetch, not at the source.
- Only legal entities are returned by default.

### Legal and disclaimer

The data is public information published by the Belgian FPS Economy in the KBO/BCE. Please cite "KBO/BCE Public Search, FPS Economy" and the `kboDataDate`.

**Personal data.** Names of directors and other functions (`includeFunctions`) and sole traders registered under their own name (`includeNaturalPersons`) are personal data under the GDPR. Both are **off by default**. You are responsible for having a lawful basis and purpose. The FPS Economy states that personal data from the register **may not be reused for direct marketing**.

The information may be incomplete or out of date; it is not legal advice and has no legal value. This Actor is **not affiliated with, endorsed by or connected to the FPS Economy, the KBO/BCE or any Belgian authority**. For official, legally valid data use the official channels (for example the KBO Open Data download or the KBO web service, which require registration with the FPS Economy).

Found a problem or want a field added? Open an issue on the Actor page.

# Actor input Schema

## `enterpriseNumbers` (type: `array`):

Belgian enterprise numbers (ondernemingsnummer / numero d'entreprise) to look up, with or without dots or the BE prefix. Numbers with a wrong check digit are ignored. Example: \["0403.199.702", "BE0202239951"].

## `naceCodes` (type: `array`):

Find companies that have one of these NACE-BEL 2025 activity codes (3 to 7 digits, dots allowed, up to 10 codes). Needs at least one postal code. A search returns at most 200 hits, so combine specific codes with a few postal codes. Example: \["62.100", "62.200"].

## `postalCodes` (type: `array`):

4-digit Belgian postal codes where an establishment or the registered seat must be. Required together with NACE codes; every group of 4 postal codes is one search. Example: \["9000", "9050"].

## `searchTerm` (type: `string`):

Phonetic search on company, establishment and trade names (also finds old names). Returns at most 200 hits; add a postal code to narrow it. Example: "delhaize".

## `searchPostalCode` (type: `string`):

Optional 4-digit postal code that narrows the name search. Example: "1000".

## `legalForms` (type: `array`):

Keep only companies whose legal form contains one of these texts, in English as shown by KBO (case-insensitive). Applies to discovery only. Example: \["private limited company", "public limited company"].

## `startedSince` (type: `string`):

Discovery only: keep companies whose enterprise start date is on or after this date (YYYY-MM-DD). Leave empty for no limit. Can be combined with Started within last days; the later date wins. Example: "2026-09-01".

## `startedWithinDays` (type: `integer`):

Discovery only: keep companies that started in the last N days, which suits scheduled runs. 0 means no limit. Example: 14.

## `onlyActive` (type: `boolean`):

Discovery only: skip stopped or otherwise not-active entities. Explicit enterprise numbers are always returned, whatever their status.

## `includeNaturalPersons` (type: `boolean`):

By default only legal entities (companies, associations) are returned. Enable to also return one-person businesses registered under a private person's name; this is personal data, see the README before enabling it.

## `includeFunctions` (type: `boolean`):

Add the persons holding a legal function (director, manager, auditor ...) with their start date. These are names of private persons; GDPR applies and they may not be used for direct marketing. See the README.

## `includeEstablishments` (type: `boolean`):

Add the establishment units (branches, shops) of each company with number, name, start date and address. Costs one extra request per 20 units.

## `maxEstablishments` (type: `integer`):

Upper limit of establishment units listed per company when Include establishment units is on; establishmentsTruncated tells if more exist. Range 1 to 200. Example: 20.

## `naceVersions` (type: `array`):

Which NACE-BEL versions of the activity list to include. 2025 is the current one; 2008 and 2003 are the older registrations kept by KBO.

## `onlyNewCompanies` (type: `boolean`):

Remember every delivered enterprise in a named key-value store and skip them on later runs, so a weekly schedule only returns companies not delivered before. Delivered companies are not billed again. The first run returns everything that matches.

## `stateStoreName` (type: `string`):

Name of the persistent key-value store that holds the delta state. Use a different name per feed (for example per NACE/postal-code set). Only lowercase letters, digits and hyphens are allowed (not at the start or end). Example: "kbo-company-state".

## `maxItems` (type: `integer`):

Maximum number of companies (dataset items, each one billed) a run outputs; the run stops once reached. Example: 100.

## `maxCandidates` (type: `integer`):

Upper limit of enterprises whose detail page is read in one run (discovery results that fail the date or legal-form filter still cost a request, but are not billed). Protects run time: about 1.5 seconds per candidate. Example: 500.

## `requestDelaySecs` (type: `number`):

Pause between requests to the KBO server, to stay polite and avoid its CAPTCHA throttle. Minimum 1, maximum 30. Example: 1.5.

## Actor input object example

```json
{
  "enterpriseNumbers": [
    "0403.199.702",
    "0202.239.951",
    "0200.065.765"
  ],
  "naceCodes": [],
  "postalCodes": [],
  "legalForms": [],
  "startedWithinDays": 0,
  "onlyActive": true,
  "includeNaturalPersons": false,
  "includeFunctions": false,
  "includeEstablishments": false,
  "maxEstablishments": 20,
  "naceVersions": [
    "2025"
  ],
  "onlyNewCompanies": false,
  "stateStoreName": "kbo-company-state",
  "maxItems": 3,
  "maxCandidates": 500,
  "requestDelaySecs": 1.5
}
```

# Actor output Schema

## `companies` (type: `string`):

Belgian companies from the KBO/BCE Public Search.

# 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 = {
    "enterpriseNumbers": [
        "0403.199.702",
        "0202.239.951",
        "0200.065.765"
    ],
    "maxItems": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("goobertje/belgium-kbo-company-registry").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 = {
    "enterpriseNumbers": [
        "0403.199.702",
        "0202.239.951",
        "0200.065.765",
    ],
    "maxItems": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("goobertje/belgium-kbo-company-registry").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 '{
  "enterpriseNumbers": [
    "0403.199.702",
    "0202.239.951",
    "0200.065.765"
  ],
  "maxItems": 3
}' |
apify call goobertje/belgium-kbo-company-registry --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,goobertje/belgium-kbo-company-registry"
        }
    }
}
```

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/ffl31SNPejiwMZPzY/builds/nHkRaM8queYcOyU8e/openapi.json
