# Map Your Show Exhibitor Scraper — Category & Industry Filters (`samstorm/map-your-show-exhibitor-scraper`) Actor

Filter Map Your Show exhibitors by product categories and Vertical Markets. Export names, websites, booths and evidence across 1–3 events. Preserve unknowns and continue capped batches. Public beta; $4/1,000 extracted profiles + $0.02/run.

- **URL**: https://apify.com/samstorm/map-your-show-exhibitor-scraper.md
- **Developed by:** [Sam Kleespies](https://apify.com/samstorm) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 extracted exhibitor profiles

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

## Map Your Show Exhibitor Scraper: Category & Industry Filters

Build an event-research shortlist from public Map Your Show exhibitor directories. Export exhibitor names, websites, booths, product categories and explicitly listed Vertical Markets, with source links and clear filter evidence.

Need public contact details after building your shortlist? See [Enrich selected exhibitor websites](#enrich-selected-exhibitor-websites).

**Public beta:** supports the `/8_0/explore/exhibitor-gallery.cfm` template on `*.mapyourshow.com`. Start with a small batch for your event. Other domains, templates, login-only pages and arbitrary URL filters are not supported. No third-party API key or proxy subscription is required.

### Try a verified example

The following PACK EXPO East input collected 10 profiles successfully during our September 29, 2026 owner validation. The directory's contents can change.

```json
{
  "directories": [
    "https://packeast26.mapyourshow.com/8_0/explore/exhibitor-gallery.cfm?featured=false&georegion=4%7C537"
  ],
  "maxProfiles": 10,
  "industryTerms": ["Pet Food"],
  "industryMode": "any"
}
```

1. Paste your public exhibitor **gallery URL**, or start with this example.
2. Set **Maximum checked profiles** and your run spending limit. Start with 10–20.
3. Run the Actor, then open **Directory entries** and **Filter evidence**.
4. Export JSON, CSV or Excel from Apify. Use `matchStatus` to select `matched` rows; keep `unknown` separate from `not_matched`.

### Pricing

**$0.02 per run + $0.004 per successfully extracted profile ($4 per 1,000 profiles). Platform usage is included.** A run returning 10 profiles costs $0.06; 20 profiles cost $0.10; 200 profiles cost $0.82. These examples assume all requested profiles are extracted and the run completes within its limits.

Every successfully extracted profile saved to the dataset is charged, including filter nonmatches, unknowns and profiles with missing optional fields. The filter helps you evaluate the returned records; it does not make the preceding profile checks free. Failed, blocked and unsupported profiles are reported in the run summary without a profile-result charge. The start fee still applies to runs with no results. There is no extra charge for company grouping.

The Actor stops before requesting another profile when its spending allowance is exhausted. Apify's run spending limit also applies. The minimum run allowance is $0.024, covering startup and one profile. Limits and pricing are the same for free and paid Apify plans.

### Inputs and supported filters

| Input | Meaning |
| --- | --- |
| `directories` | One to three public gallery URLs. All directories must reconcile their entry counts before profile collection begins. |
| `maxProfiles` | Total profiles to check across all directories, 1–200; default 20. This is not a limit on matches. |
| `categoryTerms` | Up to 20 literal words or phrases to match against Product Categories. |
| `industryTerms` | Up to 20 literal words or phrases to match only against explicitly labeled Vertical Markets. |
| `categoryMode`, `industryMode` | `any` or `all` within each family. Requested families combine with AND. |
| `maxDirectoryProfiles` | Maximum reported size of each directory, up to 5,000. |
| `startOffset` | Zero-based position in the combined directory order; default 0. Use continuation details below. |
| `expectedDirectoryFingerprint` | Required when continuing at a nonzero offset; detects changes in directory membership or order. |

URL filters `featured=false` and numeric `georegion` values are preserved. Other URL filters are rejected rather than silently ignored. Use a filter URL copied from your event's gallery: numeric values are event-specific.

Product categories and buyer industries are different source taxonomies. Missing Vertical Markets remain **unknown**; they are never inferred from a company's product categories. Matching is literal, not AI classification. The Actor returns all successfully extracted profiles so you can audit matches and unknowns.

### Output

Each dataset record includes `name`, `website`, `eventName`, `eventId`, `booths`, `categories`, `verticalMarkets`, `profileId`, `profileUrl`, `observedAt`, `fieldStatus`, `categoryFilter`, `industryFilter` and `matchStatus`. Fields may be missing or empty when the source does not provide them. Source hashes and field evidence support later inspection.

Abridged record from the successful owner validation (fields omitted for readability):

```json
{
  "name": "A-B-C Packaging Machine Corp.",
  "eventName": "PACK EXPO East 2026",
  "website": "https://www.abcpackaging.com/",
  "booths": [
    {
      "number": "1000",
      "label": "Exhibit Hall \u2014 1000"
    }
  ],
  "profileUrl": "https://packeast26.mapyourshow.com/8_0/exhibitor/exhibitor-details.cfm?exhid=02002727",
  "matchStatus": "matched",
  "industryFilter": {
    "status": "matched",
    "matches": [
      {
        "term": "Pet Food",
        "market": "Food > Pet Food/Pet Care"
      },
      {
        "term": "Pet Food",
        "market": "Other packaged products > Pet Food/Pet Care"
      }
    ]
  },
  "directoryOffset": 0
}
```

- **Directory entries:** names, event, website, booths, extraction and filter status.
- **Filter evidence:** observed taxonomies, matching evidence and field availability.
- **RUN\_SUMMARY:** discovered/checked counts, failures, stop reason and continuation information.
- **COMPANY\_GROUPS:** suggested groups of matched profiles (or all extracted profiles when no filter is requested), preserving each event's booth and source. Grouping uses the same normalized name, website host and path; it does not verify legal identity.
- **OUTPUT:** full workflow report, including diagnostics. Storage records are available from the run's Storage tab; output links point to those records.

### Continue a capped run

The Actor checks profiles in round-robin source order across your directories. It saves successful records as they arrive. A roughly 120-second work budget can end a batch before `maxProfiles`; use the default 180-second run timeout or longer.

If `RUN_SUMMARY.coverage.nextOffset` is not null, start a **new run** with the same directory URLs in the same order, set `startOffset` to that value, and copy `coverage.directoryFingerprint` into `expectedDirectoryFingerprint`. Each batch has its own start fee. If the directory's membership or order changed, continuation stops before profile collection; restart at offset 0 and deduplicate combined exports by `profileId`. Fingerprints do not detect changes inside individual profiles.

If a run is interrupted before its summary is written, the last saved dataset row provides `directoryOffset` and `directoryFingerprint`; continue with that offset plus one. Runs are not designed for Apify's Resurrect action. Company grouping applies to the current batch, not every prior batch.

A successful run with `limited` coverage is a capped batch, not a complete-event export. Discovery counts describe directory entries, not the number of profiles fetched or verified companies.

### Enrich selected exhibitor websites

Use [Website Contact Enricher](https://apify.com/samstorm/website-contact-enricher) as an optional second step. It inspects supplied websites for public emails, phones and source evidence; it has its own run and website fees.

1. Export this Actor's JSON. Select `status: "extracted"` and `matchStatus: "matched"`. If you intentionally requested no filters, select `not_requested` instead. Keep `unknown` and `not_matched` separate.
2. Review the company and website. Deduplicate identical website/name pairs while retaining a mapping to every original `profileId`. Different branch paths or business names should stay separate. A directory entry is not a verified company.
3. In Contact Enricher, clear **Website URLs** and use **Advanced website records**: copy `website`, use `profileId` as `inputId`, and copy `name` to `businessName`. Submit at most 100 website records per run.
4. Join the contact output back by `inputId`, not row order. Inspect row status and source evidence before using a contact. If you grouped profiles, map the retained ID back to every original profile.

Example from an owner-tested exhibitor website:

```json
{
  "targets": [{
    "website": "https://www.1-pack.us/",
    "inputId": "packexpo26.mapyourshow.com:12419945",
    "businessName": "1-Pack, Inc."
  }],
  "maxPages": 3,
  "runTimeoutSecs": 60
}
```

Set a contact-run timeout of at least 120 seconds and an event allowance of at least $0.025 for this one-website example. At standard prices, five extracted exhibitor profiles cost $0.04; a separate contact run with five readable websites costs $0.045, for $0.085 combined. If more profiles were extracted before selecting five websites, the first-stage cost is higher. Each Actor's live Pricing tab is authoritative.

On September 30, 2026 UTC, an existing owner export supplied five matched websites to a new contact run: all five IDs returned, four websites were readable, two had observed emails and three had phones. One offsite redirect produced a free diagnostic rather than a website-result fee. This small test reused a completed exhibitor run; it is not a customer case study, an email-delivery test or a promise of future coverage. For a redirect to a different domain, inspect the destination and supply its canonical URL if appropriate; the crawler does not automatically follow unrelated domains.

### Validation and support

Small owner tests succeeded on PACK EXPO East 2026, PACK EXPO International 2026 and IWF 2026. They establish the tested cases, not universal event compatibility or guaranteed field availability. Directories can include organizers, associations and amenities. Website ownership, contact availability, legal identity and buying intent are not verified. This Actor does not collect email addresses or enrich contacts.

For a failure or unsupported event, open an Apify issue with the gallery URL, input, run ID and expected behavior. Do not include API tokens or private customer data. Access blocks and source restrictions are reported without attempts to bypass them.

# Actor input Schema

## `directories` (type: `array`):

One to three Map Your Show /8\_0/explore/exhibitor-gallery.cfm URLs. Only featured=false and numeric georegion filters are supported; other query filters fail explicitly.

## `maxProfiles` (type: `integer`):

Maximum checked profiles across events, not matches. Up to 200; work or spending limits can end a batch sooner. All extracted rows are returned and charged.

## `maxDirectoryProfiles` (type: `integer`):

Oversized directories remain incomplete and are not expanded.

## `categoryTerms` (type: `array`):

Literal words or phrases matched against the profile's Product Categories. Missing categories remain unknown.

## `categoryMode` (type: `string`):

Match any requested product term or require every requested term.

## `industryTerms` (type: `array`):

Literal words or phrases matched only against explicitly labeled Vertical Markets. Other taxonomies remain separate.

## `industryMode` (type: `string`):

Match any requested industry term or require every requested term. Product and industry filters combine with AND.

## `startOffset` (type: `integer`):

For a new batch, copy coverage.nextOffset from the previous RUN\_SUMMARY. Nonzero offsets require its directory fingerprint.

## `expectedDirectoryFingerprint` (type: `string`):

Required for nonzero offsets. Copy coverage.directoryFingerprint from the previous RUN\_SUMMARY; use the same URLs and order.

## Actor input object example

```json
{
  "directories": [
    "https://packeast26.mapyourshow.com/8_0/explore/exhibitor-gallery.cfm?featured=false&georegion=4%7C537"
  ],
  "maxProfiles": 20,
  "maxDirectoryProfiles": 5000,
  "categoryTerms": [],
  "categoryMode": "any",
  "industryTerms": [],
  "industryMode": "any",
  "startOffset": 0
}
```

# Actor output Schema

## `entries` (type: `string`):

Successfully extracted profiles, including filter nonmatches and unknowns. Failed profiles appear in RUN\_SUMMARY.

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

No description

## `companies` (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 = {
    "directories": [
        "https://packeast26.mapyourshow.com/8_0/explore/exhibitor-gallery.cfm?featured=false&georegion=4%7C537"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("samstorm/map-your-show-exhibitor-scraper").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 = { "directories": ["https://packeast26.mapyourshow.com/8_0/explore/exhibitor-gallery.cfm?featured=false&georegion=4%7C537"] }

# Run the Actor and wait for it to finish
run = client.actor("samstorm/map-your-show-exhibitor-scraper").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 '{
  "directories": [
    "https://packeast26.mapyourshow.com/8_0/explore/exhibitor-gallery.cfm?featured=false&georegion=4%7C537"
  ]
}' |
apify call samstorm/map-your-show-exhibitor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,samstorm/map-your-show-exhibitor-scraper"
        }
    }
}
```

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/lf5Z8sv6Od8TwK2Is/builds/rDsKzIXbTvx1Oqbxu/openapi.json
