# Benelux Trade Fair Exhibitors — NL & BE expo exhibitor lists (`benelux-signals/benelux-trade-fair-exhibitors`) Actor

Extract exhibitor lists from Dutch and Belgian trade fairs (RAI Amsterdam, Jaarbeurs, Ahoy, Brussels Expo, Antwerp Expo, Flanders Expo, Easyfairs venues). Clean, deduplicated company records: name, website, booth, hall, country, categories, products, description and profile URL.

- **URL**: https://apify.com/benelux-signals/benelux-trade-fair-exhibitors.md
- **Developed by:** [Benelux Signals](https://apify.com/benelux-signals) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.80 / 1,000 exhibitor results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Benelux Trade Fair Exhibitors — NL & BE expo exhibitor lists

Turn the exhibitor list of any Dutch or Belgian trade fair into a clean spreadsheet in minutes. **Benelux Trade Fair Exhibitors** extracts company name, website, booth, hall, country, product categories, products, a short description and the exhibitor profile link from the fairs at **RAI Amsterdam, Jaarbeurs Utrecht, Rotterdam Ahoy, Brussels Expo, Antwerp Expo, Flanders Expo (Ghent), Evenementenhal (Hardenberg, Gorinchem, Venray) and Brabanthallen ('s-Hertogenbosch)**, and from any other fair that uses the same platforms.

Paste a fair URL, or just type a name like `horecava`, `metstrade` or `solids-antwerp`, and get deduplicated, company-level records you can export to Excel, CSV, JSON or straight into your CRM.

### Who is this trade fair exhibitor scraper for?

- **Sales and business development teams** who want a lead list of every company exhibiting at a Benelux trade show, before, during or after the event.
- **Exhibitors** planning which stands to visit, or checking which competitors booked a booth.
- **Market researchers and analysts** who track which companies, countries and product categories show up at fairs year after year.
- **Event agencies, stand builders and suppliers** (logistics, catering, AV, hostesses) looking for exhibitors to offer their services to.
- **Investors and journalists** who want a quick overview of a sector in the Netherlands or Belgium.

### What does Benelux Trade Fair Exhibitors do?

1. **Recognises the platform** behind the fair website and uses a dedicated extractor:
   - **RAI platform** (RAI Amsterdam fairs such as Metstrade, Horecava, Intertraffic, Aquatech, GreenTech): reads the public exhibitor list the website itself uses, 200 exhibitors per request. It is fast and includes the country of every exhibitor.
   - **Easyfairs platform** (Antwerp Expo, Flanders Expo, Evenementenhal, Brabanthallen and many other Easyfairs fairs): reads the server-rendered exhibitor pages of the fair website. It includes booth, country, categories and teaser text.
   - **Generic extractor** (Jaarbeurs, Ahoy, Brussels Expo and other organiser sites): recognises exhibitor tables, repeated exhibitor rows, "Company (booth)" lists, schema.org data and lists of profile links. It follows pagination automatically.
2. **Optionally opens each exhibitor profile** (`includeDetails`) to add the company website, products and the full category list.
3. **Normalises and deduplicates** the data: ISO country codes, halls derived from stand numbers (stand `08.772` → hall `8`), websites cleaned of social-media and tracking links, and duplicates removed (the same company listed twice, or under several letters).
4. **Keeps it company-level.** No contact persons, e-mail addresses or phone numbers are collected. They are actively removed from descriptions.
5. **Crawls politely.** It checks robots.txt before every request, honours `Crawl-delay`, spaces requests to the same site, retries carefully on errors, and uses a proxy only if you enable one.

### Supported trade fairs

You can use these names directly in the input. Any other fair works by URL.

| Name to type | Fair | Venue | Platform |
|---|---|---|---|
| `metstrade` | Metstrade (marine equipment) | RAI Amsterdam | RAI |
| `horecava` | Horecava (hospitality) | RAI Amsterdam | RAI |
| `intertraffic` | Intertraffic Amsterdam | RAI Amsterdam | RAI |
| `aquatech` | Aquatech Amsterdam (water) | RAI Amsterdam | RAI |
| `greentech` | GreenTech Amsterdam (horticulture) | RAI Amsterdam | RAI |
| `solids-antwerp` | Solids Antwerp (bulk solids) | Antwerp Expo | Easyfairs |
| `horeca-expo` | Horeca Expo | Flanders Expo, Ghent | Easyfairs |
| `recreatie-vakbeurs` | Recreatie Vakbeurs | Evenementenhal Hardenberg | Easyfairs |
| `rmv` | Rundvee & Mechanisatie Vakdagen | Evenementenhal Hardenberg | Easyfairs |
| `empack` | Empack Den Bosch (packaging) | Brabanthallen | Easyfairs |
| `batibouw` | Batibouw (construction) | Brussels Expo | Generic |
| `bouwbeurs` | BouwBeurs (construction) | Jaarbeurs Utrecht | Generic |
| `not` | NOT, Nationale Onderwijs Tentoonstelling | Jaarbeurs Utrecht | Generic |
| `infratech` | InfraTech | Rotterdam Ahoy | Generic |
| `europort` | Europort (maritime) | Rotterdam Ahoy | Generic |
| `vakbeurs-foodspecialiteiten` | Vakbeurs Foodspecialiteiten | Evenementenhal Gorinchem | Generic |

**Other fairs:** paste the URL of the exhibitor list (for example `https://www.example-fair.nl/exposanten`). If you paste the fair's home page, the actor looks for the "Exhibitors" / "Exposanten" link itself. Fairs whose exhibitor list is rendered only in the browser by JavaScript, or sits behind a login, cannot be read. The run log tells you when that happens.

### How to use it

1. Click **Try for free** and open the **Input** tab.
2. Add one or more fairs: names from the table above or exhibitor-list URLs.
3. Set **Max results** (the total for the run; this is also your cost cap).
4. Optionally switch on **Open exhibitor profile pages** for websites and products.
5. Click **Start**, then download the results as Excel, CSV or JSON, or connect them to Google Sheets, Make, Zapier or your CRM through the Apify API.

#### Input example

```json
{
    "fairs": ["horecava", "https://www.solids-antwerp.be/en/exhibitors/", "batibouw"],
    "maxResults": 500,
    "maxResultsPerFair": 0,
    "includeDetails": false
}
```

| Field | Default | Description |
|---|---|---|
| `fairs` | – | Fair names (see table) and/or exhibitor-list URLs. Up to 50 per run. |
| `maxResults` | 500 | Maximum exhibitors for the whole run, across all fairs. |
| `maxResultsPerFair` | 0 (no limit) | Cap per fair, handy for sampling several fairs. |
| `includeDetails` | false | Open every exhibitor profile for website, products and all categories. |
| `maxPagesPerFair` | 200 | Safety limit on list pages per fair. |
| `requestDelayMs` | 500 | Minimum pause between requests to one site. A larger robots.txt Crawl-delay always wins. |
| `proxyConfiguration` | off | Not needed for the supported fairs. |

#### Output example

A real record from Metstrade (list mode, without profile details):

```json
{
    "id": "rai:metstrade.com:282-33722",
    "fairName": "Metstrade",
    "fairUrl": "https://www.metstrade.com/exhibitors",
    "venue": "RAI Amsterdam, Amsterdam",
    "platform": "rai",
    "companyName": "2MV Composites B.V.",
    "website": null,
    "booth": "08.772",
    "stands": ["08.772"],
    "hall": "8",
    "country": "NL",
    "countryName": "Netherlands",
    "categories": [],
    "products": [],
    "description": null,
    "profileUrl": "https://www.metstrade.com/exhibitors/2mv-composites-b-v",
    "logoUrl": null,
    "detailsFetched": false,
    "scrapedAt": "2026-10-24T20:05:24.791Z"
}
```

With `includeDetails: true` the same record also gets `website`, `products`, `categories` and `description` when the exhibitor filled them in, and `detailsFetched` becomes `true`.

The **Overview** table in the Output tab shows fair, company, website, booth, hall, country, categories, description and profile link. A JSON `RUN_SUMMARY` in the key-value store lists, per fair, the platform detected, the number of exhibitors found against the number listed, requests made, and any warnings.

#### Which fields do you get per platform?

| Field | RAI | Easyfairs | Generic |
|---|---|---|---|
| Company name, profile URL | ✅ | ✅ | ✅ (profile URL when the site links one) |
| Booth / stand, hall | ✅ | ✅ (booth) | ✅ when listed |
| Country | ✅ | ✅ | when listed |
| Categories | with details | ✅ | when listed |
| Short description | ✅ (when the exhibitor filled it in) | ✅ | with details (meta description) |
| Website | with details | with details | when listed / with details |
| Products | with details | with details | – |

### Speed

- **RAI fairs** are fast: about 1,700 exhibitors (Metstrade) in roughly a minute without details. With details, allow about 1–2 seconds per exhibitor.
- **Easyfairs fairs** ask crawlers to wait **10 seconds between requests** (robots.txt `Crawl-delay: 10`), and we respect that. One list page holds 15 exhibitors, so 500 exhibitors take about 6–8 minutes, and with details add 10 seconds per exhibitor. Start the run and come back later, or schedule it.
- **Generic sites** usually publish the whole list on one page or a few pages: seconds to a minute.

### Pricing

This actor uses **pay per event**: you pay a small amount per exhibitor in your dataset, and platform usage is included.

| Event | Price (Free plan) | Bronze | Silver | Gold |
|---|---|---|---|---|
| Exhibitor result | $0.004 | $0.0036 | $0.0032 | $0.0028 |
| Actor start (per run) | $0.005 | | | |

#### Cost table (Free plan prices)

| What you scrape | Results | Cost |
|---|---|---|
| Quick sample of one fair | 25 | $0.105 |
| A mid-size fair (e.g. Horecava, Intertraffic) | 500 | $2.005 |
| A large fair (e.g. Metstrade) | 1,759 | $7.04 |
| Five Benelux fairs in one run | 3,000 | $12.005 |

**Bill-shock protection:** a run never fetches more than `maxResults` (default 500, so at most $2.005 per run on the Free plan) and stops cleanly at your *maximum cost per run*. Fetching profile pages (`includeDetails`) costs nothing extra per result. It only takes longer.

### FAQ

#### Can it scrape any trade fair in the Netherlands or Belgium?

Every fair on the RAI or Easyfairs platform works out of the box, including fairs that are not in the table. For other organisers the generic extractor reads most exhibitor lists that are published as normal web pages. Lists that only appear after JavaScript runs in the browser, inside a floor-plan app, or behind a login are not supported yet.

#### Does it return e-mail addresses or contact persons?

No. This actor deliberately returns company-level information only: name, website, booth, country, categories and a short description. E-mail addresses and phone numbers are removed even when an exhibitor put them in its description. Contact the companies through their own website.

#### Why are some fields empty?

Fairs publish different information, and exhibitors do not always fill in their profiles. Switch on `includeDetails` to get the website and products. The run summary shows per fair which platform was used.

#### How are duplicates handled?

Within a fair, an exhibitor that appears more than once (for example with two stands, or in several category or letter views) is returned once with all its stands. The same company at two different fairs appears once per fair, so you can see where it exhibits.

#### How fresh is the data?

Every run reads the fair website live. Exhibitor lists grow in the months before a fair, so schedule a weekly run to pick up new exhibitors.

#### My fair is not supported. What now?

Run it once with the URL of the exhibitor list. If you get no results, open an issue on the actor page with the URL, and we will look at adding it.

### Is it legal to use this data?

This actor collects **publicly available, company-level information** that fair organisers publish so that visitors can find exhibitors. It respects robots.txt and crawl delays, identifies itself with a clear User-Agent, and does **not** collect personal data such as names of contact persons, personal e-mail addresses or phone numbers. Even so, you are responsible for how you use the results. Respect the fair website's terms of use and database rights (the EU Database Directive protects substantial extractions). Comply with the GDPR and the ePrivacy rules when you contact companies, for example for B2B e-mail marketing in the Netherlands and Belgium. Do not republish the lists as your own database. If in doubt, ask a lawyer. Read more in Apify's blog post [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/).

### Related actors by benelux-signals

- **EU Tender Radar** — new public tenders from TED and TenderNed.

# Actor input Schema

## `fairs` (type: `array`):

Exhibitor-list URLs (or fair home pages) and/or names of supported fairs. Supported names: metstrade, horecava, intertraffic, aquatech, greentech, solids-antwerp, horeca-expo, recreatie-vakbeurs, rmv, empack, batibouw, infratech, europort, bouwbeurs, not, vakbeurs-foodspecialiteiten. Any other fair on the RAI or Easyfairs platform, or with a plain HTML exhibitor list, works by URL.

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

Maximum number of exhibitors for the whole run, across all fairs. Each result is one billable event, so this is also your cost cap.

## `maxResultsPerFair` (type: `integer`):

Optional limit per fair, e.g. to sample several fairs in one run. 0 = no per-fair limit.

## `includeDetails` (type: `boolean`):

Fetch each exhibitor's profile page on the fair website to add the company website, products and the full category list (and the country on generic sites where available). Slower: one extra request per exhibitor, and Easyfairs sites ask for 10 seconds between requests.

## `maxPagesPerFair` (type: `integer`):

Safety limit on list pages (pagination) fetched per fair. Profile pages are not counted.

## `requestDelayMs` (type: `integer`):

Minimum pause between two requests to the same website. A larger Crawl-delay in the site's robots.txt always wins (capped at 30 s).

## `proxyConfiguration` (type: `object`):

Not needed for the supported fairs. Enable only if a site blocks datacenter IPs.

## Actor input object example

```json
{
  "fairs": [
    "metstrade",
    "https://www.horecaexpo.be/nl/exhibitors/"
  ],
  "maxResults": 100,
  "maxResultsPerFair": 0,
  "includeDetails": false,
  "maxPagesPerFair": 200,
  "requestDelayMs": 500,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

All exhibitor records in the 'overview' table view (fair, company, website, booth, hall, country, categories, profile link).

## `runSummary` (type: `string`):

JSON summary of the run (per-fair platform, results, total listed, requests, warnings and errors) stored under the RUN_SUMMARY key.

# 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 = {
    "fairs": [
        "horecava",
        "https://www.solids-antwerp.be/en/exhibitors/"
    ],
    "maxResults": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("benelux-signals/benelux-trade-fair-exhibitors").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 = {
    "fairs": [
        "horecava",
        "https://www.solids-antwerp.be/en/exhibitors/",
    ],
    "maxResults": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("benelux-signals/benelux-trade-fair-exhibitors").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 '{
  "fairs": [
    "horecava",
    "https://www.solids-antwerp.be/en/exhibitors/"
  ],
  "maxResults": 100
}' |
apify call benelux-signals/benelux-trade-fair-exhibitors --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,benelux-signals/benelux-trade-fair-exhibitors"
        }
    }
}
```

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/g5WCsYLqDQzVLMQDz/builds/G3NeNq1TMoHFt57Cs/openapi.json
