# Trade Show Exhibitors & Attendees Finder (`sherwood/trade-show-people-finder`) Actor

Find who exhibited at and attended a trade show: give its name, get the exhibitors with the people who publicly announced or reported being there (LinkedIn posts, comments, company news), each with evidence and a likelihood score, plus booth staff by role. Pay per company and per person.

- **URL**: https://apify.com/sherwood/trade-show-people-finder.md
- **Developed by:** [Sherwood](https://apify.com/sherwood) (community)
- **Categories:** Lead generation, Business, AI
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 exhibitor delivereds

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

## Trade Show Exhibitors & Attendees Finder — who exhibited, who was there, pay per company and per person

Give it the name of a trade show (or its exhibitor list URL) and get the exhibitor list with the people who were probably there: everyone who publicly announced or reported being at the show on LinkedIn (posts and comments) or on the company's own website, each with the evidence and a likelihood score, plus the booth staff found by role. Find who attended, build event attendees lists and exhibitor contacts for trade show leads, and tell it what kind of exhibitors you are looking for so it keeps only those. **$0.004 per exhibitor delivered, $0.010 per person with evidence, $0.004 per person found by role.**

Built for automation and AI agents: nothing is required, the empty input returns a fictional sample show so you can see the output shape without spending anything, and every result is a plain dataset item with the people nested in it. The third-party Actors it calls on your behalf (Google search, Skython exhibitor list, harvestapi LinkedIn) run under your account at their public prices, within the budget you set (`maxSubActorSpendUsd`, 10 USD by default): an `estimate` item comes first and `estimateOnly` stops there.

### What you get

One item per exhibitor, with its people inside:

```json
{
  "type": "company",
  "name": "Northwind Robotics",
  "website": "https://northwind-robotics.example",
  "linkedinUrl": "https://www.linkedin.com/company/northwind-robotics-sample",
  "country": "Germany", "hall": "Hall 4", "stand": "A12",
  "categories": ["Robotics"], "description": "Collaborative robots for packaging lines",
  "companyType": "manufacturer",
  "targetFit": 0.75, "targetFitLevel": "mostly matches", "targetConfidence": 0.9,
  "exhibitorConfirmedBy": "website",
  "webEvidence": [{"url": "https://northwind-robotics.example/news/sample-expo-2026", "title": "Northwind at Sample Expo 2026",
                   "date": "2026-05-20", "excerpt": "Visit us in Hall 4, booth A12...", "nature": "announces_participation"}],
  "peopleEvidenced": 1, "peopleRoleBased": 1,
  "people": [
    {"personName": "Anna Keller", "personLinkedinUrl": "https://www.linkedin.com/in/sample-anna-keller-0000",
     "headline": "Head of Sales at Northwind Robotics", "companyName": "Northwind Robotics",
     "exhibitorMatch": "exhibitor", "isExhibitorStaff": true, "source": "post-author",
     "attendanceScore": 1.0, "attendanceLevel": "certain", "confidence": 0.9, "scoredBy": "jev",
     "roleBasis": {"title": "Head of Sales", "keywords": ["sales"]},
     "evidence": [{"kind": "post", "url": "https://www.linkedin.com/posts/...", "date": "2026-06-05",
                   "excerpt": "What a week at #SampleExpo2026! Thank you to everyone who stopped by booth A12...",
                   "nature": "reports_presence", "onSite": 0.97}]},
    {"personName": "Jonas Weber", "headline": "Marketing Manager at Northwind Robotics", "source": "employee-search",
     "attendanceScore": 0.5, "attendanceLevel": "likely", "roleBasis": {"title": "Marketing Manager", "keywords": ["marketing"]}, "evidence": []}
  ]
}
```

Also in the dataset: `attendees` items for the people with evidence who are not staff of an exhibitor (visitors, organizers, speakers, press), in parts of 100; an `estimate` item first (what the third-party Actors may bill you at most, and what this Actor may charge at most); an `event` item last (the resolved edition, counts, sub-runs with their cost, warnings). The **People** view of the dataset (or `items?unwind=people` in the API) gives one row per person; the key-value store holds `SUMMARY` (updated after every step) and `JUDGEMENTS` (every judgement, for audit).

### How people are found and scored

- **LinkedIn posts and comments**: posts found with the show's hashtags (`#IMTS2026`) and name within the window from 60 days before the show to 30 days after it, with their comments (and reactions when `evidenceSources` includes `reactions`). Each post and comment is judged: announces presence, reports presence, mentions only, unrelated. Authors and commenters become people with that evidence.
- **Company websites and blogs**: the sitemap or the news pages of each targeted exhibitor, read for pages that mention the show; a page that announces or recaps the participation confirms the exhibitor (`exhibitorConfirmedBy: website`).
- **Roles**: for each targeted exhibitor with a LinkedIn page, its employees whose current title matches `roleKeywords` (sales, business development, marketing, CEO, founder, managing director... by default), as booth staff.

Every person gets an `attendanceScore` from 0 to 1 and its level: **no sign** (0), **weak sign** (0.25: mentioned the show or reacted to a post), **likely** (0.5: announced coming or exhibiting, or a booth-facing role at a confirmed exhibitor), **strong** (0.75: reported being there), **certain** (1.0: clearly on site). People under `minAttendanceScore` (0.3 by default) are not delivered and not charged. Every judgement is made by Jev, a decision model, from the texts themselves; `scoredBy` says `jev`, or `fallback` when the model was unavailable and a keyword rule took over.

Targeting: describe the exhibitors you want in `targetCompanies` ("manufacturers of CNC machine tools and automation equipment"). Each exhibitor gets a `targetFit` from 0 to 1 and a `companyType` (manufacturer, distributor or reseller, service provider, software or data, association, press or institution). Only exhibitors at or above `minTargetFit` (0.5) are enriched and charged. Without `targetCompanies`, every exhibitor is kept.

### Costs

| Who bills | What | Price |
|---|---|---|
| This Actor | exhibitor delivered (`company-qualified`) | $0.004 |
| This Actor | person with evidence (`person-evidenced`) | $0.010 |
| This Actor | person found by role (`person-role-based`) | $0.004 |
| apify/google-search-scraper (your account) | resolving the show by name, two result pages | about $0.006 |
| skython/exhibitor-list-scraper (your account) | exhibitor read from the catalog (20 at least) | $0.0045 + $0.01 per run |
| harvestapi/linkedin-post-search (your account) | post, comment or reaction read | $0.002 |
| harvestapi/linkedin-company-employees (your account) | per company searched, plus per profile | $0.02 + $0.003 |

The third-party Actors are called with a cap each (Apify imposes at least $0.30 per call, $0.50 for Google search); the sum stays within `maxSubActorSpendUsd`. The `estimate` item shows the maximums before anything is spent; `estimateOnly: true` stops there. Example: 500 exhibitors read, 150 targeted, 600 people with evidence and 600 by role: about $9 for this Actor and $9 to $11 billed by the third-party Actors.

### Input

By name (the official site, the exhibitor list and the dates are found with a Google search):

```json
{"eventName": "IMTS 2026", "targetCompanies": "manufacturers of CNC machine tools and automation equipment"}
```

By exhibitor list URL, with dates:

```json
{"eventName": "Eurosatory 2026", "exhibitorListUrl": "https://www.eurosatory.com/en/catalogue/", "startDate": "2026-06-15", "endDate": "2026-06-19",
 "targetCompanies": "drone and counter-drone makers", "maxCompanies": 300}
```

From the dataset of an exhibitor list scraper you already ran (or as an integration after it):

```json
{"eventName": "Hannover Messe 2026", "companiesDatasetId": "YOUR_DATASET_ID", "includeRoleBased": false}
```

LinkedIn only, with your own company list:

```json
{"eventName": "Web Summit 2026", "companies": ["Northwind Robotics", "https://contoso.example"], "evidenceSources": ["posts", "comments"]}
```

Fields: **Trade show** (`eventName`, `year`, `startDate`, `endDate`, `eventUrl`, `exhibitorListUrl`, `eventLinkedinUrl`, `hashtags`), **Exhibitors** (`companies`, `companiesDatasetId`, `targetCompanies`, `excludeCompanies`, `minTargetFit`, `includeOffTargetCompanies`, `maxCompanies`), **People** (`evidenceSources`, `maxPosts`, `maxEngagementsPerPost`, `includeRoleBased`, `roleKeywords`, `maxPeoplePerCompany`, `minAttendanceScore`, `maxPeople`), **Budget** (`maxSubActorSpendUsd`, `estimateOnly`). Aliases: `event`, `tradeShow`, `name`, `url`, `exhibitors`, `datasetId`.

### Limits

- The exhibitor catalog is read by Skython's Exhibitor List Scraper, which supports about thirty catalog platforms (Map Your Show, Messe Frankfurt, Koelnmesse, Messe Düsseldorf, Messe Stuttgart, Reed, a2z, Ungerboeck...); tested here on IMTS (Map Your Show). When the listing page is on a platform it does not read (The Battery Show, for instance), the run says so in its warnings and continues in LinkedIn-only mode: people from posts, companies from the posts that speak for an exhibitor. Give `companies` or `companiesDatasetId` to add the exhibitors yourself.
- A reaction is weak evidence (level 0.25) and costs $0.002 to read: off by default.
- People named on company web pages are not extracted yet (the page confirms the exhibitor only).
- When the dates are unknown, the whole year is the window; give `startDate` and `endDate` for sharper results.
- No e-mail, no phone number.

### Data and privacy

Public data only: exhibitor catalogs, public LinkedIn posts, comments and profiles read without any account or cookie, public web pages. No e-mail, phone number, photo or sensitive attribute is collected; nothing is stored outside your own run. Presence is always given as a probability with its evidence, never as a fact, and visitors who are not exhibitor staff appear only through what they wrote publicly. Use the results for B2B prospecting and partnerships under your own legitimate-interest assessment and local law. Removal requests: maxence.fournaux+sherwood@gmail.com.

### Related Actors

- [Google Maps Scraper API](https://apify.com/sherwood/google-maps-scraper): places with free verdicts and AI qualification.
- [Review Analyzer API](https://apify.com/sherwood/review-analyzer): sentiment, topics and unanswered complaints of any reviews dataset.

# Actor input Schema

## `eventName` (type: `string`):

Name of the show, ideally with the edition year ("IMTS 2026", "Hannover Messe 2026"). The Actor finds the official site, the exhibitor catalog and the dates with a Google search. Aliases: event, tradeShow, name.

## `year` (type: `integer`):

Year of the edition when it is not in the name. Default: the year found in the name, else the current year.

## `startDate` (type: `string`):

First day of the show, YYYY-MM-DD. Found automatically when empty. LinkedIn posts are searched from 60 days before this date to 30 days after endDate.

## `endDate` (type: `string`):

Last day of the show, YYYY-MM-DD.

## `eventUrl` (type: `string`):

Home page of the show. Found with Google when empty. Alias: url (when the URL does not look like an exhibitor list).

## `exhibitorListUrl` (type: `string`):

The page listing the exhibitors (Map Your Show, Messe Frankfurt, Koelnmesse, Informa, a2z, Ungerboeck and 20+ other platforms read by Skython). Found from the site when empty. Give it when the automatic resolution fails.

## `eventLinkedinUrl` (type: `string`):

https://www.linkedin.com/company/... or /showcase/... of the event. Used to find posts mentioning the show.

## `hashtags` (type: `array`):

Hashtags used for the edition (#IMTS2026). Synthesized from the name when empty.

## `companies` (type: `array`):

Names, website URLs, or objects {name, website, linkedinUrl}. Added to (or instead of) the catalog. Alias: exhibitors.

## `companiesDatasetId` (type: `string`):

Dataset of an exhibitor list scraper run (Skython or another one): name, website and LinkedIn fields are detected. When this Actor runs as an integration after such a run, leave it empty: the dataset of the triggering run is used.

## `targetCompanies` (type: `string`):

What kind of exhibitors interest you ("software vendors for food traceability", "packaging machinery makers"). Each exhibitor is judged against it (targetFit 0 to 1) and only those at or above minTargetFit are enriched and charged. Leave empty to keep every exhibitor.

## `excludeCompanies` (type: `array`):

Names or domains to leave out (your own company, competitors).

## `minTargetFit` (type: `number`):

Exhibitors under this fit (0 to 1) are off target: not enriched, not charged, hidden unless includeOffTargetCompanies.

## `includeOffTargetCompanies` (type: `boolean`):

Also output the exhibitors under minTargetFit, without people and free of charge.

## `maxCompanies` (type: `integer`):

Exhibitors read from the catalog (Skython bills 0.0045 USD each and reads at least 20).

## `evidenceSources` (type: `array`):

Where to look for people who were there.

## `maxPosts` (type: `integer`):

Posts read across all search queries (harvestapi bills 0.002 USD per post, comment or reaction).

## `maxEngagementsPerPost` (type: `integer`):

Comments (and reactions, when enabled) read per post, 25 by default. Each one is billed 0.002 USD by harvestapi and judged as evidence.

## `includeRoleBased` (type: `boolean`):

For each targeted exhibitor with a LinkedIn page, search its employees whose title matches roleKeywords (harvestapi: 0.02 USD per company plus 0.003 USD per profile).

## `roleKeywords` (type: `array`):

Job title words searched for booth staff. Default: sales, business development, commercial, export, account manager, key account, marketing, communication, trade show, events, CEO, founder, co-founder, managing director, general manager, country manager, president, VP.

## `maxPeoplePerCompany` (type: `integer`):

Employees searched by role per targeted exhibitor, 5 by default (0.003 USD each, billed by harvestapi).

## `minAttendanceScore` (type: `number`):

People under this score (0 to 1) are not output and not charged. 0.3 keeps everyone who at least announced coming or exhibiting.

## `maxPeople` (type: `integer`):

Cap on the people delivered in the run, with evidence and by role together. 1000 by default.

## `maxSubActorSpendUsd` (type: `number`):

Cap on what the Actors called on your behalf may bill you in this run (Google search, Skython, harvestapi). Each call gets a share; Apify imposes at least 0.30 USD per call (0.50 for Google search).

## `estimateOnly` (type: `boolean`):

Stop after the estimate item: nothing is called, nothing is charged.

## Actor input object example

```json
{
  "eventName": "IMTS 2026",
  "targetCompanies": "manufacturers of CNC machine tools and automation equipment",
  "minTargetFit": 0.5,
  "includeOffTargetCompanies": false,
  "maxCompanies": 200,
  "evidenceSources": [
    "posts",
    "comments",
    "websites"
  ],
  "maxPosts": 300,
  "maxEngagementsPerPost": 25,
  "includeRoleBased": true,
  "maxPeoplePerCompany": 5,
  "minAttendanceScore": 0.3,
  "maxPeople": 1000,
  "maxSubActorSpendUsd": 10,
  "estimateOnly": false
}
```

# Actor output Schema

## `results` (type: `string`):

One item per exhibitor with its people nested, attendees items for people not matched to an exhibitor, plus the estimate and event items.

## `people` (type: `string`):

The same results unwound: one row per person, with their company.

## `summary` (type: `string`):

Resolved edition, counts, sub-runs, warnings; updated after every step.

# 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 = {
    "eventName": "IMTS 2026",
    "targetCompanies": "manufacturers of CNC machine tools and automation equipment"
};

// Run the Actor and wait for it to finish
const run = await client.actor("sherwood/trade-show-people-finder").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 = {
    "eventName": "IMTS 2026",
    "targetCompanies": "manufacturers of CNC machine tools and automation equipment",
}

# Run the Actor and wait for it to finish
run = client.actor("sherwood/trade-show-people-finder").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 '{
  "eventName": "IMTS 2026",
  "targetCompanies": "manufacturers of CNC machine tools and automation equipment"
}' |
apify call sherwood/trade-show-people-finder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sherwood/trade-show-people-finder"
        }
    }
}
```

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/oOCS9qQ4v05UePOBp/builds/cr5jXL4AGcGt7vXb5/openapi.json
