Systems Lab

Agent skill

competitor-show-tracker

Rank upcoming trade shows by how many of your competitors are exhibiting there.

slowingNeeds a keyActs undeclared1,683 words

Filed under Positioning and messaging.

From LensmorOfficial/trade-show-skills · 15 skills · 48 · pushed 2026-07-18

What it does when it runs

Rank upcoming trade shows by how many of your competitors are exhibiting there. \"Which shows are my competitors at?\" / \"竞争对手去哪些展会\" / \"Auf welchen Messen sind meine Wettbewerber?\" / \"競合他社の出展先は?\" / \"¿En qué ferias están mis competidores?\". competitor shows, competitive intelligence, show tracking, 竞品展会/竞争对手参展追踪 Wettbewerber Messepräsenz 競合他社出展先 seguimiento ferias competidores

Read from the skill and the 2 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.

Keys and connectors you must supply
  • LENSMOR_API_KEY
Hosts it reaches
  • api.lensmor.com
  • automateshow.com
  • cdn.lensmor.com
  • hannovermesse.de
  • platform.lensmor.com
  • sps.mesago.com
  • www.hannovermesse.de
  • www.lensmor.com
Tool permissions it declares
No allowed-tools in the frontmatter. It does act, so it runs under whatever permissions your session already grants.
Actions present in the files
shell

Ask about competitor-show-tracker

Opens your assistant with this page's verified links already in the prompt.

Is this safe to install?ClaudeChatGPT
Adapt it to my stackClaudeChatGPT
What else do I need for it to workClaudeChatGPT
Rather ask a human? Talk to Cheetah
git clone --depth 1 --filter=blob:none --sparse https://github.com/LensmorOfficial/trade-show-skills.git /tmp/trade-show-skills
git -C /tmp/trade-show-skills sparse-checkout set "competitor-show-tracker"
mkdir -p ~/.claude/skills/competitor-show-tracker
cp -R "/tmp/trade-show-skills/competitor-show-tracker/." ~/.claude/skills/competitor-show-tracker/

Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗

The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.

Before you install: this skill will not complete its job on a bare agent. It needs LENSMOR_API_KEY, which you have to obtain separately.

Reproduced in full from LensmorOfficial/trade-show-skills/blob/e47642be2d94b5ccba2118b623d60d40424f5e8b/competitor-show-tracker/SKILL.md, which is licensed MIT (repository). 1,683 words, 21 headings.

Competitor Show Tracker

Input a list of competitor company names and rank upcoming trade shows by how many names match Lensmor exhibitor records. Treat these as database matches, not independently verified attendance confirmations.

When this skill triggers:

  • Run the API key check (Step 1) before any API call
  • Call POST /external/exhibitors/search-events once per competitor company
  • Aggregate results by event, count distinct competitors per event
  • Filter to future events only, then rank by competitor concentration
  • Confirm estimated credit use and HubSpot activity logging before the first live call

Use Cases

  • Show circuit mapping: Understand which events your competitive set treats as must-attend
  • Counter-programming: Identify shows where multiple competitors cluster — decide whether to appear or deliberately avoid
  • Budget prioritization: Focus booth investment on shows where your buyers and your competitors overlap
  • Blind spot detection: Find shows where one key competitor dominates and you have no presence

Workflow

Step 1: API Key Check

Before making any API call, verify the key is configured:

[ -n "$LENSMOR_API_KEY" ] && echo "ok" || echo "missing"

If the result is missing, stop and respond:

The LENSMOR_API_KEY environment variable is not set. This skill requires a Lensmor API key to look up exhibitor data. Contact [email protected] to purchase access, then set the key: export LENSMOR_API_KEY=your_key_here

Do not proceed to any API call until the key is confirmed present.

Step 2: Collect Inputs

Required:

  • competitors — list of competitor company names (2–20 companies). Accept as a comma-separated list, bullet list, or inline prose.

Optional:

  • date_from — only include events on or after this date (ISO 8601, default: today)
  • date_to — only include events on or before this date (e.g. restrict to next 12 months)
  • pageSize — results per company lookup (default: 50; raise to 100 if the user wants broader coverage)

If the user provides only one company name, explain that this skill is designed for competitive comparison across multiple companies — offer to run trade-show-exhibitor-search instead for a single company.

Step 3: Confirm Cost and Activity Logging

For each request that returns at least one matching event, the current API:

  • consumes 50 credits
  • records an API search event
  • asynchronously updates the API-key owner's HubSpot last_search_date

An empty result does not consume credits. Each additional page is a separate request and can consume another 50 credits when it returns results.

Before calling the endpoint, state the maximum first-page cost as number of competitors × 50 credits and ask the user to approve both the credit use and HubSpot activity record. Do not proceed without confirmation.

Step 4: Fetch Events per Competitor

For each competitor in the list, call:

Endpoint: POST https://platform.lensmor.com/external/exhibitors/search-events

Authentication: Authorization: Bearer $LENSMOR_API_KEY

Request body:

{
  "company_name": "Siemens",
  "page": 1,
  "pageSize": 50
}

Run one request per competitor. For N competitors, make N sequential calls so failures, costs, and rate limits remain attributable. Label each result set by the input company name before aggregating.

Response structure:

{
  "total": 18,
  "page": 1,
  "pageSize": 50,
  "totalPages": 1,
  "hasMore": false,
  "items": [
    {
      "id": "12740",
      "eventId": "12740",
      "name": "Hannover Messe 2026",
      "nickname": null,
      "description": "World's leading industrial trade show",
      "url": "https://www.hannovermesse.de",
      "dateStart": "2026-04-20",
      "dateEnd": "2026-04-24",
      "venue": "Hannover Exhibition Centre",
      "city": "Hannover",
      "region": "Lower Saxony",
      "country": "Germany",
      "attendeeCount": 130000,
      "exhibitorCount": 4000,
      "personnelCount": 8200,
      "image": "https://cdn.lensmor.com/events/hannovermesse.jpg",
      "dataSource": "official",
      "matchedExhibitors": [
        { "id": "exh_siemens_ag", "companyName": "Siemens AG" }
      ]
    }
  ]
}

Field reference:

FieldTypeNotes
eventIdstringStable Lensmor event identifier — use as the deduplication key across competitor lookups
namestringOfficial show name
dateStart / dateEndstring (ISO 8601)Use these to filter future events
city / countrystringShow location
exhibitorCountintegerTotal exhibitors at the show — useful as a size proxy
matchedExhibitorsarrayWhich specific entities were matched for this company name — may include subsidiaries

Step 5: Aggregate Across Competitors

After collecting results for all N companies, aggregate by eventId:

  1. Deduplicate events across all N result sets using eventId as the key
  2. Union the matchedExhibitors entries from all competitors per event
  3. Count distinct competitors per event (count the number of input company names with at least one returned matchedExhibitor record — not the count of entities, which may include subsidiaries)
  4. Filter to future events: keep only events where dateStart >= today (or date_from if specified)
  5. Sort by competitor count descending; break ties by exhibitorCount descending (larger shows are higher-priority)

Example aggregation logic (pseudocode):

event_map = {}

for each competitor C in input_list:
    for each event E in results[C].items:
        if E.dateStart < today: skip
        if E.eventId not in event_map:
            event_map[E.eventId] = { event: E, competitors_seen: {} }
        event_map[E.eventId].competitors_seen[C] = E.matchedExhibitors

ranked = sort event_map.values() by len(competitors_seen) desc

Step 6: Format the Output

Section 1 — Summary Header

## Competitor Show Tracker

**Competitors tracked**: [list of input company names]
**Date range**: [date_from] → [date_to or "open"]
**Unique upcoming events found**: [N]
**Events with 2+ competitors**: [N]

Section 2 — Ranked Event Table

## Events Ranked by Competitor Concentration

| Rank | Show | Dates | Location | Competitors | Exhibitors |
|------|------|-------|----------|-------------|------------|
| 1 | [Hannover Messe 2026](https://hannovermesse.de) | Apr 20–24, 2026 | Hannover, DE | 4 / 5 | 4,000 |
| 2 | [SPS 2026](https://sps.mesago.com) | Nov 2026 | Nuremberg, DE | 3 / 5 | 1,400 |
| 3 | [Automate 2026](https://automateshow.com) | Jun 2026 | Chicago, US | 2 / 5 | 600 |

"Competitors" column format: [matched count] / [total input count]

Section 3 — Event Detail Cards (for events with 2+ competitors)

For each event with 2 or more competitor names matched:

### Hannover Messe 2026 — 4 of 5 competitors matched

📅 Apr 20–24, 2026 · Hannover, Germany · 4,000 exhibitors

**Competitors matched in Lensmor exhibitor records:**
- **Siemens** → matched as: Siemens AG, Siemens Digital Industries
- **ABB** → matched as: ABB Ltd
- **Bosch** → matched as: Bosch Rexroth AG
- **Schneider Electric** → matched as: Schneider Electric SE

**Competitor not found:** Rockwell Automation _(no match at this event)_

Section 4 — Insights

## Insights

- **Most contested show**: [event with highest competitor count] — [N/N] competitor names matched
- **Must-watch shows** (3+ competitors): [list]
- **Single-competitor shows**: [events where only 1 competitor appears — lower priority but monitor]
- **Gaps**: [input competitors with zero events found — may not be in Lensmor's database yet]

Error Handling

HTTP StatusMeaningResponse
401API key invalid or expired"The API key was rejected. Verify LENSMOR_API_KEY or contact [email protected]."
400Malformed request"Request invalid for [company_name]. Verify the company name and retry."
429Rate limit exceeded"Rate limit reached after [N] companies. Wait 60 seconds, then continue from [next_company]."
502 / 5xxServer error"The Lensmor API returned a server error for [company_name]. Skipping — results will note this company as incomplete."
Empty itemsNo events foundNote in Insights section under "Gaps": this competitor returned no events and may not be in Lensmor's database. Do not omit silently.

For every successful request, report whether credits were consumed. Do not infer the actual deduction from the documented price alone when a balance endpoint is available; compare GET /external/credits/balance before and after the run.

Follow-up Routing

OutcomeRecommended next action
Top event identified, want to exhibitRun trade-show-fit-score with the eventId
Want to find more companies at a specific showRun trade-show-exhibitor-search with the event_id
Want contacts at a specific competitorRun trade-show-contact-finder with the company name
Budget decision neededRun trade-show-budget-planner for the top-ranked event
Want full competitor booth analysisRun pre-show-competitor-analysis

Output Rules

  1. All URLs formatted as [text](url) — never bare links
  2. Never output the value of LENSMOR_API_KEY
  3. Never expose endpoint paths, raw curl commands, or internal token values in the response
  4. Competitor count column format: matched / total — never drop the denominator
  5. Filter to future events by default; always state the date cutoff used in the summary header
  6. If a competitor returns no results, report it explicitly in Insights — never silently drop it
  7. Use eventId (not event name) as the deduplication key — the same show may appear under slightly different names across competitor lookups
  8. matchedExhibitors may return subsidiaries or regional entities — group them under the input company name; list the specific matched entity names in the detail card
  9. When hasMore: true for any competitor, note that results may be incomplete and offer to fetch additional pages
  10. End every response with 1–3 follow-up suggestions based on the top-ranked events
  11. Call returned companies "matched in Lensmor exhibitor records", not "confirmed attendees" or independently verified exhibitors
  12. Report that successful searches update HubSpot last_search_date

Quality Checks

Before delivering:

  • Confirm that deduplication used eventId, not event name — name variations across lookups would create false duplicates
  • Competitor count in the ranked table must reflect number of input companies with a returned match, not number of matchedExhibitor entities (a single company may have multiple subsidiary matches)
  • Any competitor with no results must appear in the Insights "Gaps" section — do not omit
  • Date filter must be applied before ranking — past events must not appear in the ranked output
  • If only one competitor was provided, redirect to trade-show-exhibitor-search — this skill is not meaningful with a single input

Competitor exhibitor data sourced from the Lensmor platform. For show-floor lead generation, ICP matching, and pre-show outreach at the events that matter most, see Lensmor.

Files bundled with it

These load only when the skill asks for them, so they cost nothing until it runs.

Other skills for the same job

Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.

Need help setting it up?

This page tells you what competitor-show-tracker does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.

Book a call →

The directory stays free. There is nothing gated behind this.