# Event Exhibitor Scraper and Change Monitor (`cleanscrape/event-exhibitor-monitor`) Actor

Export Map Your Show exhibitor lists and track company or booth changes between runs. Supports 8\_0 directories, reusable watchlists and optional profile details. Try the IAAPA example, then monitor your own supported event without rebuilding the list each time.

- **URL**: https://apify.com/cleanscrape/event-exhibitor-monitor.md
- **Developed by:** [CleanScrape](https://apify.com/cleanscrape) (community)
- **Categories:** Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 exported records

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?

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

## Event Exhibitor Scraper and Change Monitor

Export public Map Your Show exhibitor directories and track what changes between runs. Get company names, booths, descriptions and source links in a consistent dataset, with optional publicly displayed profile details.

Built for event-service suppliers, B2B research teams and agencies that need useful exhibitor data without manually comparing spreadsheets.

### Try it: export an IAAPA exhibitor list

For a step-by-step walkthrough of snapshots and recurring comparisons, read [Track Map Your Show exhibitor changes](https://dev.to/cleanscrape/track-map-your-show-exhibitor-changes-without-comparing-spreadsheets-by-hand-2ff5).

Turn a supported public event directory into a spreadsheet of companies and booths. Start with a snapshot; add monitoring only when you need to compare changes over time.

| 1. Choose a directory | 2. Export a small sample | 3. Use the list |
| --- | --- | --- |
| IAAPA Expo 2026 on Map Your Show | Up to 100 exhibitors, without optional profiles | Download companies, booths and source links |

#### Run the example

1. Open **Tasks** on the Store page (**Example tasks** in Console) and choose **Export IAAPA Expo exhibitor companies**.
2. Keep `snapshot`, a limit of 100, and optional profile details off for your first run. Review the Pricing tab and your spending limit.
3. Select **Start**, then open **Output**. Check `SUMMARY` for the number scanned and the coverage status.
4. Export CSV or Excel to plan your research or prepare an event visit. Use each row's `profileUrl` to return to the exhibitor's source page.

#### A look at the output

Selected fields from our 100-row demonstration run on 14 September 2026. Booths are arrays in the actual JSON; the table displays their contents for readability.

| Company | Booth | Event | Coverage |
| --- | --- | --- | --- |
| 123 iMP Event Solutions | W554 | IAAPA Expo 2026 | capped\_snapshot |
| 1956 Individuals | W1115 | IAAPA Expo 2026 | capped\_snapshot |
| 3-Minute Shirt | W2549 | IAAPA Expo 2026 | capped\_snapshot |

This was a capped sample, **not the whole directory**. Listings can change. With profile details off, website and location fields can be null; this is not an email or contact-list export. The example depends on that event's directory staying publicly available.

#### Want to see what changes?

Choose **Monitor IAAPA exhibitor and booth changes** under **Tasks** on the Store page (**Example tasks** in Console). It uses a higher source-record limit so the complete directory can be checked.

1. The first complete run saves a baseline and exports matching exhibitors. The baseline rows and completed check are billable.
2. Run again with the same watchlist and settings. Later runs export changes only; zero rows can correctly mean nothing changed. The completed-check fee still applies.
3. A company is reported as no longer listed only after two consecutive complete checks miss it. This does not prove it withdrew from the event.

The monitoring preset does not turn on a schedule or send alerts. You can add those separately once you have checked the first results. It supports Map Your Show 8\_0 directories, not every event website.

### What you get

- Snapshot exports for supported Map Your Show 8\_0 directories.
- Monitoring for added exhibitors, updated names, booth changes and description changes.
- Optional website, location and product-category fields when publicly displayed on profiles.
- A separate coverage report, including source totals, scan limits and individual event failures.
- Persistent watchlists, stable record identifiers and two-check confirmation before reporting a company as no longer listed.

This release supports **Map Your Show 8\_0 directories hosted at `EVENT.mapyourshow.com` only**. Custom-branded event domains and individual exhibitor profile URLs are not supported as inputs. It does not claim universal event coverage, scrape attendee lists, retrieve hidden contact data or infer sponsorship budgets.

### Quick start

Use a public event directory URL. This example exports up to 100 exhibitors:

```json
{
  "eventUrls": [
    "https://iaapaexpo26.mapyourshow.com/8_0/explore/exhibitor-alphalist.cfm"
  ],
  "mode": "snapshot",
  "maxExhibitorsPerEvent": 100,
  "includeDetails": false
}
```

Run the Actor, open its Output tab and download JSON, CSV or Excel. Open the `SUMMARY` record in the default key-value store for coverage and failure details. A capped snapshot is explicitly labeled `capped_snapshot`; it is not a full-directory claim.

Event websites change and older editions can close. If an example becomes unavailable, use the directory URL for an active event on the same platform.

### Set up a recurring watchlist

```json
{
  "eventUrls": ["https://iaapaexpo26.mapyourshow.com"],
  "mode": "monitor",
  "watchlistName": "client-events-2026",
  "maxExhibitorsPerEvent": 5000,
  "includeDetails": false,
  "keywords": []
}
```

The first complete run exports a baseline of matching exhibitors. Later runs export changes only. An unchanged run can correctly return zero dataset rows; its successful check and counts remain available in `SUMMARY`.

Save the input as an Apify Task and schedule it at your preferred cadence. Use the same watchlist name and settings to continue the history. Changing keywords or the detail setting creates a separate baseline, preventing false alerts caused by comparing different scopes. Changing the scan limit alone does not reset history.

Named storage preserves the baseline between runs. Monitor mode needs permission to create and access its own named key-value store and coordination queue in the run owner's account. Overlapping runs of the same watchlist are rejected rather than allowed to overwrite one another. Snapshot mode does not create persistent watchlist state.

### Pricing

The prices and calculations below use the base rate before Store discounts. Eligible subscription tiers receive lower rates; the Pricing tab shows the current tier prices.

| Billable event | Price | When it applies |
| --- | --- | --- |
| Exported exhibitor or change | **$0.002 each** | $2 per 1,000 delivered dataset records; includes the initial monitoring baseline |
| Completed monitoring check | **$0.05 per event directory** | Applies in monitor mode, including the first complete baseline check and checks with no changes |
| Optional profile detail | **$0.001 per enriched profile** | Only when `includeDetails` is enabled and at least one public detail is extracted; applies on each run that enriches the profile |

**No startup fee.** Actor execution compute is included in these event prices. You do not need to supply a proxy or an external API key.

Examples without optional profiles:

- Snapshot of 100 exhibitors: **$0.20**.
- Initial monitoring baseline of 1,000 exhibitors for one event: **$2.05**.
- Later check of that event with no changes: **$0.05**.
- Later check with 10 changes: **$0.07**.
- Ten events checked four times, with 100 total changes: **$2.20**, after the initial baselines.

Optional details for 100 enriched profiles add $0.10. Basic profiles with no public details are marked `no_public_details` and have no enrichment charge. Successful enrichment is separately billable even if a later part of an event fails. Failed source checks do not incur the completed-monitoring-check fee, but previously delivered records or extracted details remain billable. Stored data retained in your account and downstream integrations remain subject to their own platform/service terms.

Set an Apify run spending limit before scheduling. If a limit interrupts delivery, that event's baseline is not advanced. A retry may repeat previously delivered records; deduplicate using `recordId`. This is not an exactly-once billing or delivery guarantee.

### Inputs

| Input | Meaning |
| --- | --- |
| `eventUrls` | One to ten HTTPS Map Your Show event URLs. Homepage, 8\_0 gallery and alphabetical/list routes are accepted. Duplicate events are processed once. |
| `mode` | `snapshot` exports current matches; `monitor` maintains a baseline and exports subsequent changes. |
| `watchlistName` | Persistent history name, using 1-64 letters, numbers, underscores or hyphens. Default: `my-events`. Use a new name for an intentional reset. |
| `maxExhibitorsPerEvent` | Integer 1-5000. In snapshot mode, caps exported matches. In monitor mode, the complete directory must fit within this source-record limit. The quick-start UI uses 100; increase it explicitly for monitoring. |
| `includeDetails` | Fetch publicly displayed website, country, city, region and product categories. Default: false. Maximum 500 matched profiles per event. |
| `keywords` | Optional case-insensitive substring matches against company name or listing description. Any keyword can match. Up to 20 terms. This is not a category, country or website filter. |

Filtered gallery URLs are rejected rather than silently ignored. Remove URL filters and use the supported `keywords` setting. Direct exhibitor profile URLs, floorplans, non-8\_0 directories and login pages are not supported as inputs.

### Output contract

Every dataset row has `schemaVersion`, `recordType`, `recordId`, `eventId`, `eventName`, `exhibitorId`, `companyName`, `booths`, `description`, `website`, `country`, `city`, `region`, `categories`, `detailsStatus`, `sourceUrl`, `profileUrl`, `observedAt` and `coverageStatus`.

Unknown optional scalar values are `null`; absent categories and booths are empty arrays. Source names are preserved rather than guessed or merged by similar spelling. Multiple booths are represented in an array. Listing descriptions may be abbreviated by the source. Product categories may require login on some events and are not harvested when gated.

Change rows additionally provide:

| Field | Meaning |
| --- | --- |
| `changeType` | `added`, `updated` or `no_longer_listed` |
| `changedFields` | Fields that differ for an update |
| `before` / `after` | Comparable values before and after observation; one side is null for additions or confirmed absence |

Snapshot rows contain `changeType: null`, an empty `changedFields` array and null `before`/`after` values.

Illustrative change record, not a claimed live observation:

```json
{
  "schemaVersion": "1.0",
  "recordType": "change",
  "eventId": "example26",
  "exhibitorId": "123",
  "companyName": "Example Manufacturing",
  "changeType": "updated",
  "changedFields": ["booths"],
  "before": { "companyName": "Example Manufacturing", "booths": ["B12"], "description": null },
  "after": { "companyName": "Example Manufacturing", "booths": ["C08"], "description": null },
  "observedAt": "2026-09-14T12:00:00Z",
  "coverageStatus": "complete_directory"
}
```

The illustration omits common source and identifier fields for brevity. Actual rows include the full contract above.

### How monitoring avoids misleading changes

A complete scan must reconcile retrieved source IDs with the source-reported total. Overlapping pages, changed totals, failed requests and incompatible source schemas are rejected for monitoring.

A company must be absent from **two consecutive complete successful checks** before `no_longer_listed` is emitted. A failed check does not advance this count. This means no longer observed in that public directory, not proof that the company withdrew from the event or stopped trading.

If a baseline has at least ten exhibitors and more than 40% disappear at once, the check is quarantined. No changes or baseline updates are made for that event. Check whether the source closed, changed access or genuinely changed substantially before starting a new watchlist. Empty source directories are always treated as unavailable, not as mass-removal evidence.

The website can still change between requests. These checks reduce misleading output; they cannot prove a perfectly atomic snapshot or detect changes that occur and revert between runs.

### Integrations

Use Apify datasets with your existing Python, JavaScript, spreadsheet or automation workflow. For recurring notifications, connect an Apify run-success webhook or Make/Zapier workflow, inspect `SUMMARY`, then process dataset rows where `recordType` is `change`. A run can partially succeed across events, so do not assume every supplied directory completed.

This Actor does not send emails, edit a CRM, contact exhibitors or create schedules automatically.

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("cleanscrape/event-exhibitor-monitor").call(run_input={
    "eventUrls": ["https://iaapaexpo26.mapyourshow.com"],
    "mode": "snapshot",
    "maxExhibitorsPerEvent": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["companyName"], item["booths"])
```

### Limitations and responsible use

- Map Your Show 8\_0 only. A platform hostname does not guarantee that every event keeps its directory publicly accessible.
- No private attendee data, login-only categories, hidden contacts, contact enrichment or sponsor-tier extraction in this release.
- Complete monitoring supports at most 5,000 source records per event. Optional details support at most 500 keyword-matched profiles per event.
- Profile access can differ across exhibitors. Snapshot mode reports unavailable details. Monitor mode preserves the event baseline if a requested profile fails or previously populated optional fields become unavailable, rather than assuming those fields were deleted.
- Metadata and descriptions are supplied by the event or exhibitor and may be incomplete or outdated. Observation time is not the original edit time.
- Only collect and use data you are permitted to access. Review organizer terms, privacy obligations and rights to reuse directory content. Public visibility does not grant permission for unrestricted resale or outreach.

### Support

Open an issue on this Actor with the event URL, run ID, expected field and observed result. Never include your API token or private credentials. Requests for another directory platform are welcome; support will be added only when the source and output can be validated.

CleanScrape builds practical data tools with structured output, explicit limitations and careful changes to published contracts.

### Retrieve separately saved profile details

When optional enrichment finds public details, the Actor saves them before applying the enrichment charge. Open **Public profile details index** in Output, or open the `PROFILE_DETAILS` record in the run's default key-value store. Its `records` array contains the storage key for each saved profile. Open that key in the same store to retrieve the data. This index is empty when no profiles were enriched.

These records remain accessible under your storage retention settings even if a later step fails or the run reaches its spending limit. An indexed profile may be free if billing failed after storage; the index is a retrieval manifest, not an invoice. Normal snapshot and change records retain the same dataset format.

### Interpret filtered monitoring results

With keywords enabled, `no_longer_listed` means the exhibitor is absent from the matching scope on two consecutive complete checks. A company can leave that scope by changing its name or description; this does not prove that it withdrew from the event. Monitor without keywords when you need whole-directory membership comparisons.

### Thanks for using CleanScrape

What worked well, and what could be better? [Share your experience in Reviews](https://console.apify.com/actors/3HcgSwgewoXVLHmvG/info/reviews) to help other users decide whether this tool fits their workflow. Honest feedback is welcome, including anything that fell short.

For a question, bug or feature request, [open an issue](https://apify.com/cleanscrape/event-exhibitor-monitor/issues). Include your expected result and a non-sensitive input example. Never include API tokens or credentials. Leaving feedback is optional and does not affect access, pricing or support.

# Actor input Schema

## `eventUrls` (type: `array`):

One to ten public HTTPS URLs hosted at EVENT.mapyourshow.com. Use unfiltered 8\_0 gallery/list URLs or event homepages. Custom-branded domains, individual profile URLs, other platforms and login pages are not supported.

## `mode` (type: `string`):

Snapshot exports current matches. Monitor establishes a baseline and then exports changes.

## `watchlistName` (type: `string`):

Reuse this name to continue monitoring. A new name starts fresh history. Use 1-64 letters, numbers, underscores or hyphens.

## `maxExhibitorsPerEvent` (type: `integer`):

Snapshot: maximum matched records to export. Monitor: entire source directory must fit within this limit; use 5000 for large events. A capped monitor preserves its baseline.

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

Optional website, country, city, region and product categories. Adds $0.001 per profile with extracted public details. Empty profiles are not charged. Up to 500 matched profiles per event. Login-only fields are not collected.

## `keywords` (type: `array`):

Optional case-insensitive substring filters on company name or listing description; any term may match. Not a category or country filter.

## Actor input object example

```json
{
  "eventUrls": [
    "https://iaapaexpo26.mapyourshow.com/8_0/explore/exhibitor-alphalist.cfm"
  ],
  "mode": "snapshot",
  "watchlistName": "my-events",
  "maxExhibitorsPerEvent": 100,
  "includeDetails": false,
  "keywords": []
}
```

# Actor output Schema

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

No description

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

No description

## `profileDetails` (type: `string`):

No description

# 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 = {
    "eventUrls": [
        "https://iaapaexpo26.mapyourshow.com/8_0/explore/exhibitor-alphalist.cfm"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanscrape/event-exhibitor-monitor").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 = { "eventUrls": ["https://iaapaexpo26.mapyourshow.com/8_0/explore/exhibitor-alphalist.cfm"] }

# Run the Actor and wait for it to finish
run = client.actor("cleanscrape/event-exhibitor-monitor").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 '{
  "eventUrls": [
    "https://iaapaexpo26.mapyourshow.com/8_0/explore/exhibitor-alphalist.cfm"
  ]
}' |
apify call cleanscrape/event-exhibitor-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cleanscrape/event-exhibitor-monitor"
        }
    }
}
```

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/3HcgSwgewoXVLHmvG/builds/hie27EOcDym2KFTuh/openapi.json
