← Plugin catalog
Business & Operations

ZoomInfo

ZoomInfo Technologies LLC v6.1.0

ZoomInfo — B2B company and professional intelligence. Use for prospecting, finding people at companies, current and past employment, job changes, org charts, executives, verified business contact information, company research, intent, Scoops, and GTM signals.

Language: English · Automatically detected from descriptions.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package author
ZoomInfo Technologies LLC

Package observed Sep 30, 2026.

Changes

ZoomInfo

Sep 30, 2026 · 1 saved observations

Technical updates

Newly listed paths: .DS_Store. This compares saved file lists, not package contents; a different collection source can change the list.

Skill evidence →

Files & skills

File archives

Plugin package37 files · 70.8 KBBrowse files →
Skill instructions
account-health3.67 KB

View saved version →

---
name: account-health
description: 'Assess the health of an account from its recent conversations — sentiment trajectory and risk signals — backed by an engagement timeline and an account_research snapshot. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "how healthy is Acme", "are we at risk of churn here", "what''s the sentiment trend", or wants a risk read before a QBR or renewal. Strictly evidence-based: it does not invent risk or generic advice, and it asks the user for input where the conversations do not settle the question.'
---

# Account Health

A grounded read on where an account's health is heading: the sentiment trend, the real risk signals, and what to do about them — only what the evidence supports.

## Prerequisites

`browse_engagements` (timeline) requires an active calendar/email/meeting integration; `conversation_intelligence` (sentiment/risk) requires at least one connected source; `conversation_intelligence` and `account_research` consume AI credits. If no conversation data exists, the health read is limited to CRM/firmographic signal — say so explicitly rather than implying a confident verdict.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Context** (optional but valuable) — anything the user knows that conversations won't show: renewal timing, recent escalations, exec sponsor changes, usage/adoption data. Ask for this if a health call hinges on it.

## Workflow

1. **Resolve the account.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Gather evidence.** Build a recent timeline with `browse_engagements` (cadence and any drop-off in contact), run `conversation_intelligence` for sentiment trajectory and risk signals across recent conversations, and pull an `account_research` snapshot for deal/relationship context. Keep CI scoped to the account; it sees only the last few engagements and cannot count or topic-search, so treat its read as recent signal, not a full trend line.
3. **Check before concluding.** If the evidence is thin or mixed, or a verdict depends on something the data does not show (renewal date, usage, an off-platform escalation), ask the user for that input before writing the assessment. Do not fill gaps with generic churn-risk boilerplate.
4. **Assess.** Give a health read with a clear direction and a confidence level, every claim tied to specific evidence. Separate what the data shows from what is inferred or assumed.

## Output Format

### Account health — [Company]

**Read** — one line: healthy / watch / at-risk, with a confidence level (and why confidence is what it is).

**Sentiment trajectory** — how tone and engagement have moved across recent conversations, with source moments.

**Risk signals** — specific, evidence-backed signals (a gone-quiet champion, an unresolved escalation, slipping cadence). Omit anything you cannot support; do not pad.

**Strengths** — what is genuinely going well, if anything, with evidence.

**Recommended actions** — one to three concrete, evidence-tied moves. If the evidence does not support a confident recommendation, say what to confirm first instead.

### Evidence discipline

Lead with what the conversations and data actually show. Mark inferences as inferences. Where you asked the user for input, fold their answer in and attribute it. A short, honest read beats a padded one.

### When there is no data

If conversation data is unavailable, give the CRM/firmographic view only, state that sentiment and conversational risk could not be assessed, and point the user to their ZoomInfo admin.
account-relationship-recap3.22 KB

View saved version →

---
name: account-relationship-recap
description: Recap where things stand with a company across recent conversations, with emphasis on how the relationship is evolving. Identify the account by ZoomInfo company ID (preferred) or by name or domain (triggers a lookup). Blends account_research for deal and firmographic context with company-scoped conversation_intelligence for what has actually been said recently. Use when someone asks "where are we with Acme", "how is the relationship trending", "recap our recent conversations with this account", or wants a relationship read before a check-in. Reasons over the last few engagements only.
---

# Account Relationship Recap

Where we stand with an account, read from recent conversations: the current state, and the direction it is moving.

## Prerequisites

Company-scoped `conversation_intelligence` requires at least one connected email or meeting source; `account_research` and `conversation_intelligence` consume AI credits (`browse_engagements`, used for optional cadence, is free). If no conversation data exists for the account, produce the `account_research`-based read and note that conversation context was unavailable, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Lens** (optional) — e.g. "renewal risk", "expansion", "post-exec-change". Frames the recap.

## Workflow

1. **Resolve the company.** Use the ZoomInfo ID directly; otherwise resolve a name/domain via `search_companies` and confirm an ambiguous match before spending credits.
2. **Read the relationship.** Run `account_research` (deal status, history, stakeholders) and company-scoped `conversation_intelligence` in parallel. Ask CI what has been discussed recently, how sentiment and engagement have shifted, which threads are open, and whether new people have entered the conversation. Keep CI scoped to this one account; it cannot search by topic or count mentions, and sees only the last few engagements.
3. **Anchor cadence (optional).** If useful, call `browse_engagements` (company-scoped, `-chronological`) for the recent engagement cadence and the gap since last contact.
4. **Synthesize the trajectory.** Decide whether the relationship is warming, steady, or cooling, and say why with evidence. Tie every claim to a source (CI, account_research, CRM). Do not assert momentum or risk the data does not support.

## Output Format

### Where we stand — [Company]

**Trajectory** — one line: warming / steady / cooling, with the evidence in a clause.

**Recent conversations** — 3-5 bullets on what has actually been discussed lately (from CI, with source meetings).

**What's changed** — the relationship shifts that matter: new or departed stakeholders, a change in tone or responsiveness, momentum gained or lost. Each tied to evidence.

**Open threads / risks** — what is unresolved or worth watching.

**Suggested next step** — one evidence-based move (only if the data points to one).

### When there is no data

If conversation data is unavailable, give the `account_research` view and state plainly that the relationship-trajectory read is limited without connected conversation history.
account-research9.36 KB

View saved version →

---
name: account-research
description: Produce a full intelligence brief on a target company — firmographics, CRM/account context, intent signals, recent news, scoops, and competitive landscape — framed by your GTM context and led with a TL;DR summary. Identify the account by ZoomInfo account/company ID (preferred) or by company name, domain, or ticker (which triggers a lookup step). Include detailed context on why the brief is being pulled.
---

# Account Research

Produce a high-signal intelligence brief on a target company. Lead with a synthesized executive summary, suppress sections where data is thin, and tie next steps to specific people and concrete topics surfaced during research.

## Input

The user will provide via `$ARGUMENTS` an account identifier (required) plus optional context:

- **Account identifier (required)** — one of:
  - **Preferred**: a ZoomInfo account/company ID (numeric, e.g. `136118787`). Use directly as `companyId`; skip the search step.
  - **Fallback**: a company name, domain, or ticker. Resolve to a `companyId` via `search_companies` as a first step (see Workflow step 2).
- **Research context (strongly recommended)** — a sentence or two on *why* this brief is being pulled and what decision it supports. Examples: "preparing for a QBR — focus on renewal risk and expansion levers", "competitive analysis vs. Acme — looking for displacement angles", "cold outbound — find the warmest entry point and a credible reason to reach out". This shapes the `account_research` query, intent seeding, news/scoops triage, and the TL;DR framing.

## Workflow

1. **Anchor on purpose.** Read the research context from `$ARGUMENTS`.
   - If supplied, restate it in one sentence as the *brief purpose* and keep it in mind as the framing lens for every downstream step.
   - If missing, ask the user once for the purpose. If they decline or say "just general intel", default to **general account intelligence** and state that assumption at the top of the brief so the reader knows the framing wasn't tailored.
   - Use the purpose to derive 2-4 *priority GTM themes* (e.g., QBR-renewal-risk → engagement health, exec stability, competing vendors, expansion signals). These themes drive seeding and triage in later steps.

2. **Get GTM context.** Call `get_gtm_context` to retrieve your organization's offerings, ICP, personas, competitors, and strategic priorities. Use this to frame findings throughout. If empty, proceed without — and omit the GTM Fit section.

3. **Resolve the company.**
   - If the user supplied a ZoomInfo account/company ID, use it directly as `companyId` — do not call `search_companies`.
   - Otherwise, call `search_companies` with the appropriate field (`companyWebsite` for a domain, `companyTicker` for a ticker, `companyName` for a name) and extract `companyId` from the top match. If no confident match, surface the ambiguity to the user before continuing rather than guessing.

4. **Fetch in parallel (retrieval, not filtering).** Treat each tool call as a context-retrieval step. Pull broadly now; decide what's relevant during synthesis. Steps that only need the `companyId` can run in parallel — `enrich_companies`, `account_research`, `enrich_company_signals` (intent, news, and scoops in one call — see below), and `find_similar_companies`.
   - **Tailor the `account_research` query to the brief purpose.** Don't pass a generic "tell me about this account" string. Instead, name the purpose and the priority themes — e.g., *"Preparing for a QBR. Surface renewal status, contract dates, recent engagement, open expansion conversations, named champions and detractors, and any signs of competitive evaluation."* The more context the better.
   - **Signals retrieval.** Call `enrich_company_signals` with the `companyId` and `signalTypes: ["INTENT", "NEWS", "SCOOP"]` (or omit `signalTypes` to get all three). It returns the company's recent intent topics, news, and scoops in a single call; score thresholds, topic resolution, and recency are handled server-side, so do **not** pre-filter — triage in step 5.

5. **Synthesize.** Each retrieval is raw context — now decide what makes the brief, framed by the user's stated purpose. Apply these principles:
   - **Intent triage**: review every intent topic returned by `enrich_company_signals`. Keep topics that map to the brief purpose, the priority themes, your GTM offerings, or that suggest a non-obvious signal worth flagging (e.g., a competitor's category, an adjacent buying motion). Drop topics that are noise or irrelevant to the purpose. If nothing meaningful remains, replace the table with a one-line note.
   - **Purpose-weighted news/scoops relevance**: the brief purpose is the primary tiebreaker. Start from the base news priority (PERSON / FUNDING / M&A / PRODUCT > GENERAL_PRESS_RELEASE > GENERAL_NEWS), then promote items that map to the priority themes (e.g., for a competitive brief, a product launch can outrank a routine leadership move; for a renewal QBR, a layoff or budget-cut signal outranks a generic product release). Dedupe items covering the same theme; trim to 5-7.
   - **Cross-reference**: a new CTO scoop + cloud migration intent → connect the dots, and connect them *to the user's stated goal*.
   - **Past-date flag**: if `account_research` surfaces dates in the past (renewal, contract end, last activity, scheduled meeting), flag them as needing verification — could be active negotiation, stale CRM sync, or a missed milestone.
   - **Cohort consistency**: if the `find_similar_companies` cohort spans inconsistent industries vs. the target, flag that the peer set is directional rather than exact.
   - **Section suppression**: skip the funding table for public mega-caps (just reference the ticker); skip GTM Fit if no GTM context; flatten scoops if only 1-3 returned.

6. **Write the exec summary last.** Re-read the body, then write the TL;DR at the top. The Situation line must explicitly answer *"why this brief, now"* against the user's stated purpose — not just "who they are."

## Output Format

### TL;DR — [Company Name]

*Brief purpose: [restate the user's research context in one line, or "general account intelligence (no purpose supplied)" if defaulted].*

**Situation.** [2-4 sentences answering *why this brief, now* against the stated purpose: who they are, the dominant story now, where the relationship stands, and the specific signal(s) that make this purpose timely.]

**Top 3 facts.** Three most consequential data points across all sources.

**Highest-leverage actions.** 1-3 concrete actions, each pointing at a specific person, pilot, topic, or moment.

---

### Company Snapshot

| Field | Value |
|-------|-------|
| Website | |
| Industry | |
| Employees | |
| Revenue | |
| HQ | |
| Type | (Public/Private) |
| Ticker | |
| Founded | |
| ZoomInfo ID | |

### GTM Fit

*Omit if no GTM context was returned.*

- **ICP Match**: industry, size, geography fit
- **Offering Relevance**: which products map to this account's signals
- **Competitive Presence**: any defined competitors in their news/scoops/stack
- **Persona Alignment**: do their org charts include your target personas

### Account Context

Summarize `account_research`: relationship status, engagement, deal context, named contacts. If any surfaced dates are in the past, note them with a verification prompt (could be active negotiation, stale CRM sync, missed milestone, or closed-deal lag — recommend confirming with the account team). If dates fall within the next 30 days, surface them in the TL;DR instead.

### Intent Signals

Show only the topics retained after triage in step 5 — topics the company is actively expressing intent on that map to the brief purpose, priority themes, your offerings, or a non-obvious signal worth flagging.

| Topic | Signal Score | Audience Strength | Category | Signal Date |
|-------|-------------|-------------------|----------|-------------|

Highlight the top 3 and tie them to your offerings or the user's stated context. Replace the table with a one-line note if nothing meaningful survived triage.

### Recent News & Scoops

Group news by Financial / People / Product / General if 5+ items span categories; otherwise list flat. For each: headline, date, one-line summary, source URL. Then list scoops — group by Leadership Moves / Growth Signals / Strategic Moves / Risk Signals only if 4+ returned, otherwise flat. Call out timing opportunities (e.g., new CTO → vendor evaluation likely).

### Competitive Landscape

If the cohort's industries are inconsistent with the target, lead with a one-line caveat that peers are directional. Then show the top 10:

| # | Company | Industry | Employees | Revenue | Country | Similarity |
|---|---------|----------|-----------|---------|---------|------------|

Note patterns: direct competitors vs. adjacent players vs. peers; how the target compares on size and market position.

### Corporate Structure

- **Ultimate Parent / Parent**: if applicable
- **Funding**: total raised, most recent round + date + amount. For public mega-caps (revenue > $5B), replace with "Public — see ticker for capital structure."

### Key Takeaways & Next Steps

3-5 bullets connecting the dots across sources, framed by the user's stated purpose. Then suggest concrete next actions — each must reference a specific person, pilot, deal, topic, or moment surfaced above, with a clear rationale tied to the brief purpose. No generic skill mentions or boilerplate. Omit any line that doesn't have a concrete target.
ae-cs-handoff3.55 KB

View saved version →

---
name: ae-cs-handoff
description: Produce an AE-to-CS handoff brief — everything the incoming CSM needs from the sales conversations. Builds an engagement timeline, then runs conversation_intelligence in parallel on the key engagements to pull requirements, success criteria, stakeholders and how they like to work, and the relationship state. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone says "build the handoff for Acme", "what does the CSM need to know", "prep the post-sale transition", or closes a deal that needs a clean handoff.
---

# AE-to-CS Handoff Brief

Capture what was promised, what success looks like, and who the people are — so the CSM starts from context, not a cold account.

## Prerequisites

`browse_engagements` (timeline) requires an active calendar/email/meeting integration; `conversation_intelligence` (the deep read) requires at least one connected source and consumes AI credits, as do `account_research` and `contact_research`. If no conversation data exists, build the structural handoff from research and flag that the conversational detail (requirements, working style) is missing, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Context** (optional) — the product sold, deal size, go-live timing, anything the CSM specifically needs.

## Workflow

1. **Resolve the account.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Build the timeline.** Call `browse_engagements` (account-scoped) for the sales-cycle engagements; identify the few that carry the most signal (discovery, key demos, negotiation, commitments). Limit to roughly the 2-4 highest-signal engagements — each gets its own `conversation_intelligence` call in step 3, which costs AI credits, so do not fan out across the whole timeline. Keep their engagement IDs.
3. **Deep-read the key engagements in parallel.** Run `conversation_intelligence` on those engagement IDs (one CI call per engagement) for stated requirements and success criteria, commitments made to the customer, decision-makers and how they like to work, and any sensitivities. Pull `account_research` and `contact_research` for the structural picture. CI sees only the last few engagements, so anchor on the key ones rather than expecting full history.
4. **Assemble the handoff.** Synthesize a CSM-ready brief. Distinguish what was promised (must be honored) from what was aspirational. Attribute each requirement and commitment to the conversation it came from. Do not invent commitments.

## Output Format

### AE-to-CS handoff — [Company]

**Deal summary** — what was sold, why they bought (the core problem and desired outcome), in 2-3 lines.

**Success criteria** — how the customer defined success, in their words, with sources.

**Commitments made** — what the AE promised the customer (and any timelines). These transfer to the CSM.

**Stakeholders** — per key person: role, influence, champion/skeptic, and how they like to work (cadence, format, sensitivities) where the conversations show it.

**Open items & risks** — anything unresolved at close that the CSM inherits.

**Recommended first move** — the CSM's best opening action, tied to the above.

### When there is no data

If conversation data is unavailable, give the research-based account and stakeholder structure, and flag that requirements, commitments, and working style could not be captured from conversations.
build-list3.83 KB

View saved version →

---
name: build-list
description: Build a list of contacts or companies matching specific criteria. Describe what you're looking for in natural language and get a structured, tabular list you can export. Supports filtering by title, seniority, department, industry, company size, location, tech stack, growth rate, and more. Outputs a clean table artifact.
---

# Build List

Build a targeted list of contacts or companies from ZoomInfo and output as a structured table.

## Input

The user will describe what they want via `$ARGUMENTS`. Examples:
- "CTOs at Series B+ startups in SF with 50-200 employees"
- "VP of Sales at healthcare companies using Salesforce with 500+ employees"
- "All SaaS companies in EMEA with $10M-$50M revenue"
- "Directors of Engineering at companies similar to Datadog"
- "Marketing leaders at Fortune 500 companies in financial services"

The user may also specify:
- How many results they want (default: 25)
- Whether they want contacts, companies, or both
- Specific fields to include in the output

## Workflow

1. **Determine list type**: Is the user asking for contacts, companies, or both? Default to contacts if they mention titles/roles, companies if they mention firmographics only.

2. **Parse criteria** from natural language into structured filters:
   - Job titles, management levels, departments, job functions → contact filters
   - Industry, employee count, revenue, geography, tech stack, company type → company filters
   - Growth rate, funding, rankings → company filters

3. **Resolve all filter values** using `lookup` before searching. This is critical — do NOT guess values. For every filter you plan to use, call `lookup` with the corresponding field name to get the valid values and use the returned `id` values in your search parameters.

4. **Execute the search**:
   - For **contacts**: Use `search_contacts` with all resolved filters. Sort by `-contactAccuracyScore`. Request up to 100 results.
   - For **companies**: Use `search_companies` with all resolved filters. Sort by `-employeeCount` or `-revenue`. Request up to 100 results.
   - For **both**: Search companies first, then search contacts at the top results.

5. **Enrich top results** if the search returns limited detail:
   - Use `enrich_contacts` (batch of 10) or `enrich_companies` (batch of 10) on the top results to fill in emails, phones, and other details.

6. **Output as a clean table artifact.** Create a markdown or CSV artifact the user can copy or export.

## Output Format

### Search Criteria Applied

Show the user exactly what filters were used so they can verify:

| Filter | Value |
|--------|-------|
| Management Level | Vice President |
| Industry | Computer Software |
| Employee Count | 51-100, 101-250 |
| Metro Region | San Francisco-Oakland-Hayward, CA |
| ... | ... |

### Contact List (if contact search)

| # | Name | Title | Company | Email | Direct Phone | Accuracy | Location |
|---|------|-------|---------|-------|-------------|----------|----------|
| 1 | | | | | | | |
| 2 | | | | | | | |

### Company List (if company search)

| # | Company | Industry | Employees | Revenue | HQ Location | Website | ZoomInfo ID |
|---|---------|----------|-----------|---------|-------------|---------|-------------|
| 1 | | | | | | | |
| 2 | | | | | | | |

### List Summary
- **Total results found**: X (showing top Y)
- **Filters applied**: [summary]
- **Average accuracy score**: X (contacts only)
- **Data quality**: Flag any concerns (low accuracy, stale records)

### Refinement Options
If the list is too broad or too narrow, suggest specific filter adjustments:
- "Add `revenue` filter to narrow from 847 to ~200 results"
- "Remove metro region filter to expand from 12 to ~150 results"
- "Try adjacent industries: Information Technology Services, Internet"

If the user wants to iterate, they can re-run with adjusted criteria. Suggest the exact modified command.
buying-committee14.7 KB

View saved version →

---
name: buying-committee
description: Map the buying committee at a target account. Identifies decision-makers, prioritizes who to engage, and surfaces gaps and multi-thread risks. Leads with a TL;DR (top 3 to engage, biggest gap, multi-thread risk), uses compact tables, and deep-researches top stakeholders to catch stale records. Identify the account by ZoomInfo account/company ID (preferred) or by company name, domain, or ticker (which triggers a lookup step). Include detailed context on the deal, situation, and persona priorities driving the map.
---

# Buying Committee

Map the buying group at a target account — who matters, what role they play, and who to engage first. Output is scannable: headline first, compact tables, deeper profiles only for the top 3-5.

## Input

The user will provide via `$ARGUMENTS` an account identifier (required) plus optional context:

- **Account identifier (required)** — one of:
  - **Preferred**: a ZoomInfo account/company ID (numeric). Use directly as `companyId`; skip the search step.
  - **Fallback**: a company name, domain, or ticker. Resolve to a `companyId` via `search_companies` as a first step (see Workflow step 3).
- **Research context (strongly recommended)** — a free-form description of *why* this committee map is being pulled and what decision it supports. Richer is better — flat enums and persona one-liners produce flat maps. Capture as much as is true: the deal stage and value, the product/offering in play, recent activity or stalls, who's already engaged, who's missing, competitive pressure, persona priorities (e.g., "security leadership", "VP Engineering and above"), timing constraints, and any working hypothesis the user wants tested. Examples:
  - *"Stage 3 deal, $400K ARR, security platform replacing Acme. We've talked to the Director of SecOps but the CISO is quiet — looking for the actual economic buyer and any procurement/legal blockers. Worried about a single-threaded relationship."*
  - *"Cold prospecting into a target ICP account. No prior engagement. Find the warmest entry point for a Data Platform pitch — likely Eng or Data leadership, but flag adjacent personas (CFO if cost story, CISO if data residency)."*
  - *"Renewal in 90 days, current champion left last quarter. Need the new owner and anyone on the customer's side who could block renewal or push for expansion."*

If the identifier is ambiguous (e.g., a bare string that could be a name or a ticker), prefer the most specific interpretation: all-digits → ID; short all-caps token (≤5 chars) → ticker; a string containing a dot or known TLD → domain; otherwise → name.

## Workflow

Parallelize aggressively — once the company is resolved, account research, enrichment, recommendations, scoops, and supplemental search can all fan out in parallel.

1. **Anchor on purpose.** Read the research context from `$ARGUMENTS`.
   - If supplied, restate it in 1-2 sentences as the *map purpose* and keep it as the framing lens for every downstream step.
   - If missing, ask the user once for the context. If they decline or say "just general mapping", default to **general committee mapping for prospecting** and state that assumption at the top of the brief.
   - From the context, derive: a **map purpose** (1 line), **priority personas/functions** (3-6 — e.g., CISO, SecOps Director, Procurement Lead, CFO), a **best-fit use case enum** for `get_recommended_contacts` (`PROSPECTING` / `DEAL_ACCELERATION` / `RENEWAL_AND_GROWTH`), and any **named hypotheses to test** (e.g., "find the actual economic buyer", "identify replacement champion"). These priorities drive the `account_research` query, `search_contacts` filters, scoops triage, and synthesis.

2. **Lookup metadata first** — call `lookup` for any fields relevant to the request (management levels, departments, job functions). Use returned `id` values in subsequent calls.

3. **Get GTM context** — call `get_gtm_context` with `detailed: true` to retrieve full personas, ICP segments, offerings, and competitors. The detailed mode matters here because committee mapping benefits from full persona definitions. If empty, proceed without and note the gap in the TL;DR.

4. **Resolve the company.**
   - If the user supplied a ZoomInfo account/company ID, use it directly as `companyId` — do not call `search_companies`.
   - Otherwise, call `search_companies` with the appropriate field (`companyWebsite` for a domain, `companyTicker` for a ticker, `companyName` for a name) and extract `companyId` from the top match. If no confident match, surface the ambiguity to the user before continuing rather than guessing.
   - Then `enrich_companies` for firmographics including `employeeCountByDepartment`.

5. **Fetch in parallel (retrieval, not filtering).** Treat each tool call as a context-retrieval step. Pull broadly now; decide what's relevant during synthesis. Steps that only need the `companyId` (plus inputs from step 1) can run in parallel — `account_research`, `get_recommended_contacts`, `search_contacts`, `enrich_company_signals` (`signalTypes: ["SCOOP"]`) / `search_scoops`.
   - **Tailor the `account_research` query to the map purpose.** Don't pass a generic "tell me about this account" string. Inject the full research context — name the deal stage, the offering, named hypotheses, persona priorities — and ask for named individuals organized by function, engagement status, deal context (stage, last activity, competition), and any signals about budget owners, blockers, or champions. The more context the better.
     - Normalize engagement to two states: **Engaged** (explicit prior interaction signal) or **New** (everything else, including ambiguous). Default to New when in doubt.
     - If `account_research` surfaces dates in the past (renewal, contract end, last activity), retain them but tag for verification — they may signal active negotiation, broken CRM sync, or a missed milestone.
   - **`get_recommended_contacts`** — pass the use-case enum derived in step 1. Treat as supplemental signal. Empty results are common (cold-start tenants, no CRM data); note as a confidence indicator rather than retrying.
   - **`search_contacts`** — filter by the priority personas/functions derived in step 1 (resolved against `lookup` IDs from step 2 and GTM personas from step 3). Sort by `-contactAccuracyScore`. Pull broader than you'll keep — filtering happens in step 7.
   - **`enrich_company_signals` (`signalTypes: ["SCOOP"]`) / `search_scoops`** — no role filter. Retrieval is unconstrained; step 7 will triage for VP+ moves relevant to the priority personas and named hypotheses.

6. **Enrich and deep-research** — merge contacts from step 5, dedupe by `personId`:
   - `enrich_contacts` in batches of 10 on the top 20 merged contacts. `NO_MATCH` failures are normal — note them, don't retry.
   - `contact_research` in parallel on the top 3-5 (ranked by seniority + engagement + fit to priority personas + relevance to named hypotheses). This is where stale records get caught — if research indicates the person has departed, route them to **Excluded / Needs Verification**, not the main map.

7. **Synthesize.** Each retrieval is raw context — now decide what makes the map, framed by the map purpose, priority personas, and named hypotheses. Apply these principles:
   - **Scoops triage**: review every scoop returned. Keep **New Hire / Lateral Move / Executive Move / Promotion** at VP+ level, especially in the priority personas or adjacent functions named in the context. For each newly-named person, run `search_contacts` if not already enriched and add to the committee with a `RECENTLY APPOINTED` flag and the event date. These often pre-date what `account_research` knows. Drop scoops irrelevant to the map purpose.
   - **Search/recommendation triage**: from the broad `search_contacts` and `get_recommended_contacts` pulls, keep contacts that fit a priority persona, address a named hypothesis (e.g., "find the actual economic buyer"), or fill a coverage gap visible from `account_research`. Drop everyone else — broad retrieval is fine, broad output isn't.
   - **Role classification (conservative)**:
     - **Champions** require explicit engagement evidence (CRM activity, demo attended, prior emails). Title alone is never sufficient — without a signal, place under Influencers > Potential Champions.
     - **Technical Evaluators** are Director+ in IT, Engineering, or the function being sold to. Sales Ops VPs are Influencers > Operations unless the product evaluates against criteria they own.
     - **Economic Buyers** hold budget — C-Level Finance, the function head sponsoring the deal, or CEO for strategic deals.
     - **Influencers** use named sub-buckets (Strategic Partnerships, Communications, Adjacent Marketing, M&A / Corp Dev, Operations, Legal / Compliance, HR / Talent, Potential Champions). Skip empty buckets.
   - **Hypothesis check**: explicitly address each named hypothesis from step 1 — did the data confirm, contradict, or fail to resolve it? Surface the answer in the TL;DR.
   - **Source tagging**: tag every contact with source — `[from account_research]`, `[from search]`, `[from recommendations]`, `[from scoops]`. Flag source disagreements.

8. **Write the exec summary last.** Re-read the body, then write the TL;DR at the top, framed by the map purpose.

## Output Format

### Buying Committee: [Company Name]

**[Industry]** | **[Employees]** | **[Revenue]** | **[HQ]**

### TL;DR

*Map purpose: [restate the user's research context in one line, or "general committee mapping for prospecting (no context supplied)" if defaulted].*

One paragraph framed by the map purpose. Top 3 contacts to engage (named, one-line reasoning each, tied to the purpose), biggest coverage gap (specific role/function with risk), multi-threading risk in one sentence, and a one-line answer to each named hypothesis from the research context (confirmed / contradicted / unresolved). If a past-date reference came back from `account_research`, lead with: *"Renewal/contract date in CRM appears stale — verify deal state before acting on this map."*

### Company Snapshot

One-paragraph context — what they do, where they sit in the buying journey.

### GTM Fit

Omit this section if no GTM context was retrieved. Otherwise:
- **ICP Match**: fit assessment
- **Persona Coverage**: matched / partial / missing — flag gaps
- **Relevant Offerings**: which products apply
- **Competitive Presence**: any defined competitors at the account

### Account Context

- **Deal Status**: stage, value, close date, competition
- **Engaged Stakeholders**: who we've talked to
- **Key Signals**: intent, recent activity, executive appointments from scoops
- **Open Issues / Blockers**: from CRM

If a past date was surfaced: *"`account_research` references [event] on [date], in the past. Verify deal state before relying on the engagement strategy below."*

### Committee Map (visual, additive)

After the contact tables below, include a `mermaid flowchart TD` block showing the committee organized by role with engagement state color-coded (engaged / new / recently appointed / stale-excluded / gap) and the recommended sequencing path overlaid (e.g., green dashed arrows for "engage 1st → 2nd → 3rd"; red dashed for "departed, replaced by"). Keep the chart additive — every name in it must also appear in a contact table below, since not all markdown clients render mermaid (Slack, plain email, basic viewers fall back to the code block).

Use a class definition block at the top so the colors render consistently:
```
classDef engaged fill:#d4edda,stroke:#155724,color:#155724
classDef new fill:#f8f9fa,stroke:#6c757d,color:#212529
classDef recent fill:#fff3cd,stroke:#856404,color:#856404
classDef stale fill:#f8d7da,stroke:#721c24,color:#721c24
classDef gap fill:#e2e3e5,stroke:#383d41,color:#383d41,stroke-dasharray: 5 5
```

Then below the chart, a one-line legend: `🟢 Engaged · ⚪ New · 🟡 Recently appointed · 🔴 Stale (excluded) · ⬛ Gap`.

### Committee Map (tables)

Per category, lead with a 5-column table.

#### Economic Buyers

| Name | Title | Email | Status | Source |
|------|-------|-------|--------|--------|

#### Champions

| Name | Title | Email | Status | Source |
|------|-------|-------|--------|--------|

(Explicit engagement evidence required. If none: "No Champions identified — see Potential Champions under Influencers.")

#### Technical Evaluators

| Name | Title | Email | Status | Source |
|------|-------|-------|--------|--------|

#### Influencers

Group by named sub-bucket (Strategic Partnerships, Communications, Adjacent Marketing, Operations, Legal, HR, Potential Champions, etc.). One 5-column table per bucket that has contacts.

#### Recently Appointed (last 90 days)

| Name | Title | Appointment Date | Email | Status |
|------|-------|------------------|-------|--------|

These also appear in their primary category with a `RECENTLY APPOINTED` flag — this is a duplicated index for visibility.

### Key Stakeholders (top 3-5)

Richer profiles for the deep-researched contacts.

#### [Name] — [Title]
- **Role**: Economic Buyer / Champion / Technical Evaluator / Influencer:Sub-bucket
- **ZoomInfo counterpart**: mapped internal contact based on title (CEO ↔ ZoomInfo CEO, CRO ↔ ZoomInfo CRO, etc.; use GTM context for explicit mappings if defined)
- **Background**: career summary, time in role
- **Engagement history**: prior interactions, or "No prior engagement recorded"
- **Why they matter**: tied to role and account context
- **Flags**: `stale data`, `research data limited`, `RECENTLY APPOINTED`, source disagreements
- **Recommended approach**: specific to active pilots, current operational engagement, or pending decision moments

### Engagement Strategy

Specific to this account — not a generic playbook. Anchor each step to a named person and a real account-context signal (active pilot, recent appointment, contract date, coverage gap).

1. **Immediate priorities (next 2 weeks)**: top 3 actions, each tied to a specific person and signal.
2. **Coverage gaps**: specific empty persona slots — "No Finance stakeholder below the CFO; Director-level FP&A search recommended."
3. **Sequencing**: ordered outreach with named people and reasons.
4. **Multi-threading risk**: current single-thread dependencies and the moves to fix them.

### Excluded / Needs Verification

| Name | Reason | Recommended Action |
|------|--------|--------------------|

Use for: contacts confirmed departed via deep research, `NO_MATCH` failures with no fallback, account_research records flagged for data quality issues. Do **not** include in the main map.

### Next Steps

Concrete next actions, each referencing a specific person, persona gap, hypothesis, or moment surfaced above — and tied to the map purpose. No generic skill mentions or boilerplate. Omit any line that doesn't have a concrete target.
call-coaching3.41 KB

View saved version →

---
name: call-coaching
description: Coach a rep on how they handled a specific call — discovery quality, objection handling, talk dynamics, and next-call focus. Name the call if you know it, or let the skill pull recent calls and identify the most likely candidate to confirm. Uses conversation_intelligence to read how the conversation actually went. Use when someone asks "how did I do on the Acme call", "coach me on my last discovery call", "where did I lose them", or wants actionable feedback before the next conversation. Analyzes one call at a time.
---

# Call Coaching

Give a rep specific, actionable feedback on a single call: what worked, what to improve, and what to focus on next time.

## Prerequisites

`browse_engagements` (to find the call) is free but requires an active calendar/meeting integration; `conversation_intelligence` (to analyze it) requires at least one connected meeting source and consumes AI credits. If the call has no transcript to analyze, say so rather than coaching from assumption.

## Input

Provided via `$ARGUMENTS`:

- **Which call** (optional) — an account and/or date. If omitted, the skill identifies the most likely recent call and confirms before analyzing.
- **Focus** (optional) — e.g. "discovery", "the pricing objection", "did I talk too much". Targets the coaching.

## Workflow

1. **Identify the call.** `browse_engagements` filters by date and by company/contact ID, not by call name, so resolve any named account or contact first via `search_companies` / `search_contacts`, then call `browse_engagements` (`engagementType: MEETINGS`, `sort: -chronological`) scoped to that ID and date window and pick the matching meeting from the results. If nothing was named, call `browse_engagements` for the user's recent meetings, propose the most likely candidate, and confirm it before spending credits. If more than one meeting plausibly matches, ask. Keep the chosen engagement ID.
2. **Analyze how it went.** Run `conversation_intelligence` scoped to that engagement ID. Ask how the rep handled discovery (did they uncover pain, budget, timeline, decision process), how objections were handled, what the customer's reactions and sentiment were, and where the conversation stalled or advanced. Keep the query scoped to this one call.
3. **Coach against good practice.** Assess the call against solid discovery and objection-handling fundamentals — open questions over pitching, listening over talking, surfacing next steps, addressing concerns directly. Ground every point in a specific moment from the call; cite what was said. Be candid and useful, not generic. If the transcript is too thin to judge something, say so rather than inventing a critique.

## Output Format

### Call coaching — [Call title, date]

**What went well** (2-3) — specific strengths, each tied to a moment in the call.

**What to improve** (2-3) — the highest-leverage changes, each with the moment that shows it and a concrete alternative ("when they raised price, you discounted; instead anchor on the value point from earlier").

**Talk dynamics** — a quick read on balance (who drove, listening vs pitching, questions asked) if the data supports it.

**Focus for the next call** — one or two things to do differently next time, tied to where this deal now stands.

### When there is no data

If the call cannot be found or has no transcript, tell the user and offer to coach from notes they provide, rather than fabricating an assessment.
call-recap4.14 KB

View saved version →

---
name: call-recap
description: Recap a recent call with a tight summary, the decisions made, action items, and open questions. Name the call (account and/or date) if you know it, or let the skill pull your most recent calls and offer a shortlist to pick from. Uses conversation_intelligence to read what was actually said, with light account_research for deal context. Use when someone says "recap my last call", "what came out of the Acme meeting", "summarize yesterday's call", or needs a post-call writeup. The output adapts to the request — for example decisions-only or action-items-only.
---

# Call Recap

Turn a just-finished call into a compact, high-signal recap: what was discussed, what was decided, who owns what, and what is still open.

## Prerequisites

`browse_engagements` (to find the call) requires an active calendar/email/meeting integration. `conversation_intelligence` (to read the call) requires at least one connected meeting or email source. Both `conversation_intelligence` and `account_research` consume AI credits. If no conversation data is available for the call, say so and point the user to their ZoomInfo admin rather than guessing at content.

## Input

Provided via `$ARGUMENTS`:

- **Which call** (optional) — an account and/or a date ("the Acme call", "yesterday's demo"). If omitted, the skill lists recent calls to pick from.
- **Emphasis** (optional) — e.g. "just the action items", "what did we decide", "for my manager". Shapes the output.

## Workflow

1. **Identify the call.**
   - If the user named an account or date, resolve the account via `search_companies` first if needed (`browse_engagements` filters by company/contact ID and date, not by call name), then call `browse_engagements` (`engagementType: MEETINGS`, `sort: -chronological`) scoped to that ID and date window and confirm the match.
   - If nothing was named, call `browse_engagements` for the user's recent meetings and present a numbered shortlist (date, title, account, participants). Let the user pick one (or several) before spending AI credits. Keep each chosen engagement's ID.

2. **Read the call with `conversation_intelligence`.** Scope CI to the chosen engagement ID and ask for a structured read: what was discussed, decisions made, action items with owners and any stated due dates, open questions, and notable customer statements. For multiple selected calls, run one CI call per engagement (do not ask one CI call to span several). Keep the query specific to that engagement; CI cannot search by topic or count mentions.

3. **Add light context (optional).** If deal/relationship framing helps, pull `account_research` for the account — kept brief. Skip it if the user just wants the recap itself; this is a recap, not a full account brief.

4. **Synthesize.** Write the recap from the CI output. Attribute decisions and action items only when the conversation supports them; never invent an owner or a due date that was not stated (mark those "owner not stated" / "no date given"). Cite the source meeting.

## Output Format

Default compact template (adapt to the user's emphasis):

**[Call title] — [date]**
*Participants: [names].*

**Summary** — 2-4 sentences on what the call was about and where it landed.

**Decisions**
- [Decision, with who made/agreed it if stated.]

**Action items**
- [Owner — action — due date or "no date given"]

**Open questions / unresolved**
- [What is still hanging, with the source moment.]

**Suggested next step** *(one line, only if the conversation points to one.)*

### Adapting the template

If the user asked for a subset ("just action items", "decisions for the QBR notes"), lead with that section and trim the rest. If they asked for a manager-facing version, keep it to summary + decisions + next step. Match the format to the request rather than always emitting every section.

### When there is no call or no data

If no recent calls are found, say so and ask the user to name the account or widen the date range. If a call is found but `conversation_intelligence` has no transcript for it (e.g. not recorded, or indexed within the last several hours), report that the recording was not available to analyze rather than fabricating a recap.
commitment-ledger2.81 KB

View saved version →

---
name: commitment-ledger
description: Build a ledger of what we promised versus what they promised, and what is still outstanding, across the last few engagements with an account or contact. Uses conversation_intelligence as the primary source. Identify the account or contact by ZoomInfo ID (preferred) or name (triggers a lookup), or point it at specific calls. Use when someone asks "what did we commit to", "what are they supposed to send us", "what's still outstanding with this account", or wants an accountability check before a follow-up. Covers the last few engagements only, not full history.
---

# Commitment Ledger

A two-sided accounting of promises across recent conversations: ours, theirs, and what is still open.

## Prerequisites

`conversation_intelligence` requires at least one connected email or meeting source and consumes AI credits. `browse_engagements` (used to scope or pick engagements) requires an active integration and is free. If no conversation data exists, say so rather than presenting an empty ledger as "no commitments".

## Input

Provided via `$ARGUMENTS`:

- **Scope** (required) — an account (company ID or name/domain), a contact (contact ID or name + company), or specific calls to review.
- **Emphasis** (optional) — e.g. "just what they owe us", "anything tied to the contract". Shapes the output.

## Workflow

1. **Resolve scope.** Use a ZoomInfo ID directly, or resolve a name via `search_companies` / `search_contacts`. If the user wants specific calls and none are named, present a `browse_engagements` shortlist to pick from before spending credits.
2. **Extract commitments.** Run `conversation_intelligence` scoped to the account, contact, or chosen engagement. Ask it to list commitments by side (what we said we would do; what they said they would do), with status and the source meeting. Keep CI scoped to one ID per call; it sees only the last few engagements and cannot count or topic-search, so frame this as a recent-commitments ledger, not an exhaustive audit.
3. **Reconcile.** Mark each commitment open, done, or unclear based on later conversations. Flag anything overdue or contradicted. Attribute every line to a source meeting; do not list a commitment the conversation does not support.

## Output Format

### Commitment Ledger — [Account / Contact]

*Covers the last few engagements (through [date]). Not a full-history audit.*

**We owe them**
| Commitment | Made on | Status |
|------------|---------|--------|

**They owe us**
| Commitment | Made on | Status |
|------------|---------|--------|

**Outstanding / overdue** — a short list of what most needs chasing, with who owns it.

### When there is no data

If no conversation data is available for the scope, report that the ledger cannot be built from conversations and point the user to their ZoomInfo admin to confirm integration coverage.
company-intent-monitor2.59 KB

View saved version →

---
name: company-intent-monitor
description: Monitor a company's buyer-intent signals and assess fit against your GTM context. Uses company signals scoped to intent for a single account, returns the recent topics it is researching, and analyzes which ones align with your offerings and ICP. Identify the company by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "what is Acme researching", "are they showing intent on anything we sell", "monitor intent for this account", or wants an intent read before prioritizing an account.
---

# Company Intent Monitor

What is this account actively researching, and does any of it line up with what we sell?

## Prerequisites

`enrich_company_signals` charges data credits — each intent signal returned counts as a record, but companies already under management (enriched within the last 12 months) are free. `get_gtm_context` is free. Intent availability depends on your ZoomInfo package; if no intent is on file, that is a real (and useful) answer, not an error.

## Input

Provided via `$ARGUMENTS`:

- **Company** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`. If none is supplied, ask which company.
- **Focus** (optional) — topics or themes you care about, to weight the alignment read.

## Workflow

1. **Set the lens.** Call `get_gtm_context` (free) for your offerings, ICP, and competitors — the basis for judging which topics matter.
2. **Resolve the company.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
3. **Pull intent.** Run `enrich_company_signals` with `signalTypes: ["INTENT"]` for the company. Read the topics, their signal scores, and recency.
4. **Analyze alignment.** Map each topic against your offerings and ICP: which topics indicate demand for something you sell, which point at a competitor's category, and which are noise. Call out the strongest aligned topics. Do not stretch a loosely related topic into a fit it does not have.

## Output Format

### Intent monitor — [Company]

**Recent intent topics**

| Topic | Signal score | Recency |
|-------|--------------|---------|

Strongest first.

**Alignment with your offerings** — the topics that map to what you sell (and which offering), with a one-line reason each. Note any competitor-category intent separately.

**Read** — 1-2 lines: what the pattern suggests and whether this account is worth prioritizing now.

**If there is no active intent** — say so plainly; absence of intent is a legitimate result, and it means this account is not currently showing research-based demand.
company-news-monitor2.39 KB

View saved version →

---
name: company-news-monitor
description: Monitor recent news and business events for a company and deliver a quick digest. Uses company signals scoped to news and scoops for a single account, grouped by type and recency, with a "so what" for each. Identify the company by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "what's the latest news on Acme", "any recent developments at this account", "catch me up on what's happening there", or wants a news digest before a touchpoint.
---

# Company News Monitor

A fast read on what has happened at an account lately, and which of it is worth acting on.

## Prerequisites

`enrich_company_signals` charges data credits — each news article or scoop returned counts as a record, but companies already under management (enriched within the last 12 months) are free. `get_gtm_context` (optional, for relevance flagging) is free. News and scoop availability depends on your ZoomInfo package.

## Input

Provided via `$ARGUMENTS`:

- **Company** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`. If none is supplied, ask which company.
- **Lens** (optional) — e.g. "anything about expansion", "leadership changes only". Filters the digest.

## Workflow

1. **Resolve the company.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Pull news and events.** Run `enrich_company_signals` with `signalTypes: ["NEWS", "SCOOP"]` for the company.
3. **Add a relevance lens (optional).** If useful, call `get_gtm_context` (free) so you can flag items that touch your offerings, a competitor, or a known priority.
4. **Build the digest.** Group items by type (funding, M&A, product, leadership/executive moves, expansion, financial results, partnerships, and general news), most recent first. For each, give the date, the headline, a one-line "so what", and the source. Do not editorialize beyond what the item supports.

## Output Format

### News & developments — [Company]

Grouped, most recent first:

**[Category]**
- **[date]** — [headline]. *So what:* [one line]. [source]

**Worth acting on** — the one or two items that create a timely outreach opening, if any, with the angle. Omit if nothing rises to that bar.

**If nothing recent** — say there is no notable recent news or scoop activity on file rather than padding the digest with stale or trivial items.
competitor-analysis12 KB

View saved version →

---
name: competitor-analysis
description: Produce a fact-led competitive intel brief on one or more competitors — firmographics, recent strategic moves, product positioning, ICP overlap, and discovery questions. Defaults to your configured competitors from GTM context if none specified. Combines ZoomInfo data (account_research, scoops, intent, exec teams, similar companies) with web search for product/pricing/customer-sentiment intelligence. Identify competitors by ZoomInfo account/company ID (preferred) or name; include rich context on why the brief is being pulled and what decision it supports.
---

# Competitor Analysis

Produce a fact-led competitive intel brief. Lead with an executive comparison across competitors, then a per-competitor section. Pull positioning verbatim from the GTM context — don't invent your own opinions about who wins or who's the biggest threat.

## Input

The user will provide via `$ARGUMENTS`:

- **Competitor identifiers (optional)** — zero or more of:
  - **Preferred**: ZoomInfo account/company IDs (numeric). Use directly as `companyId`; skip the search step for that competitor.
  - **Fallback**: competitor names. Resolve via `search_companies` (use `companyWebsite` from GTM context's `url` field if present; otherwise `companyName`).
  - If omitted entirely, default to all competitors configured in your GTM context.
  - For named competitors NOT in GTM context, flag as "uncovered" — research proceeds, but pre-built positioning is missing.
- **Research context (strongly recommended)** — a free-form description of *why* this brief is being pulled and what decision it supports. Richer is better — flat depth enums and deal one-liners produce flat briefs. Capture as much as is true: the deal or situation in play, what you're losing or winning on, the offering or product line under pressure, the audience for the brief (AE prep / leadership review / enablement), how exhaustive the analysis needs to be, and any specific angles or hypotheses to test. Examples:
  - *"Losing the mid-market segment to Clay on data orchestration. Need to understand their recent product moves, pricing, and where their customer reviews show cracks. AE-facing — concrete discovery questions matter most."*
  - *"Quarterly competitive review for leadership. All configured competitors. Want a scannable Executive Comparison plus 90-day strategic moves. Depth on each is light."*
  - *"Deep dive on Acme before a head-to-head bake-off next month. Their security platform vs ours. Want G2/TrustRadius sentiment themes, recent CISO commentary, and the exact products they'd field against our SKUs."*

This context drives depth allocation (deep vs scan), the `account_research` query framing, scoops/news triage, web-search angles, and the discovery-question slant.

## Workflow

Parallelize aggressively — once each competitor's company ID is resolved, all per-competitor calls can fan out in parallel. When briefing multiple competitors, run all competitors' fan-outs in the same parallel batch.

1. **Anchor on purpose.** Read the research context from `$ARGUMENTS`.
   - If supplied, restate it in 1-2 sentences as the *brief purpose* and keep it as the framing lens for every downstream step.
   - If missing, ask the user once. If they decline or say "just general competitive intel", default to **general competitive scan across configured competitors** and state that assumption at the top.
   - From the context, derive: a **brief purpose** (1 line), **depth allocation** (which competitors get deep treatment vs lighter coverage), **priority angles** (3-5 — e.g., pricing, data orchestration, CISO-level positioning, G2 sentiment), and any **named hypotheses** to test (e.g., "test whether Clay's mid-market push is sustainable"). These drive the `account_research` query, scoops triage, and web-search angles.

2. **Get GTM context** — call `get_gtm_context` with `detailed: true`. This is the **anchor source**: it contains your defined competitors with `products`, `reasonsTheyWin`, `reasonsTheyLose`, `customersWeWon`, and `competitiveProducts`. Quote these verbatim in the output — they're pre-built positioning content, not your interpretation.

3. **Determine the competitor set** — match user-named competitors (or IDs) against the GTM-context list. If user named none, brief all configured. Flag uncovered competitors as noted in Input.

4. **For each competitor, fan out in parallel (retrieval, not filtering).** Treat each tool call as a context-retrieval step. Pull broadly now; decide what's relevant during synthesis.
   - **Resolve company ID** — if the user supplied a ZoomInfo ID, use directly; otherwise `search_companies` (use `companyWebsite` from GTM context's `url` field if present; fall back to `companyName`).
   - **Firmographics** via `enrich_companies` (full field set including `employeeCountByDepartment`, `companyFunding`, `recentFundingDate`, `totalFundingAmount`).
   - **Strategic narrative** via `account_research` — inject the brief purpose, priority angles, and named hypotheses into the query. Ask for go-to-market motion, recent moves, customer wins/losses, leadership changes, direct overlap with your products, and anything that bears on the specific angles named in the context.
   - **Recent scoops and intent** via `enrich_company_signals` (`signalTypes: ["SCOOP", "INTENT"]`) — one call returns their recent scoops and intent topics, with no role or topic pre-filtering. Triage in step 7. Intent for competitors often returns sparse — note as a confidence indicator if so.
   - **Their executive team** via `search_contacts` (`managementLevel: "C Level Exec,VP Level Exec"`, sort by `-contactAccuracyScore`, `pageSize: 15`).
   - **Their similar companies** via `find_similar_companies` — apply the cohort-consistency check; if the top peers span inconsistent industries vs the target, flag as directional only.

5. **Web search per competitor** — `WebSearch` targeted to the priority angles from step 1. At minimum: G2 reviews / TrustRadius sentiment, head-to-head comparisons (`"[Competitor] vs [Your Org]"`), recent product launches, public earnings/CEO statements (if public). For deep targets, add angle-specific queries (e.g., pricing, specific product lines, customer churn stories). Capture verifiable quotes with URLs. **Cross-check exec data**: if `account_research` named a CEO, verify against web — stale CEO records have been observed.

6. **Date and currency checks** — if `account_research` surfaces dates in the past (renewal, contract end, exec tenure end, last activity), retain but flag for verification. If a CEO or other top exec named in `account_research` is contradicted by web search, lead with the corrected fact and note the source disagreement.

7. **Synthesize.** Each retrieval is raw context — now decide what makes the brief, framed by the brief purpose and priority angles. Apply these principles:
   - **Intent triage**: from the `enrich_company_signals` intent topics, keep those that map to the brief purpose, priority angles, or non-obvious competitive signals worth flagging. Drop noise. If nothing meaningful remains, say so explicitly — don't infer roadmap from absence.
   - **Scoops triage**: keep product launches, exec moves at VP+, partnerships, M&A, hiring patterns relevant to the priority angles. Drop generic press releases.
   - **Verbatim positioning**: pull `reasonsTheyWin`, `reasonsTheyLose`, `customersWeWon` **verbatim** from GTM context. Do not paraphrase or add your own opinions.
   - **Recent moves**: dated, sourced, described without interpretation ("Acquired Pocus on Mar 19" — not "Aggressive M&A signals confidence").
   - **ICP overlap**: classify each of your defined ICPs against the competitor's apparent reach (High / Partial / None) using firmographics and `customersWeWon` evidence.
   - **Discovery questions**: 3 per competitor (more for deep targets), anchored in a specific gap, priority angle, or surfaced fact. Not generic.
   - **Hypothesis check**: explicitly address each named hypothesis from step 1 — confirmed / contradicted / unresolved. Surface in the Executive Comparison preamble.
   - **Avoid** threat ranking, "biggest threat" calls, or whitespace synthesis — these require win-rate and pipeline data the skill doesn't have.

## Output Format

### Executive Comparison

*Brief purpose: [restate the user's research context in one line, or "general competitive scan (no context supplied)" if defaulted].*

**Hypothesis check** (one line per named hypothesis from the input): confirmed / contradicted / unresolved.

A single side-by-side table covering all competitors:

| | Competitor 1 | Competitor 2 | Competitor 3 |
|---|---|---|---|
| HQ / Founded | | | |
| Type / Funding | total raised + most recent round + date | | |
| Revenue (range) | | | |
| Employees (Eng / Sales / Mktg) | | | |
| CEO | | | |
| Most recent strategic move | one-line + date | | |
| Public G2 rating (if pulled) | | | |
| Defined by [Your Org] as primary competitor for | from GTM context `competitiveProducts` | | |

Below the table, a short **Recent product/strategy moves (last 90 days, all competitors)** bulleted list — one to three bullets per competitor, with `[scoops]` / `[web]` / `[CRM]` source tags.

Then a **⚠️ Data quality flags** block listing any failures or uncertain data — failed intent calls, weak similarity cohorts, stale exec records caught by web cross-check, framework errors. Be specific.

---

### [Competitor Name]

**Snapshot.** One-paragraph context — what they do, key exec team (CEO / CTO / CMO / CRO / CPO), department headcount weights from `employeeCountByDepartment`.

**Recent moves (last 90 days)** with `[source]` tags — bulleted, dated, no interpretation. Lead with M&A and exec moves; then product launches; then hiring patterns. Include URLs for web-sourced items.

**Product positioning (per [Your Org]'s defined competitive matrix):**

| Their product | Your product (per GTM context) |
|---|---|
| | |

Map their products to the items in GTM context's `competitiveProducts` field for this competitor.

**Per GTM context** `[GTM]`:
- *reasonsTheyWin*: [verbatim from GTM context — bulleted]
- *reasonsTheyLose*: [verbatim from GTM context — bulleted]
- *customersWeWon*: [verbatim from GTM context — bulleted]

**ICP overlap with [Your Org]'s defined ICPs:**
- High: [ICP names where the competitor competes hard]
- Partial: [ICP names where they touch but it's not their focus]
- None: [ICPs they don't compete in]

(Use firmographics + `customersWeWon` as evidence. If unclear, mark as "Partial".)

**G2 / web sentiment** `[web]` (if pulled): rating + N reviews. 1-2 themes from praise, 1-2 themes from criticism. Source URLs.

**Intent signal** `[intent]` (if returned): 1-line note. If 0 signals returned, say so explicitly — don't infer roadmap from absence.

**Discovery questions to ask in deal:**

1. [Question rooted in a specific `reasonsTheyLose` weakness or a verified gap]
2. [Question that surfaces a feature/capability they're missing]
3. [Question grounded in a recent move or specific deal-stage friction]

---

### [Next Competitor Name]

(Repeat the structure above per competitor.)

---

### Skill Issues to Fold Back

If anything failed or returned unreliable data during the run, list it here so the next iteration can pick it up:
- Tool errors (parameter type bugs, 400s)
- Weak `find_similar_companies` cohorts
- Stale `account_research` records caught by web search
- Empty `enrich_company_signals` intent results

This section can be omitted if everything ran cleanly.

## Notes on what NOT to do

- **Don't invent threat rankings** ("top threat", "fastest mover", "most displaceable"). The skill doesn't have win-rate or pipeline data to back these calls.
- **Don't paraphrase** `reasonsTheyWin` / `reasonsTheyLose` / `customersWeWon` — quote them verbatim. They're pre-built positioning your org has approved.
- **Don't interpret roadmap from absence of intent signals** — competitors often return sparse intent.
- **Don't synthesize a cross-competitor whitespace section** — that requires win/loss data this skill doesn't pull.
- **Don't pad** — if a section has thin data, say so explicitly rather than filling with interpretation.
contact-relationship-recap3.08 KB

View saved version →

---
name: contact-relationship-recap
description: Recap where things stand with a specific person across recent conversations, with emphasis on how the relationship is evolving. Identify the contact by ZoomInfo contact ID (preferred) or by name plus company (triggers a lookup). Blends contact-scoped conversation_intelligence for what this person has actually said recently with contact_research for their role and background. Use when someone asks "where are we with Jane", "is this person still our champion", "recap my conversations with this contact", or wants a read on an individual relationship before reaching out. Reasons over the last few engagements only.
---

# Contact Relationship Recap

Where we stand with one person, read from recent conversations: their posture toward us, and how it is changing.

## Prerequisites

Contact-scoped `conversation_intelligence` requires at least one connected email or meeting source; `conversation_intelligence` and `contact_research` consume AI credits. If no conversation data exists for the person, give the `contact_research`-based read and note that conversation context was unavailable, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Contact** (required) — ZoomInfo contact ID (preferred), or a name plus company to resolve via `search_contacts`.
- **Lens** (optional) — e.g. "is the champion still engaged", "did sentiment cool after the demo". Frames the recap.

## Workflow

1. **Resolve the contact.** Use the ZoomInfo contact ID directly; otherwise resolve via `search_contacts` (name + company) and confirm an ambiguous match before spending credits.
2. **Read the relationship.** Run contact-scoped `conversation_intelligence` and `contact_research` in parallel. Ask CI what this person has raised across recent conversations, how engaged and positive they have been, what they have committed to, and whether their stance has shifted. Keep CI scoped to this one contact; it cannot search by topic or count mentions, and sees only the last few engagements.
3. **Synthesize posture and trajectory.** Classify the person's current posture (engaged champion, supportive, neutral, skeptical, gone quiet) and whether it is strengthening or weakening, with evidence. Do not infer a champion or a risk the conversations do not support.

## Output Format

### Where we stand with [Name] — [Title, Company]

**Posture** — one line: engaged champion / supportive / neutral / skeptical / gone quiet, with the evidence.

**Recent from them** — 3-5 bullets on what this person has actually said or asked for lately (from CI, with source meetings).

**What's changed** — shifts in engagement, tone, or influence; e.g. went quiet after a reorg, warmed up after a successful pilot. Tied to evidence.

**Commitments / open asks** — what they promised or are waiting on from us.

**Suggested next step** — one evidence-based move to re-engage or advance the relationship.

### When there is no data

If conversation data is unavailable, give the `contact_research` view and state that the relationship read is limited without connected conversation history.
daily-brief4.12 KB

View saved version →

---
name: daily-brief
description: Brief the user on their day. Pull today's (or a named day's) meetings and, for each, synthesize the current state of play, a suggested focus or objective, and any follow-ups needed. Uses browse_engagements for the schedule, then account_research, contact_research, and conversation_intelligence per meeting. Use when someone says "what's on my plate today", "brief me for my meetings", "prep my day", or wants a morning rundown before back-to-back calls. Because it researches every meeting, it can consume meaningful AI credits — it confirms scope before fanning out across a full day.
---

# Daily Brief

Give the user a fast, per-meeting rundown of their day: where each account stands, the one thing to drive, and what to follow up on.

## Prerequisites

`browse_engagements` (the schedule) requires an active calendar/meeting integration; `conversation_intelligence` requires at least one connected meeting or email source. `account_research`, `contact_research`, and `conversation_intelligence` all consume AI credits, and this skill calls them once per meeting — so a full day of meetings can be credit-heavy. Confirm scope before fanning out (see Workflow step 2). If no integration is connected, report that and point the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Day** (optional) — defaults to today. "Tomorrow", "Monday", or a date all work.
- **Filter** (optional) — e.g. "customer meetings only", "just external", a specific account. Defaults to external meetings (ones with non-colleague participants).

## Workflow

1. **Get the schedule.** Call `browse_engagements` with a window covering the target day (`engagementType: MEETINGS`, `sort: chronological`). Drop internal-only meetings (no external participants) unless the user asked for everything.

2. **Size it and confirm.** Count the external meetings. Each one fans out three AI-credit calls (`account_research`, `contact_research`, `conversation_intelligence`), so the spend adds up quickly — even a handful of meetings is a non-trivial number of AI credits. If there are more than a few (roughly 3+), tell the user the meeting count, note that each is researched with several AI-credit calls, and offer to scope down (external customer meetings only, the most important few, or a named subset) before proceeding. This pause keeps a packed calendar from turning into a large unprompted credit spend.

3. **Research each meeting (parallel, bounded).** For the in-scope meetings, fan out per meeting: `account_research` (kept light — this is a day view, not a full brief), `contact_research` for the attendees, and `conversation_intelligence` scoped to the account or the specific engagement for recent state and open items. Parallelize across meetings, but respect the volume you confirmed in step 2. Keep each CI query scoped to one account or engagement; CI cannot search by topic, filter by call type, or count mentions, and only reasons over the last few engagements — base each card on what it returns, not on it having full history.

4. **Synthesize one card per meeting.** Frame each around the single most useful outcome for that meeting. Pull follow-ups from prior commitments surfaced by CI. Do not pad cards with generic firmographics — lead with what changes how the user shows up.

## Output Format

### Your day — [N] meetings ([date])

For each meeting, in time order:

**[time] · [title] — [account]**
- **State of play**: 1-2 lines on where things stand (from CI + research).
- **Focus**: the one outcome to drive in this meeting.
- **Follow-ups**: open commitments or items to close, from prior conversations (or "none surfaced").
- **Who's in the room**: attendees with role, one line.

Close with a single **Watch-outs** line across the day if anything connects (a renewal clock, a slipping deal, an exec sitting in) — only if it is evidence-based, not generic.

### When the day is empty or data is thin

If no meetings are found, say the day looks clear (for the chosen filter) rather than erroring. For any meeting with no conversation data, base its card on research only and note that no prior-conversation context was available.
decision-process-mapper2.93 KB

View saved version →

---
name: decision-process-mapper
description: Map a prospect's buying process as voiced on recent calls — their stated decision criteria, timeline, steps, and approvers. Uses conversation_intelligence over an account's recent engagements, with account_research for stakeholder context. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "what's their buying process", "who actually signs off", "what's the timeline and what do they need to decide", or wants to qualify a deal against MEDDIC-style criteria. Captures only what was actually stated; gaps are marked as unknown rather than inferred.
---

# Decision-Process Mapper

Reconstruct how the prospect actually buys, from what they have told you: criteria, steps, timeline, and the people who decide.

## Prerequisites

`conversation_intelligence` requires at least one connected meeting or email source; `conversation_intelligence` and `account_research` consume AI credits. If no conversation data exists, build what you can from `account_research` and mark the rest unknown, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Framework** (optional) — e.g. "MEDDIC", "just the approvers and timeline". Shapes which fields to foreground.

## Workflow

1. **Resolve the account.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Extract the process.** Run `conversation_intelligence` scoped to the account, asking what the prospect has said about how they will decide: the decision criteria, the evaluation steps, the timeline and any deadlines, the budget or procurement process, and who is involved in or approves the decision. Run `account_research` for the org/stakeholder picture. Keep CI scoped to one account; it sees only the last few engagements and cannot topic-search, so map what was said, not the whole sales cycle.
3. **Map, and mark gaps honestly.** Assemble the process. For anything not actually stated in conversation, label it **not stated** rather than inferring it. Distinguish a named approver from a guessed one. Tie each filled field to the source moment.

## Output Format

### Decision process — [Company]

| Element | What they said | Source / status |
|---------|----------------|-----------------|
| Decision criteria | | |
| Evaluation steps | | |
| Timeline / deadline | | |
| Budget / procurement | | |
| Decision-makers & approvers | | |
| Champion | | |

Use **not stated** in any cell the conversations did not cover.

**Biggest gaps** — the two or three unknowns that most need confirming, and a question to surface each on the next call.

### When there is no data

If conversation data is unavailable, present the `account_research` stakeholder view, mark the process fields unknown, and note the read is limited without connected conversation history.
draft-follow-up3.19 KB

View saved version →

---
name: draft-follow-up
description: Draft a follow-up email after a call by extracting the commitments and next steps that were actually agreed, then writing a compact, friendly-professional message. Name the call if you know it, or let the skill pull recent calls to pick from. Uses conversation_intelligence to read what was said and committed. Use when someone says "draft a follow-up to that call", "send a recap email", "write the follow-up for my Acme meeting", or needs a post-call note. Drafts only what the conversation supports — it does not invent commitments.
---

# Draft Follow-Up

Turn what was said on a call into a tight follow-up email: thank, recap, and confirm next steps.

## Prerequisites

`browse_engagements` (to find the call) is free but requires an active calendar/email/meeting integration; `conversation_intelligence` (to read it) requires at least one connected meeting or email source and consumes AI credits. If no conversation data exists for the call, say so rather than drafting from assumption.

## Input

Provided via `$ARGUMENTS`:

- **Which call** (optional) — an account and/or date. If omitted, the skill lists recent calls to pick from.
- **Tone / recipient** (optional) — e.g. "warm", "more formal for the exec", "to the whole room". Defaults to friendly-professional, addressed to the primary external attendee.

## Workflow

1. **Identify the call.** `browse_engagements` filters by date and by company/contact ID, not by call name, so resolve any named account/contact first via `search_companies` / `search_contacts`, then call `browse_engagements` scoped to that ID and date window and pick the matching meeting. If nothing was named, present a numbered shortlist of recent calls and let the user pick before spending credits. Keep the engagement ID.
2. **Extract what was said.** Run `conversation_intelligence` scoped to that engagement ID for the agreed next steps, commitments on each side, decisions, and any open questions to address in the note. Keep the query scoped to this one engagement.
3. **Confirm direction if ambiguous.** If the recipient or tone is unclear, or the call surfaced sensitive points, pause and confirm with the user before drafting.
4. **Draft the email.** Write a concise message: a one-line thanks, a 2-3 sentence recap, a clear list of next steps with owners and any dates, and a single call to action. Include only commitments the conversation actually supports; never invent an owner, a date, or a promise. Keep it skimmable.

## Output Format

**Subject:** [specific, references the meeting or its outcome]

**Body:**
> [Greeting.]
>
> [One-line thanks + 2-3 sentence recap of what was discussed and where it landed.]
>
> Next steps:
> - [Owner — action — date, if stated]
>
> [One-line close with the call to action.]
>
> [Sign-off.]

Present the draft for review; this skill drafts only and does not send. After the draft, list the **commitments extracted** (us vs them) so the user can verify nothing was added or missed. Offer to adjust tone, length, or recipient.

### When there is no data

If the call cannot be found or has no transcript to read, tell the user and ask them to name the call or supply the key points to draft from, rather than fabricating a recap.
email-thread-summarizer2.86 KB

View saved version →

---
name: email-thread-summarizer
description: Summarize a long email thread into its current state, the decisions and key points, and the open questions. Finds the thread with browse_engagements (emails), then uses conversation_intelligence with includeContent to read the actual thread body. Name the account, contact, or subject if you know it, or let the skill list recent threads to pick from. Use when someone says "summarize this email thread", "what's the state of the Acme thread", "catch me up on this email chain", or faces a long back-and-forth before replying. Summarizes one thread at a time.
---

# Email Thread Summarizer

Collapse a long email chain into what matters: where it stands, what was decided, and what is still open.

## Prerequisites

`browse_engagements` (to find the thread) requires a connected email integration; `conversation_intelligence` (to read the body) requires at least one connected email source and consumes AI credits. If the thread's content is not available to read, say so rather than guessing at its contents.

## Input

Provided via `$ARGUMENTS`:

- **Which thread** (optional) — an account, contact, or subject. If omitted, the skill lists recent email threads to pick from.
- **Emphasis** (optional) — e.g. "what do they need from me", "just the decisions". Shapes the output.

## Workflow

1. **Find the thread.** Call `browse_engagements` with `engagementType: EMAILS` (scoped to the account/contact if known, `sort: -chronological`). If the target is ambiguous, present a short numbered shortlist (subject, participants, date) and let the user pick before spending credits. Keep the chosen engagement ID.
2. **Read the body.** Run `conversation_intelligence` scoped to that engagement ID with `includeContent: true` so it returns the actual email body/thread alongside its answer. Ask for the thread's current state, the decisions and commitments, and the open questions. Keep it to the one thread; CI cannot search across threads by topic.
3. **Summarize.** Distill the chain in reading order of importance, not message order. Attribute key points to who said them. Surface what needs a reply or a decision. Do not invent positions no one stated.

## Output Format

### Thread summary — [Subject]

*Participants: [names]. Spans [first date] to [last date], [N] messages.*

**Where it stands** — 2-3 sentences on the current state and what the thread is waiting on.

**Decisions & key points** — bullets, each attributed to who said it.

**Open questions / needs a reply** — what is unresolved, and specifically what is being asked of whom.

**Suggested reply focus** *(if the user is drafting a response)* — the one or two things their reply should address.

### When there is no data

If no matching thread is found, or its content cannot be read, tell the user and ask them to name the thread or paste the chain, rather than summarizing from assumption.
engagement-timeline5.08 KB

View saved version →

---
name: engagement-timeline
description: Build a timeline of engagements (meetings and emails) with an account or contact over a date range. Identify the account or contact by ZoomInfo ID (preferred), or by name or domain (triggers a lookup), or omit both to time-line your own recent engagements. Defaults to the last 90 days and can slide the window further back for a longer history. Returns a chronological timeline, a breakdown by engagement type, and a participant list with per-person engagement counts — and keeps each engagement's ID in context so you can immediately double-click any one to ask what was discussed. Use when someone asks "when did we last meet with X", "how often have we engaged this account", "show me the history with this contact", or wants a relationship timeline before a call.
---

# Engagement Timeline

Build a timeline of meetings and emails with an account or contact, then let the user double-click any engagement to see what was discussed.

## Prerequisites

`browse_engagements` reads from the calendar, email, and meeting providers connected to ZoomInfo. It requires at least one active calendar, email, or meeting integration in the workspace. If nothing is connected, `browse_engagements` returns no results — say so plainly and point the user to their ZoomInfo admin rather than implying there has been no contact.

`browse_engagements` is free (no credits). The optional double-click step uses `conversation_intelligence`, which consumes AI credits.

## Input

Provided via `$ARGUMENTS`:

- **Scope** — one of:
  - An **account**: ZoomInfo company ID (preferred), or a company name/domain (resolve via `search_companies`).
  - A **contact**: ZoomInfo contact ID (preferred), or a name + company (resolve via `search_contacts`).
  - **Neither**: time-line the current user's own recent engagements across all accounts.
- **How far back** (optional) — default is the last 90 days. "Last quarter", "this year", "since January", or a specific range all work; for anything beyond 90 days the window slides (see Workflow).
- **Type** (optional) — meetings only, emails only, or both (default both).

## Workflow

1. **Resolve scope.** Use a supplied ZoomInfo ID directly as `zoominfoCompanyId` or `zoominfoContactId`. Otherwise resolve a name/domain via `search_companies` / `search_contacts` and confirm the top match if it is ambiguous. With no scope, call `browse_engagements` with no ID to get the user's own engagements.

2. **Set the window.** `browse_engagements` accepts a date range up to 90 days wide (`engagementDateStart`, `engagementDateEnd`), ending no more than a month in the future. Default to the last 90 days. For a longer history, **slide the window backward in 90-day chunks** (e.g. 0-90 days ago, then 90-180, then 180-270) and merge the results, stopping when a chunk comes back empty or you reach the user's requested horizon. Tell the user when you are looking back across multiple windows so the wait is expected.

3. **Pull engagements.** Call `browse_engagements` with the resolved scope, `engagementType` (default `EMAILS_AND_MEETINGS`), `sort: -chronological` (newest first), and `engagementLimit` up to 50 per call. Set `userIntent` to the user's actual request. If a window is full at the limit, narrow it and page rather than silently truncating.

4. **Aggregate.** From the merged set compute: total engagements and the date range actually covered; a split by type (meetings vs emails); and a participant list with a count of engagements per person (name, and account where it differs). Retain each engagement's ID and the account/contact IDs in your working context — do **not** print raw IDs in the user-facing timeline, but keep them so the user can pick one to analyze.

## Output Format

### Summary

One line: who this is for, how many engagements over what actual date range, and the split (e.g. "14 engagements with Acme over the last 88 days — 9 meetings, 5 emails").

### Timeline

Newest first. One line per engagement: date, type, title/subject, and the key participants. Group by month if the range spans several months. Flag the most recent engagement and the gap since (e.g. "last contact 12 days ago").

### Participants

A short table, most-engaged first:

| Person | Account | Engagements |
|--------|---------|-------------|

Note anyone who has gone quiet (engaged early in the window, absent recently) — that is often the signal worth acting on.

### Double-click any engagement

Close by offering the next step: the user can name any engagement above ("the demo on the 14th", "the last email") and you will pass its engagement ID to `conversation_intelligence` to answer what was discussed, what was decided, or what is still open. Keep CI scoped to that single engagement; do not use it to search the timeline by topic or to count mentions (it cannot).

### When there is no data

If `browse_engagements` returns nothing, do not present an empty timeline as "no relationship". State that no engagements were found for the scope and window, that this may mean no connected integration covers them, and suggest widening the window or checking integration status with the ZoomInfo admin.
enrich-company2.12 KB

View saved version →

---
name: enrich-company
description: Look up a company's full profile. Provide a company name, domain, ticker symbol, or ZoomInfo company ID. Returns firmographics, financials, corporate structure, growth signals, and contact counts.
---

# Enrich Company

Look up a single company's full profile in ZoomInfo.

## Input

The user will provide via `$ARGUMENTS` one of:
- A domain or website (e.g., `stripe.com` or `https://stripe.com`)
- A company name (e.g., `Stripe`)
- A stock ticker (e.g., `SNOW`)
- A ZoomInfo company ID

## Workflow

1. **Lookup metadata first** — before calling any other MCP tool, use `lookup` to load reference data for any fields relevant to the request. Use the returned `id` values (not display names) in all subsequent API calls. This ensures accurate parameter resolution, especially if a fallback search is needed.

2. **Identify the best match key** from the user's input:
   - URL or domain → use `domain` or `companyWebsite` parameter
   - Company name → use `companyName`
   - Ticker → use `companyTicker`
   - Company ID → use `companyId`

3. **Enrich the company** using `enrich_companies` with the identified parameters.

4. **If no match**, try a fallback:
   - Use `search_companies` with `companyName` for fuzzy matching — use lookup `id` values for any filters
   - Suggest alternatives from the search results

## Output Format

**[Company Name]** — [One-line description]

| Field | Value |
|-------|-------|
| Website | |
| Industry | |
| Sub-Industries | |
| Employee Count | |
| Revenue | |
| Founded | |
| HQ Location | |
| Company Type | (Public/Private/etc.) |
| Ticker | |
| Business Model | (B2B/B2C/B2G) |
| Phone | |
| SIC Codes | |
| NAICS Codes | |
| ZoomInfo Company ID | |

**Corporate Structure**
- Ultimate Parent: [if applicable]
- Parent: [if applicable]
- Subsidiaries: [count if available]

**Growth Signals**
- 1-Year Employee Growth: X%
- 2-Year Employee Growth: X%
- Recent Funding: [if available]

**ZoomInfo Coverage**
- Contacts in Database: [count]

Include the ZoomInfo Company ID — users will need it for follow-up commands like `/zoominfo:find-buyers` or `/zoominfo:find-similar`.
enrich-contact1.93 KB

View saved version →

---
name: enrich-contact
description: Look up a person's full professional profile. Provide a name and company, email address, phone number, or ZoomInfo person ID. Returns title, department, contact details, accuracy score, and company info.
---

# Enrich Contact

Look up a single contact's full profile in ZoomInfo.

## Input

The user will provide via `$ARGUMENTS` one of:
- An email address (e.g., `jane@acme.com`)
- A name and company (e.g., `Jane Smith at Acme Corp`)
- A phone number
- A LinkedIn URL
- A ZoomInfo person ID

## Workflow

1. **Lookup metadata first** — before calling any other MCP tool, use `lookup` to load reference data for any fields relevant to the request. Use the returned `id` values (not display names) in all subsequent API calls. This ensures accurate parameter resolution, especially if a fallback search is needed.

2. **Identify the best match key** from the user's input:
   - Email → use `email` parameter
   - Name + company → use `firstName`, `lastName`, `companyName`
   - Full name + company → use `fullName`, `companyName`
   - Phone → use `phone`
   - LinkedIn URL → use `externalURL`
   - Person ID → use `personId`

3. **Enrich the contact** using `enrich_contacts` with the identified parameters.

4. **If no match**, try a fallback:
   - If name + company failed, try `search_contacts` with `jobTitle` or `companyName` variations — use lookup `id` values for any filters
   - Suggest alternative spellings or company names

## Output Format

**[Full Name]** — [Title] at [Company]

| Field | Value |
|-------|-------|
| Department | |
| Management Level | |
| Email | |
| Direct Phone | |
| Mobile Phone | |
| Accuracy Score | |
| Location | |
| Company | |
| Company Industry | |
| Company Size | |
| LinkedIn | |
| Last Updated | |
| ZoomInfo Person ID | |

If any fields are unavailable, omit them rather than showing blanks. Note the accuracy score prominently — anything below 80 deserves a flag.
exec-brief3.15 KB

View saved version →

---
name: exec-brief
description: Produce a succinct one-pager for an executive dropping into a call with zero context. Blends account_research (who they are, deal state), conversation_intelligence (what has been discussed and what is open), and contact_research (who is in the room). Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup); name the key attendees if known. Use when someone says "brief the VP for the Acme call", "exec one-pager for tomorrow", "my SVP is joining cold", or needs a tight pre-call brief for a senior stakeholder. Built to be read in two minutes.
---

# Exec Brief

One page an executive can absorb in the elevator: who, why now, where we stand, and the one thing to do in the room.

## Prerequisites

`conversation_intelligence` requires at least one connected meeting or email source; `account_research`, `contact_research`, and `conversation_intelligence` consume AI credits. If no conversation data exists, build from research and note that the "where we stand" view is research-based only, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **The exec and the meeting** (recommended) — who is being briefed, the meeting's purpose, and the attendees, so the one-pager is framed for their role.

## Workflow

1. **Resolve the account** (and key attendees, if named). Use ZoomInfo IDs directly, or resolve via `search_companies` / `search_contacts`.
2. **Gather, then compress.** Run `account_research` (company + deal context) and account-scoped `conversation_intelligence` (recent state, open threads, commitments) in parallel. Run `contact_research` only for attendees the user named or that research surfaces as the key deal contacts; if no attendees are known, ask before spending `contact_research` credits rather than researching the whole account. Keep CI scoped to the account; it sees only the last few engagements.
3. **Write for an exec.** Ruthlessly compress to one page. Lead with why this account matters and why now. Give the exec the single most useful thing to do or say, and the landmines to avoid. Cut firmographic detail that does not change how they show up. Every line earns its place; attribute the relationship claims.

## Output Format

### Exec brief — [Company]

**Bottom line** (2-3 sentences) — who they are, why this meeting matters, and where the relationship stands right now.

**Where we stand** — 2-3 bullets on the deal/relationship state and what is currently open (from CI + research).

**In the room** — the attendees in one line each: name, role, and what they care about.

**Your move** — the one thing for the exec to do or say to move this forward.

**Landmines** — one or two things to avoid (a sore point, a competitor, an unresolved issue), each with a reason.

Keep the whole thing to roughly one page. If a section has nothing high-signal, drop it rather than padding.

### When there is no data

If conversation data is unavailable, build the one-pager from research and state that the current-state view is not grounded in recent conversations.
find-similar5.06 KB

View saved version →

---
name: find-similar
description: Find companies or contacts similar to a given reference. Provide a company name/domain or a person's name/email and get a ranked list of lookalikes scored by similarity. Useful for territory expansion, TAM analysis, competitive mapping, expanding buyer networks, and building targeted prospecting lists.
---

# Find Similar

Find companies or contacts similar to a reference entity using ZoomInfo's ML-powered similarity model.

## Input

The user will provide via `$ARGUMENTS`:
- **For companies**: a company name, domain, or ZoomInfo company ID
- **For contacts**: a person's name and company (e.g., "Jane Smith at Acme Corp"), email address, or ZoomInfo person ID
  - Optionally: a target company to scope results to (e.g., "at Microsoft" or "within Salesforce")
  - Optionally: how many results they want (defaults to 25, max 100)

Determine whether the user is looking for similar **companies** or **contacts** based on what they provide, then follow the appropriate workflow below.

---

## Company Workflow

1. **Lookup metadata first** — before calling any other MCP tool, use `lookup` to load reference data for any fields relevant to the request. Use the returned `id` values (not display names) in all subsequent API calls.

2. **Find similar companies** using `find_similar_companies`. This returns up to 100 results ranked by similarity score.
   - If you have a ZoomInfo company ID, pass `companyId`.
   - If you only have a company name, pass `companyName` — the API can resolve it directly.

### Company Output Format

**Similar companies to [Reference Company Name]:**

| Rank | Company | Industry | Employees | Revenue | Country | Similarity Score |
|------|---------|----------|-----------|---------|---------|-----------------|
| 1 | | | | | | |
| 2 | | | | | | |
| ... | | | | | | |

Show the top 25 by default. If the user asks for more, show up to 100.

After the table:
- Note the total number of similar companies returned
- Call out any patterns (e.g., "heavily weighted toward mid-market SaaS in North America")
- Suggest next steps: use `/zoominfo:enrich-company` to get full details on any result, or `/zoominfo:find-buyers` to identify contacts at a target

---

## Contact Workflow

1. **Lookup metadata first** — before calling any other MCP tool, use `lookup` to load reference data for fields relevant to interpreting the results:
   - `lookup` with `fields: [{"fieldName": "management-levels"}, {"fieldName": "departments"}, {"fieldName": "job-functions"}]`
   - Use the returned `id` values (not display names) in all subsequent API calls and for categorizing results.

2. **Resolve the reference person** if the user did not provide a ZoomInfo person ID:
   - If the user gave an email → use `enrich_contacts` with `email` to get the person's ZoomInfo person ID.
   - If the user gave a name and company → use `enrich_contacts` with `firstName`, `lastName`, and `companyName` to get the person's ZoomInfo person ID.
   - If enrichment fails, fall back to `search_contacts` with `fullName` and `companyName` to find a match.
   - Extract the ZoomInfo person ID from the result.

3. **Resolve the target company** if the user specified one:
   - Use `search_companies` with `companyName` or `companyWebsite` to get the ZoomInfo company ID — use lookup `id` values for any filters.

4. **Find similar contacts** using `find_similar_contacts` with:
   - `referencePersonId`: the resolved ZoomInfo person ID (required)
   - `targetCompanyId`: the resolved ZoomInfo company ID (only if the user specified a target company)
   - `pageSize`: user-specified count or 25

### Contact Output Format

#### Reference Person
**[Full Name]** — [Title] at [Company]
Brief profile summary: department, management level, job function. This anchors the similarity analysis.

#### Similar Contacts

| Rank | Name | Title | Company | Department | Management Level | Score |
|------|------|-------|---------|------------|-----------------|-------|
| 1 | | | | | | |
| 2 | | | | | | |
| ... | | | | | | |

Show the top 25 by default. If the user asks for more, show up to 100.

For each contact, use the `meta` field from the response to explain WHY they are a match. The meta describes the reference person used to form the similarity — use this to connect the recommendation back to the reference person's attributes.

#### Pattern Analysis
- **By Title/Function**: What roles dominate the results? (e.g., "Heavily weighted toward revenue operations and sales leadership")
- **By Seniority**: What management levels appear most? Use the lookup values to categorize accurately.
- **By Company Profile**: What types of companies do these contacts work at? (e.g., "Mostly mid-market SaaS, 200-1000 employees")
- **If scoped to a target company**: Note which departments and levels within that company have the strongest matches.

After the table:
- Note the total number of similar contacts returned
- Call out any patterns in the results
- Suggest next steps: use `/zoominfo:enrich-contact` to get full details on any result, or `/zoominfo:find-buyers` to identify other contacts at a specific company from the list
meeting-prep14.2 KB

View saved version →

---
name: meeting-prep
description: Prepare for an upcoming meeting with a company. Identify the account by ZoomInfo account/company ID (preferred) or by company name, domain, or ticker (which triggers a lookup step) — or name no account at all and let the skill pick the meeting from your upcoming calendar. Provide attendee names or emails and rich context on the meeting purpose, stakes, and known dynamics to get a tight, decision-ready brief — headline, relationship posture per attendee, prior-conversation context (open threads and unresolved questions from past calls and emails), ranked talking points, discovery questions, suggested agenda, and what NOT to do. Use when prepping for a sales or customer call, QBR, renewal, or demo. Optimized for a 30-min slot.
---

# Meeting Prep

Produce a tight, decision-ready brief for a ~30-minute meeting. Lead with a TL;DR (top 3 to know plus an opener), then back it with company, relationship, attendee, and conversation context.

## Prerequisites

The calendar-picker and prior-conversation steps read ZoomInfo engagement data, which requires an active calendar, email, or meeting integration in the workspace (`conversation_intelligence` needs at least one connected email or meeting source). If none is connected, still produce the research-based brief and note that conversation context was unavailable — point the user to their ZoomInfo admin to enable it. `account_research`, `contact_research`, and `conversation_intelligence` consume AI credits; `enrich_*` consume bulk data credits.

## Input

The user will provide via `$ARGUMENTS` an account identifier (required), attendees (recommended), plus optional context:

- **Account identifier (required, unless picking from your calendar)** — one of:
  - **Preferred**: a ZoomInfo account/company ID (numeric). Use directly as `companyId`; skip the search step.
  - **Fallback**: a company name, domain, or ticker. Resolve to a `companyId` via `search_companies` as a first step (see Workflow step 3).
  - **Or name no account**: if the user says "prep me for my next meeting", "what should I know for my 2pm", or "prep my meetings this week", skip the identifier and pick the meeting from the calendar (see Workflow step 0). The chosen meeting's account and attendees are resolved from the engagement record.
- **Attendees (recommended)** — names and/or email addresses. Without attendees, the brief is necessarily generic.
- **Meeting context (strongly recommended)** — a free-form description of the meeting and what success looks like. Richer is better — flat enums like "discovery / QBR / renewal / demo" produce flat briefs. Capture as much as is true: the meeting purpose, the stakes, what's been discussed before, the deal stage, what you want to walk out with, known tensions or open questions, competitive context, the offering in play, and any working hypotheses you want to test or pitfalls to avoid. Examples:
  - *"30-min discovery with the CISO and Director of SecOps. They downloaded the report on identity sprawl last month. Goal: get to a technical evaluation. Worried they're already late-stage with Acme — need to test that fast without burning credibility."*
  - *"Renewal QBR. $600K ARR up in 60 days. Champion left two months ago, new VP Eng hasn't engaged. Need to surface value delivered, find the new owner, and avoid a price-only negotiation."*
  - *"Demo for the Director of Data Platform. Came inbound on the streaming use case. They have an in-house ETL setup. Goal: land a paid pilot. Don't lead with the AI features — they'll see it as a distraction."*

If the identifier is ambiguous (e.g., a bare string that could be a name or a ticker), prefer the most specific interpretation: all-digits → ID; short all-caps token (≤5 chars) → ticker; a string containing a dot or known TLD → domain; otherwise → name.

## Workflow

Parallelize aggressively — most calls only need the `companyId` and can fan out together. Per-attendee, run `contact_research` and `enrich_contacts` in parallel: `contact_research` returns narrative context but quality varies, so `enrich_contacts` guarantees a structured fallback (title, email, phone, employment history) when narrative data is redacted or thin.

0. **Pick the meeting (only if no account was named).** If the user named an account or attendees, skip this step. Otherwise call `browse_engagements` with a forward window (today through ~7-14 days ahead, `engagementType: MEETINGS`, `sort: chronological`, `userIntent` set to the request) and present a short numbered shortlist — time, title, account, attendees — for the user to pick from before spending research or AI credits. From the chosen engagement, carry its ZoomInfo company ID forward as the account: pass it as `zoominfoCompanyId` to `browse_engagements`/`conversation_intelligence` and as `companyId` to the research/enrich tools (same ID, different parameter names per tool). Use its participants as the attendees below, and keep its engagement ID for step 4b. If `browse_engagements` returns nothing, tell the user no upcoming meetings were found and ask them to name an account instead (or check that a calendar integration is connected).

1. **Anchor on purpose.** Read the meeting context from `$ARGUMENTS`.
   - If supplied, restate it in 1-2 sentences as the *meeting purpose* and keep it as the framing lens for every downstream step.
   - If missing, ask the user once. If they decline or say "just general prep", default to **general meeting prep** and state that assumption at the top of the brief.
   - From the context, derive: a **meeting purpose** (1 line), the **desired outcome** (what walking out successful looks like), **priority topics/themes** (3-5 — e.g., identity sprawl, ETL pain, renewal value), and any **named risks or hypotheses to test** (e.g., "test if they're already late-stage with Acme"). These priorities drive the `account_research` query, attendee framing, talking-point ranking, and the suggested agenda.

2. **Get GTM context** — Call `get_gtm_context` (no params, no credits). Use it to tailor talking points to your offerings and strategic priorities, flag competitor presence, and frame around your ICP. If empty, proceed without.

3. **Resolve the company.**
   - If the user supplied a ZoomInfo account/company ID, use it directly as `companyId` — do not call `search_companies`.
   - Otherwise, call `search_companies` with the appropriate field (`companyWebsite` for a domain, `companyTicker` for a ticker, `companyName` for a name) and extract `companyId` from the top match. If no confident match, surface the ambiguity to the user before continuing rather than guessing.

4. **Fan out company research in parallel (retrieval, not filtering).** Treat each tool call as a context-retrieval step. Pull broadly now; decide what's relevant during synthesis. Steps that only need the `companyId` can run together — `account_research`, `enrich_companies`, and `enrich_company_signals` (intent, news, and scoops in one call).
   - **Tailor the `account_research` query to the meeting purpose.** Don't pass a generic "tell me about this account" string. Inject the full meeting context — purpose, desired outcome, priority topics, named hypotheses, attendees if known — and ask for relationship history, deal context, engagement signals, competitive presence, and anything that would change how you walk into the meeting.
   - **Signals retrieval**: call `enrich_company_signals` with the `companyId` and `signalTypes: ["INTENT", "NEWS", "SCOOP"]` (or omit `signalTypes` for all three). It returns recent intent, news, and scoops in one call; topic resolution and recency are handled server-side, so do **not** pre-filter. Triage happens in step 6.

4b. **Pull prior-conversation context (runs in parallel with step 4; skip if no engagement data).** Run `conversation_intelligence` scoped to the account (`zoominfoCompanyId`) — or to the specific engagement ID when you picked the meeting in step 0 — asking what was discussed in recent conversations, which threads are still open, which questions went unresolved, and what the customer asked us to follow up on. This is the "what was actually said" layer that research and enrichment miss. Keep the query scoped and specific; do not ask CI to search by topic, filter by call type, or count mentions (it cannot, and only sees the last few engagements). If no conversation data is available, skip this and note it in the brief.

5. **Resolve and research attendees in parallel** — Run `search_contacts` for all attendees in one batch (by email, name + companyId, or title + companyId). Then run `contact_research` and `enrich_contacts` in parallel for the resolved set (batch up to 10 per `enrich_contacts` call). If an attendee can't be resolved, note it — don't fabricate.

6. **Synthesize the brief.** Each retrieval is raw context — now decide what makes the brief, framed by the meeting purpose and priority topics. Apply these principles:
   - **Intent triage**: review every intent topic returned by `enrich_company_signals`. Keep topics that map to the meeting purpose, priority topics, your GTM offerings, or a non-obvious signal worth flagging (e.g., a competitor's category, an adjacent buying motion). Drop topics that are noise. If nothing meaningful remains, skip the intent section.
   - **News/scoops triage**: keep items that connect to the meeting purpose, the deal stage, attendees, or priority topics. Drop generic press releases unrelated to the agenda.
   - **Conversation context**: from `conversation_intelligence`, surface open threads, unresolved questions, and commitments. These are the highest-signal inputs for the opener and talking points — a warm-dormant posture paired with an open thread from the last call is the strongest possible opening. Cite the source meeting where CI provides it.
   - **Classify relationship posture per attendee** from `employmentHistory` and `contact_research` cues: **Cold**, **Warm-but-dormant** (significant past engagement at a prior employer or directly, but no current activity — highest leverage), **Active**, or **Hostile**. The opener depends on this.
   - **Talking-point ranking**: cap at 3-5, ranked by relevance to the desired outcome. Each must tie to a specific surfaced fact and (where possible) a named attendee.
   - **Hypothesis check**: explicitly address each named hypothesis or risk from step 1 — did the data confirm, contradict, or fail to resolve it? Surface in the TL;DR.
   - **Source tagging**: tag key claims with sources (`[CRM]`, `[contact_research]`, `[enrichment]`, `[news]`, `[scoops]`, `[intent]`). When `contact_research` is redacted/minimal, mark the attendee profile with a confidence note.
   - **Past-date flag**: for any date in `account_research` that is in the past relative to today, retain and flag for verification rather than dropping silently — could be active negotiation, a stale CRM sync, or a missed milestone.

7. **Write the TL;DR last,** after the rest is drafted. Frame it explicitly by the meeting purpose and desired outcome.

## Output Format

### TL;DR

> **Meeting purpose / desired outcome**: [restate the user's context in one line, or "general meeting prep (no context supplied)" if defaulted].
>
> **Top 3 to know walking in** (each tied to the desired outcome):
> 1. [Most decision-relevant fact]
> 2. [Second]
> 3. [Third]
>
> **Hypothesis check** (one line per named hypothesis from the input): confirmed / contradicted / unresolved.
>
> **Carrying over from last time** (if conversation data exists): 1-2 open threads, unresolved questions, or promised follow-ups from prior calls/emails, each with the source meeting.
>
> **Open with**: "[Single recommended opening line — verbatim, calibrated to attendee posture and any open thread]"

### Company Snapshot

| Field | Value |
|-------|-------|
| Industry | |
| Employees | |
| Revenue | |
| HQ | |
| Business Model | |
| Website | |

One-paragraph overview from the enrichment description.

### Relationship Context

Summarize from `account_research` with source tags: deal status, last engagement, account health, and key history. If no CRM data, say so explicitly. For any past date (renewal, contract end, expiration, last activity, opp close), retain it and flag inline: *"Verify — date is in the past; may indicate active negotiation, stale CRM, or missed milestone."*

### Prior Conversations

*From `conversation_intelligence`. Omit if no conversation data was available, and note that an email/meeting integration is not connected.*

- **Recent themes**: what has actually been discussed across the last few calls/emails.
- **Open threads / unresolved questions**: what is still hanging, with the source meeting.
- **Commitments**: what we promised and what they promised, if surfaced.

Keep this tight (3-6 bullets). This is recent-conversation context only — the last few engagements, not full history.

### Attendees

For each attendee:

#### [Name] — [Title]

| Field | Value |
|-------|-------|
| Department | |
| Management Level | |
| Email | |
| Time in Role | |
| Posture | Cold / Warm-but-dormant / Active / Hostile |

**Why they matter for THIS meeting**: 2 lines max. Connect role/background to the decision in front of them.

**Talking points for them**: 1-2 specific to this attendee.

If `contact_research` returned redacted/minimal data, add: *"Profile data restricted — verify externally."*

### Talking Points (3-5)

Ranked by impact, each tagged for its audience.

1. **[Topic]** `[for: <attendee names or "all">]`: [Why to raise it + supporting data point with source tag]
2. ...

Prioritize items that show homework, connect to your GTM offerings, surface competitive angles, or hit a specific persona.

### Discovery Questions (3-5)

Specific, anchored in concrete facts from the brief — not generic.

1. **[for: <attendee or "group">]** — [Question grounded in something surfaced above.]
2. ...

### Suggested Agenda (~30 min)

- **(0-5) Open**: [Specific opener — relationship-continuity for warm-dormant, value-frame for cold, status-check for active]
- **(5-15) Explore**: [Primary discovery thread — top talking point + 2 questions]
- **(15-25) Develop**: [Second thread — secondary point, demo, or proposal]
- **(25-30) Close**: [Specific desired next step]

### What NOT to Do

1-3 specific failure modes for *this* meeting. Concrete, not generic.

- **Don't [specific anti-pattern]** — [why it would backfire here].
mutual-action-plan3.96 KB

View saved version →

---
name: mutual-action-plan
description: 'Build a mutual action plan (MAP) from what was actually discussed on recent calls — the shared, dated set of steps each side owns to reach the goal. Reviews recent engagements and goes deep with conversation_intelligence scoped to individual calls to pull open items, agreed next steps, owners, and the timelines discussed. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone says "build a mutual action plan for Acme", "turn our last calls into a MAP", "what are the next steps and dates on both sides", or needs a close or onboarding plan. Evidence-based: it plans only what was discussed and asks for the target date if one was not stated.'
---

# Mutual Action Plan

Turn the commitments and timelines from recent calls into a single shared plan: who does what, by when, on both sides, toward an agreed goal.

## Prerequisites

`browse_engagements` (to find the calls) is free but requires an active calendar/meeting integration; `conversation_intelligence` (to read them) requires at least one connected meeting or email source and consumes AI credits (minimum ~9 per call), and this skill calls it once per key engagement, so the spend scales with how many calls you deep-read. `account_research` (optional deal context) consumes AI credits. If no conversation data exists, say so rather than inventing a plan.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Goal & target date** (ask if it matters and was not given) — the close date, go-live, or objective the plan drives toward. Do not assume it; if the plan needs a date that was never discussed, ask the user.

## Workflow

1. **Resolve the account.** If no account was supplied, ask the user which one before proceeding. Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies` (`browse_engagements` filters by company ID + date, not by name).
2. **Find the recent calls.** Call `browse_engagements` (account-scoped, `engagementType: MEETINGS`, `sort: -chronological`). Pick the few most recent substantive calls that carry plan-relevant content (typically the last 2-4); each gets its own CI call, which costs credits, so do not fan out across the whole history. Keep their engagement IDs.
3. **Deep-read each call.** Run `conversation_intelligence` scoped to each engagement ID (one CI call per engagement) for open items, agreed next steps, who owns each (us vs them), and any dates, deadlines, or sequencing discussed. Keep each query to its single engagement; CI sees only the last few engagements and cannot topic-search or count.
4. **Confirm the goal.** If a target close/go-live date or objective was discussed, anchor the plan on it. If the plan needs one and it was never stated, ask the user rather than inventing a date.
5. **Assemble the MAP.** Merge the items into one plan, deduping across calls. Give each a clear owner and a target date where one was discussed. Order by date. Mark anything discussed without an owner or date as needing confirmation. Include only steps the conversations support; do not pad with a generic playbook.

## Output Format

### Mutual Action Plan — [Company]

*Goal: [stated objective and target date, or "target date not stated — confirm with the customer".]*

| # | Step | Owner | Target date | Status | Source |
|---|------|-------|-------------|--------|--------|
| 1 | | Us / Them | | open / done / at risk | [call] |

Ordered by target date (undated steps last).

**Gaps to confirm** — steps that were discussed without a clear owner or date, and any dependency the calls left unresolved. These are the first things to nail down with the customer.

### When there is no data

If `browse_engagements` finds no recent calls, or they have no transcripts to read, tell the user a MAP cannot be built from conversations and offer to draft one from items they provide, rather than fabricating steps or dates.
next-best-action2.99 KB

View saved version →

---
name: next-best-action
description: Recommend the next best action on a deal or relationship, grounded in the current conversation state. Uses conversation_intelligence as the primary source, with account_research for deal context. Identify the account or contact by ZoomInfo ID (preferred) or name (triggers a lookup), or point it at a specific engagement. Use when someone asks "what should I do next with Acme", "what's my next move here", "how do I advance this deal", or wants an evidence-based recommendation rather than a generic playbook. Reasons over the last few engagements only.
---

# Next-Best-Action

Read the current state of the conversation and recommend the one or two moves most likely to advance it.

## Prerequisites

`conversation_intelligence` requires at least one connected email or meeting source; `conversation_intelligence` and `account_research` consume AI credits. If no conversation data exists, base the recommendation on `account_research` and say the read is limited, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Scope** (required) — an account, a contact, or a specific engagement (ID, or a name to resolve).
- **Goal** (optional) — e.g. "get to a technical eval", "close this quarter", "re-engage a stalled deal". Sharpens the recommendation.

## Workflow

1. **Resolve scope.** Use a ZoomInfo ID directly, or resolve via `search_companies` / `search_contacts` and confirm an ambiguous match before spending credits (`conversation_intelligence` and `account_research` both cost AI credits, so a wrong resolution burns them). For a specific call not named, offer a `browse_engagements` shortlist first.
2. **Read the state.** Run `conversation_intelligence` scoped to the account/contact/engagement for where things stand: open threads, stated next steps, blockers, buying signals, and unanswered questions. Pull `account_research` for deal stage and stakeholder context. Keep CI scoped to one ID; it sees only the last few engagements and cannot search by topic or count, so reason from what it returns.
3. **Recommend.** Propose one to three concrete next actions, ranked, each tied to specific evidence from the conversations and aimed at the stated goal. For each, give the move, why now (the evidence), and the expected effect. Skip generic advice — if the evidence does not support a confident recommendation, say what is missing and what to find out next instead.

## Output Format

### Next best action — [Account / Contact]

**State of play** — 2-3 lines on where things stand right now, from the conversations.

**Recommended moves** (ranked, 1-3):
1. **[The move]** — *Why now:* [evidence from a specific conversation]. *Expected effect:* [what it unlocks].

**What we don't yet know** — the open question(s) that would most change the recommendation, and how to get the answer.

### When there is no data

If conversation data is unavailable, give the best `account_research`-based suggestion and flag that it is not grounded in recent conversations.
objection-blocker-tracker2.93 KB

View saved version →

---
name: objection-blocker-tracker
description: Track the open objections and blockers on a deal and how they have evolved across recent calls. Uses conversation_intelligence over an account's or contact's recent engagements. Identify the account or contact by ZoomInfo ID (preferred) or name (triggers a lookup). Use when someone asks "what objections are still open with Acme", "what's blocking this deal", "how has the security concern evolved", or wants a blocker check before a forecast or a next call. Reasons over the last few engagements only, so it tracks recent movement rather than full deal history.
---

# Objection & Blocker Tracker

Surface the concerns standing between you and the deal, and show whether each is getting better or worse.

## Prerequisites

`conversation_intelligence` requires at least one connected meeting or email source and consumes AI credits. `browse_engagements` (to scope or pick calls) requires an active integration and is free. If no conversation data exists, say so rather than reporting "no objections" (the absence of data is not the absence of objections).

## Input

Provided via `$ARGUMENTS`:

- **Scope** (required) — an account or contact (ZoomInfo ID, or a name to resolve).
- **Focus** (optional) — e.g. "just pricing", "anything technical", "security and procurement". Narrows the read.

## Workflow

1. **Resolve scope.** If no account or contact was supplied, ask the user which one before proceeding. Use a ZoomInfo ID directly, or resolve a name via `search_companies` / `search_contacts`.
2. **Extract objections and blockers.** Run `conversation_intelligence` scoped to the account or contact. Ask it to list the objections, concerns, and blockers raised across recent conversations, who raised each, when, and how it was last left. Keep CI scoped to one ID; it sees only the last few engagements and cannot count or topic-search, so present this as recent movement, not a complete tally.
3. **Track the trajectory.** For each item, classify status: newly raised, addressed/resolved, recurring (keeps coming back), or escalating. Tie each to the source moments. Do not record an objection the conversation does not support, and do not mark something resolved without evidence it was.

## Output Format

### Open objections & blockers — [Account / Contact]

*From the last few engagements (through [date]).*

For each, most pressing first:

**[Objection / blocker]** — `[status: new | recurring | escalating | addressed]`
- **Raised by:** [who, when]
- **Evolution:** how it has moved across calls (e.g. "raised in discovery, partially addressed in the demo, resurfaced on the last call").
- **Where it stands:** the current state and what would move it.

Close with **Most likely to stall the deal** — the one or two items to resolve first, with why.

### When there is no data

If conversation data is unavailable, report that open objections cannot be tracked from conversations and point the user to their ZoomInfo admin.
personalize-email19.9 KB

View saved version →

---
name: personalize-email
description: Generate 1-3 personalized email variants for a single prospect. The composition bar adapts to the use case — cold_outbound demands a signal → pain → positioning chain; follow-ups / recaps / renewals lean on prior context and next-step framing. Supports cold_outbound, discovery_follow_up, demo_recap, re_engagement, renewal, expansion, objection_handling. Returns subject lines and mobile-readable bodies with a rationale chain. Use for sales prospecting, lead generation, account-based selling, buyer-intent-driven outreach, B2B prospecting. Triggers on phrases like "write a cold email", "personalize an email", "draft outreach", "follow up on this prospect", "email this prospect", "outbound to X", "send a chaser".
---

# Personalize Email

Generate personalized email variants. Calls `get_gtm_context(detailed: true)` unconditionally, resolves the prospect, runs a relationship-context pre-flight, pulls signals + CRM context, and composes 1-3 variants tuned to the chosen use case. Iteratively refinable.

## The bar — adapts by use case

The composition bar depends on what the email is trying to do. Don't force a cold-outbound frame onto a follow-up.

| Use case | Anchor for the variant | Pain-bridge required? |
|---|---|---|
| `cold_outbound` | **Signal → pain → positioning chain** (specific, recent, verifiable signal; concrete inferred pain; GTM-context value prop) | **Yes — mandatory** |
| `re_engagement` | Fresh new signal since the last contact → reconnection frame | Yes (lightweight — the signal IS the reason to reach back) |
| `discovery_follow_up` | Prior conversation reference → next-step framing | No (the prior touchpoint replaces the pain bridge) |
| `demo_recap` | Recap of what was shown / heard → concrete next step | No |
| `renewal` | Outcome recap → renewal moment + stakeholder ask | No (anchor is the contract, not a pain) |
| `expansion` | Existing outcome → adjacent need / persona | Pain-bridge ON the adjacent need, not the existing relationship |
| `objection_handling` | Acknowledge stated objection → reframe | No (the objection IS the anchor) |
| `chaser` (treat as a `re_engagement` variant) | One new fact or framing since the last send → "still relevant?" | No |

Universal — every variant: specific to *this* prospect (no template feel); concrete next action; honest about state; ≤ use-case length cap.

The rule in one line: **never default to "let me find a pain" when the use case calls for "what happens next."**

## Always-on context: `get_gtm_context`

Call `get_gtm_context(detailed: true)` first. Parse offerings into:

```
offering_profile = { offering, pain_points[], value_props[], proof_bank[], cta_ladder[] }
```

Anchor on **one** `offering_profile`. Pick **one** `value_prop`. Never invent stats or customer names — only what GTM context / proof_bank provides.

## Input

- **Prospect identifier (required)** — ZI person ID / email / name+company / name+domain.
- **Use case (default `cold_outbound`)** — drives length, framework, CTA, and bar (see above).
- **Outreach context (recommended)** — natural-language goal ("competitive displacement against [vendor]", "follow up on last week's pricing conversation").
- **Prior touchpoint summary (recommended for follow-ups / recaps / chasers)** — what happened last + named participants + open thread. Without it, the skill falls back to `account_research` + `contact_research` to reconstruct.
- **Sender info (optional)** — name, title, email, phone, signoff. Otherwise omit signature.
- **User-supplied template/content (optional)** — wins over everything below. Use as skeleton; fill placeholders only.
- **Variant count (optional)** — 1 / 2 / 3. Default: governed by persona-fit discipline.
- **Preferred angle (optional)** — `curiosity` / `value-frame` / `urgency`.
- **Recipient email** — required for sending. Refuse if unresolvable.

## Use-case routing

| Use case | Length | Framework | CTA style |
|---|---|---|---|
| `cold_outbound` | 50–80 | AIDA or Becc Holland 4-line | Lowest-friction tease |
| `discovery_follow_up` | up to 120 | PAS (pain known) | 15–20 min fit check |
| `demo_recap` | 80–120 | Recap → next-step | Concrete next-step proposal |
| `re_engagement` / `chaser` | 50–80 | Curiosity / new-signal hook | One-line ask |
| `renewal` | 80–120 | Outcome-recap → renewal step | Tied to contract step |
| `expansion` | 80–120 | Outcome-recap → adjacent need | Fit check on adjacency |
| `objection_handling` | up to 120 | Acknowledge → reframe | Direct one-question response |

Frameworks: **AIDA** (cold) · **PAS** (pain known) · **Challenger** (provocative insight) · **Becc Holland 4-line** (Premise / Hook / CTA / Push-Pull — cold + re-engagement).

## Signal → pain mapping (cold-outbound + re-engagement)

Used when the use case requires a signal → pain bridge. For follow-ups / recaps / renewals, the bridge is the prior touchpoint or contract moment, not a new pain.

| Signal | Recency | Implied pains | Buying window |
|---|---|---|---|
| **M&A — acquirer** | 90d | Integration complexity, redundant tooling, vendor consolidation, IT security review | 3–9mo post-close |
| **M&A — acquiree** | 90d | Loss of autonomy, vendor contract review, rip-and-replace risk | 0–6mo post-close |
| **New CEO / C-suite hire** | 30d | Strategy reset, 100-day plan, vendor relationship reset, budget reallocation | 60–180d |
| **Funding round** | 90d | Enterprise-grade tool need, hiring acceleration, scaling pains. A: replace founder tools · B: process formalization · C+: enterprise readiness | 3–6mo |
| **Hiring plans / surge** | 30d | Onboarding load, tooling gaps revealed by scale | 0–6mo |
| **Layoffs / restructuring** | 60d | Cost pressure, consolidation, automation appeal. Sensitivity > urgency | 6–12mo |
| **Product launch** | 90d | GTM readiness, sales/marketing alignment, enablement gaps | 0–6mo |
| **Earnings / financial results** | 30d | Public commitments → execution pressure | 30–90d |
| **Intent topic spike** | 14d | Active research; score 80+ + audience A/B = warm | 0–60d |
| **Partnership announcement** | 60d | Co-sell pressure, competitive disruption to incumbent vendors | 3–6mo |
| **Pain Point scoop** | 90d | ZI-curated pain — already the bridge | 0–90d |

When multiple signals exist, choose by **(recency × buyer-relevance × stage-alignment)**. Recency weighted heavily — a 14-day signal beats a 60-day one.

## Personalization ladder — use **exactly one**, never stack

| Tier | What | When |
|---|---|---|
| **P0** | Neutral trigger (role + market trend) | Last-resort fallback |
| **P1** | Role/segment insight (ICP-level) | When company-specific signal is thin |
| **P2** | Company-specific event (news / product / metric) | Default for cold_outbound |
| **P3** | Individual-specific (quote, prior interaction, CRM note) | Strongest; re_engagement / discovery_follow_up |
| **Tier 0 override** | User-supplied template content | Always wins; fill placeholders only |

## Proof-source hierarchy — use **exactly one**, in order

1. Direct prior result with this account/contact (from `contact_research` / CRM).
2. Peer / segment outcome (from `proof_bank`).
3. Product evidence without metrics (capability → expected outcome).
4. Fallback: generic capability statement.

**Never invent stats or customer names.** If proof_bank is empty, drop to tier 3 or 4 — never fabricate.

## Tone calibration

When tone isn't supplied, infer by seat:
- **Executives** (C/EVP/SVP) — outcome-first, concise, numeric proof, direct CTA.
- **Directors / Managers** — problem → approach → outcome → CTA.
- **Practitioners / ICs** — workflow friction → concrete benefit → quick next step.

Universal: ~Grade 8 reading level. Slightly casual; slightly unsure phrasing ("might be off-base, but…").

## Anti-patterns — fail-fast checklist

If any fires, regenerate.

1. **Generic congratulations.** Banned openers: "Congrats on", "Saw the news about your", "Hope this finds you well", "Loved your recent post about" (without naming + thesis).
2. **"Just checking in" / "circling back".** Dead. Use a signal or don't follow up.
3. **Self-introduction-first.** "We're a leading provider of…" / "Hi, I'm…" / "We help [persona]…" — lead with the prospect.
4. **"I noticed..." crutch.** Stating a public fact without doing something with it.
5. **Signal without payoff.** Naming a signal then jumping to product pitch — skips the bridge.
6. **Forcing a pain bridge on a non-cold use case.** Follow-ups, recaps, renewals don't need a freshly invented pain. The anchor is the prior touchpoint or contract moment.
7. **Generic praise.** "Love what you're building" / "Big fan." Must tie to a specific achievement.
8. **Meeting ask as primary CTA on cold.** Tanks reply rate. Use a tease.
9. **Length > use-case cap.** Emails over 150 words are 42% less likely to get a reply.
10. **AI-generated feel.** Hedging, em-dashes everywhere, abstract claims with no verifiable detail.
11. **Padded subject lines.** Long, punctuation, numbers, first-names, brackets. Keep to 2–6 lowercase words.
12. **Stale signals.** 90d most categories / 30d hires-exec moves / 14d intent.
13. **Multiple CTAs.** Exactly one per email.
14. **Bullets in emails <100 words.** Fragments the mobile read.
15. **Invented stats / customer names.** Hard rule.
16. **Personalization stacking.** One ladder tier only.

## Workflow

### 1. Pull GTM context (always)
`get_gtm_context(detailed: true)` → `offering_profile`. If empty, flag.

### 2. Honor input data first
**INPUT DATA FIRST, TOOLS LAST.** If user supplied template / sender info / recipient email / prior touchpoint summary / outreach context, use directly. Only call tools for missing data.

### 3. Resolve the prospect
- ZI person ID → use directly.
- Email → `enrich_contacts(email)`.
- Name + company → `enrich_contacts(firstName/lastName/companyName)`; fall back to `search_contacts`.
- Resolve the prospect's company ID.
- **Recipient email required** — refuse if unresolvable.
- **Multi-recipient rule** — use only the first; never reference others.

**Stale-record handling.** If `lastUpdatedDate` >12mo OR current `companyName` doesn't match user-named company: use company-level signals only, skip `contact_research`, surface caveat, suggest verifying role.

### 3.5. Relationship-context pre-flight (mandatory)

Tag the resolved company. **Wait for user confirmation when the label is anything other than `prospect`.**

- **`competitor`** — matches `get_gtm_context.competitors`. **Hard-warn.** Surface and ask: reroute to partnership/displacement-defense, acknowledge intentional targeting, or refuse.
- **`customer`** — in `get_gtm_context.customers` / `proof_bank`. Suggest switching use_case to `expansion` or `renewal`.
- **`partner`** — in `get_gtm_context.partners` / `integration_partners`. Surface co-sell / integration angle.
- **`prospect`** — default; proceed.

**Pipeline-account check (specialization).** Run `account_research(zoominfoCompanyId, query="Open opportunities, active deal stages, named champions, last activity date")`. Open opp → `pipeline_account` → suggest `discovery_follow_up` / `expansion`. Renewal date within 90d → suggest `renewal`. Active engagement → suggest `discovery_follow_up`.

### 4. Pull signals in parallel

Pull only what the use case needs:

- **Always:** `enrich_companies` (companyId, fields: description, industries, employeeCount, revenue, ...).
- **Cold / re-engagement / chaser:** `enrich_company_signals` (`signalTypes: ["NEWS", "SCOOP", "INTENT"]`) — returns recent news, scoops, and intent in one call. Rank and filter in step 5 (the news category, e.g. funding / M&A / product / leadership, is carried on each returned signal).
- **Discovery follow-up / demo recap / renewal / expansion / objection_handling:** primarily `contact_research` + `account_research` for prior-touchpoint reconstruction; news/scoops only as supporting context.

Always run `contact_research` for the prospect (unless record is stale), with a query tuned to the use case.

`enrich_company_signals` resolves intent topics server-side, so there is no need to pre-resolve topics via `lookup` — request `INTENT` in `signalTypes` and triage the returned topics in step 5.

### 5. Pick the anchor

- **Cold / re-engagement:** rank signals by `(recency × buyer-relevance × stage-alignment)`. Recency: 0-14d = 1.0 · 14-30d = 0.7 · 30-60d = 0.4 · 60-90d = 0.2 · >90d = drop. 80-90d signals carry an "on the cusp" caveat. Buyer-relevance: CFO ↔ funding/earnings/M&A · CRO ↔ hiring/product launch · CTO ↔ tech-stack/product · CEO ↔ all. Pick top + record runner-up.
- **Follow-up / recap / renewal / expansion / objection:** the anchor is the prior touchpoint (or contract moment, or named objection). Pull it from prior-touchpoint summary first, then `contact_research` / `account_research`. If both are silent and no touchpoint can be reconstructed → refuse and surface the gap.

**Refuse-to-produce gate (cold / re-engagement only).** Refuse when **two or more** hold:
1. **Signal layer thin** — no company-level signal ≤60d.
2. **`contact_research` GTM-irrelevant** — nothing returned, OR what was returned maps to no value prop.
3. **Positioning anchor weak** — no clean value prop in GTM context maps to the inferred pain.

All three → refuse outright. One → proceed but flag. Route refusals to warming channels or a different prospect.

### 6. Bridge to the anchor (use-case-conditional)

- **Cold / re-engagement:** use the signal → pain mapping to infer the pain: *"For [persona] at a company that just [signal], the dominant unsolved problem in the next 90 days is likely [specific pain] because [reason]."* Iterate if generic.
- **Other use cases:** the anchor is the prior touchpoint / contract / objection. The body's job is to acknowledge, surface the next step, and remove friction — not to introduce a freshly imagined pain.

### 7. Anchor positioning in GTM context
Map the inferred pain (cold/re-engagement) OR the prior touchpoint (other use cases) to one concrete claim from `offering_profile.value_props` — never the elevator pitch. Pick one proof source per the hierarchy. If no value prop maps, flag and offer to reroute.

### 8. Compose variants

**Persona-fit discipline:**
- **Strong fit** → 3 variants.
- **Moderate fit** → 2 variants.
- **Stretch fit** → 1 variant with strong opt-out CTA. Don't force volume.

**Variant angles:**
- **A — Curiosity.** Lead with observation / question; tease.
- **B — Value-frame.** Concrete claim or stat tied to the anchor (pain for cold; outcome for follow-up; objection-reframe for objection).
- **C — Urgency / window.** Timing implication. Cold: only when signal ≤30d and buying window tight. Renewal/expansion: tied to contract date.

Length per use case. Apply chosen framework. Tone: slightly casual, slightly unsure.

**Exactly one** each: personalization tier · anchor · value prop · proof source · CTA.

### 9. Subject lines

2–6 lowercase words. No punctuation / numbers / first-names / brackets. Three patterns — generate then pick strongest:
1. **Pain → Outcome** (cold). "pipeline gaps shorten replies"
2. **Trigger → Value** (cold / re-engagement). "post-close stacks"
3. **Recap → Next step** (follow-up / recap / renewal). "monday's pricing thread"
4. **Peer / Proof cue** (any). "how X improved reply rates"

### 10. Signature

If `sender_info` available, emit with **two trailing spaces per line** for Markdown line breaks:

```
Best,␠␠
Jordan Smith␠␠
Senior Account Executive␠␠
jordan.smith@example.com
```

If no sender info → omit signature. Don't invent.

### 11. Self-check before output

- ☑ Word count within use-case cap.
- ☑ Subject 2–6 lowercase words.
- ☑ Opens with personalized hook (no generic greeting).
- ☑ Cold / re-engagement: signal → pain → positioning chain present and specific. Other use cases: prior-touchpoint anchor present.
- ☑ Exactly one each: ladder tier · anchor · value prop · proof source · CTA.
- ☑ ~Grade 8; mobile-readable.
- ☑ No clichés, jargon, filler, invented stats.
- ☑ Recipient email present.
- ☑ Signature: two trailing spaces per line OR omitted entirely.
- ☑ All 16 anti-patterns cleared (including #6 — pain not forced on non-cold use cases).

### 12. Rubric (final scoring)

Score 0–2 per dimension. Bar: ≥8/10. Drop or regenerate failures.

1. **Specificity** — verifiable fact about *this* prospect.
2. **Anchor strength** — for cold: pain bridge; for follow-up: prior-touchpoint reference; for renewal: contract moment.
3. **Positioning** — specific GTM-context claim.
4. **Reciprocity** — gives insight / framing / opt-out before asking.
5. **Send-worthiness** — would a senior seller press send?

### 13. Present + offer iteration

1. Accept variant.
2. Different signal (runner-up) — cold / re-engagement.
3. Different persona at same company.
4. Tighter anchor.
5. Switch angle.
6. Adjust tone (casual / formal / direct).
7. Switch use case.

Iterate from step 6. Track variant evolution. Terminate on accept or pivot.

## Fallback rules

- **Contact lookup fails** → `Hi [First Name]` greeting; continue.
- **No public/CRM history** → skip `contact_research`; company signals only.
- **Company sparse** → role-based personalization (drop to P1).
- **Sender info missing** → omit signature.
- **GTM context fails** → generic capability statement (proof tier 4); surface gap.
- **No signal passes recency floor (cold)** → refuse; route to warming.
- **No prior touchpoint reconstructable (follow-up)** → refuse; ask the user for a summary.

Never block on a single missing tool (recipient email is the hard gate). Never invent data.

## Output Format

### TL;DR — Email for [Prospect Name], [Title] at [Company] · Pass [N]

*Use case: [restate]. Framework: [AIDA / PAS / Challenger / Becc Holland].*

**Anchor.** [For cold: signal + age + one-liner. For follow-up: prior touchpoint summary. For renewal: contract moment. For objection: stated objection.]
**Bridge.** [For cold: inferred pain in one sentence. For others: omit OR brief next-step framing.]
**Positioning.** [Specific GTM-context value prop.] *Proof source:* [tier 1/2/3/4].

---

### Variant A — [angle]
**Subject:** [2–6 lowercase words]
[Body within use-case cap.]

### Variant B — [angle] *(if persona fit ≥ moderate)*
**Subject:** [2–6 lowercase words]
[Body.]

### Variant C — [angle] *(if persona fit strong)*
**Subject:** [2–6 lowercase words]
[Body.]

---

### Rationale

| | |
|---|---|
| Use case | [label] |
| Anchor | [signal+age / touchpoint / contract / objection] |
| Personalization tier | [P0–P3] |
| Pain (cold/re-engagement only) | [pain] |
| Value prop | [claim] |
| Proof source | [tier 1–4] |
| Framework | [AIDA / PAS / Challenger / Becc Holland] |
| Rubric | A: [X/10] · B: [X/10] · C: [X/10] |

### Iteration options

1. Accept [variant] → hand off to sequencer.
2. Different signal — anchor on [runner-up].
3. Different persona at the same company.
4. Tighter anchor.
5. Switch angle.
6. Casual / formal / direct.
7. Switch use case.

### Caveats (when relevant)

- **Relationship flag** — if `competitor` / `customer` / `partner` / `pipeline_account`, variants assume user confirmed override.
- **Thin signal** — variants on weak base; warm on another channel first.
- **Empty signal (cold)** — 0 variants; route to warming.
- **Stretch fit** — 1 variant only.
- **Stale-signal cliff** (60–90d) — urgency angle unavailable.
- **Edge-of-recency** (80–90d) — on the cusp.
- **Stale prospect record** — verify role before sending.
- **No prior touchpoint** (follow-up) — refused; ask for a summary.
- **GTM-context gap** — positioning generic; update GTM context.
- **Sender info missing** — signature omitted.

### Chain Targets

- Hand to a sequencer (e.g., Outreach, Salesloft).
- Multi-step sequence → run once per step with different signals + use cases.
- Batch personalization → `personalize-at-scale` (future scope).
- Different prospect at same company → re-run with new identifier.
qbr-prep4.04 KB

View saved version →

---
name: qbr-prep
description: 'Assemble a QBR prep pack for a business review — value moments, usage and adoption themes, risks, and open items, with a deal and relationship snapshot. Combines account_research for the account picture with conversation_intelligence over recent calls (scoped to individual engagements) for what the customer actually said. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone says "prep me for the Acme QBR", "build a QBR pack", "what should I cover in the business review", or needs a review-ready summary. Evidence-based: value moments, themes, and risks come from the conversations and CRM, not from assumption.'
---

# QBR Prep Pack

Everything to walk into a quarterly business review: what value landed, what the customer has been raising, where the risks are, and what to cover.

## Prerequisites

`account_research` and `conversation_intelligence` consume AI credits (CI is a minimum ~9 per call), and this skill runs `account_research` plus CI once per key engagement, so it can be credit-heavy. `browse_engagements` (to find the calls) is free but requires an active calendar/meeting integration; `conversation_intelligence` requires at least one connected meeting or email source. If no conversation data exists, build the pack from `account_research` and flag that value moments and themes could not be drawn from conversations, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Review scope** (optional) — the period being reviewed and the QBR's goal (renewal runway, expansion, adoption push). Shapes what to foreground; ask if it materially changes the pack and was not provided.

## Workflow

1. **Resolve the account.** If no account was supplied, ask the user which one before proceeding. Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Snapshot the account.** Run `account_research` for the deal/relationship picture, stakeholders, and recent firmographic/news context. This frames the review.
3. **Read recent calls.** Call `browse_engagements` (account-scoped, `engagementType: MEETINGS`, `sort: -chronological`) and pick the few most relevant recent calls (typically the last 2-4 — each gets its own CI call, which costs credits). Run `conversation_intelligence` scoped to each engagement ID (one call per engagement) for value moments the customer voiced, usage and adoption themes they raised, risks and concerns, and open items. Keep each query to its single engagement; CI sees only the last few engagements and cannot topic-search or count.
4. **Assemble the pack.** Synthesize into a review-ready structure. Ground value moments and risks in specific conversations or CRM context with sources; do not assert outcomes the evidence does not support. Note that usage/adoption themes here come from what was discussed, not from product telemetry (ZoomInfo does not have product-usage data).

## Output Format

### QBR Prep Pack — [Company]

**Snapshot** — deal status, relationship, key stakeholders, and any notable recent context (from `account_research`).

**Value delivered** — the value moments and outcomes the customer actually acknowledged, each with its source call. This is the heart of the review.

**Usage & adoption themes** — what the customer has said about how they are using the product and where adoption stands, drawn from the conversations (not telemetry). Note thin coverage rather than inventing it.

**Risks & open items** — evidence-backed risks and unresolved items going into the review, each with a source and, where possible, a handle.

**Suggested QBR focus** — the two or three things to lead with or land in the review, tied to the above.

### When there is no data

If conversation data is unavailable, deliver the `account_research`-based snapshot and state that value moments, adoption themes, and conversational risk could not be assembled, so the pack is limited to the account view.
recommend-contacts4.7 KB

View saved version →

---
name: recommend-contacts
description: Get AI-powered contact recommendations at a target company based on your ZoomInfo interaction history. Provide a company name or domain and optionally a use case.
---

# Recommended Contacts

Get ML-ranked contact recommendations at a target company, personalized to your ZoomInfo usage and CRM data.

## Input

The user will provide via `$ARGUMENTS`:
- A company name, domain, or ZoomInfo company ID (required)
- Optionally: a use case — "prospecting", "deal acceleration", or "renewal" (defaults to PROSPECTING)
- Optionally: how many results they want (defaults to 25, max 100)

## Workflow

1. **Lookup metadata first** — before calling any other MCP tool, use `lookup` to load reference data for any fields relevant to the request. Use the returned `id` values (not display names) in all subsequent API calls. This ensures accurate parameter resolution and result interpretation.

2. **Resolve the company** if the user provided a name or domain:
   - Use `search_companies` with `companyName` or `companyWebsite` to find the company — use lookup `id` values for any filters.
   - Extract the ZoomInfo company ID from the result.

3. **Enrich the company** using `enrich_companies` with the resolved `companyId` to get firmographic context (industry, size, revenue, business model). This context is used to interpret the recommendations.

4. **Map the use case** to the correct enum value:
   - "prospecting" or default → `PROSPECTING` (based on contacts you've viewed, copied, or exported on the ZoomInfo platform; has cold-start support)
   - "deal acceleration" or "new business" → `DEAL_ACCELERATION` (based on contacts in closed-won CRM opportunities for new business)
   - "renewal", "growth", or "expansion" → `RENEWAL_AND_GROWTH` (based on contacts in closed-won CRM opportunities for renewals)

5. **Get recommendations** using `get_recommended_contacts` with:
   - `ziCompanyId`: the resolved ZoomInfo company ID
   - `useCaseType`: the mapped enum value
   - `pageSize`: user-specified count or 25

6. **Enrich the top contacts** using `enrich_contacts` on the top 10 results (batch of 10) to get full contact details including email, direct phone, and accuracy scores.

## Output Format

### Target Company
One-line summary: [Company Name] — [Industry], [Employee Count] employees, [Revenue], [HQ Location]

### Use Case
State which use case was used and what it means:
- **PROSPECTING**: "Recommendations based on contacts similar to those you've recently viewed, copied, or exported in ZoomInfo."
- **DEAL_ACCELERATION**: "Recommendations based on contact patterns from your CRM's closed-won new business deals."
- **RENEWAL_AND_GROWTH**: "Recommendations based on contact patterns from your CRM's closed-won renewal deals."

### Recommended Contacts

| Rank | Name | Title | Department | Management Level | Email | Direct Phone | Accuracy | Score |
|------|------|-------|------------|-----------------|-------|-------------|----------|-------|
| 1 | | | | | | | | |
| 2 | | | | | | | | |

For each contact, use the `meta` field from the recommendation response to explain WHY they were recommended. The meta describes the reference person the recommendation was based on. Present this as a "Why Recommended" note below the table or as an additional column.

### Recommendation Analysis

Group the recommended contacts by pattern:
- **By Department**: Which departments are most represented? (e.g., "8 of 25 are in Sales, 6 in Marketing")
- **By Seniority**: What management levels dominate? (e.g., "Heavily weighted toward Director and VP")
- **By Function**: What job functions appear most? (e.g., "Strong signal toward revenue-facing roles")

Use the resolved lookup values to categorize accurately — do not guess department or management level labels.

### Engagement Priority

Rank the top 5 contacts to engage first, with reasoning:
- Who has the highest combined relevance (recommendation score) and reachability (accuracy score)?
- Who is the likely entry point vs. the likely decision-maker?
- Suggested outreach sequence

### Next Steps
- Use `/zoominfo:enrich-contact` to deep-dive on any specific person
- Use `/zoominfo:find-buyers` if you need to filter by specific persona criteria beyond what recommendations provide
- If recommendations are sparse, note that PROSPECTING recommendations improve as you use ZoomInfo more (view, copy, export contacts). DEAL_ACCELERATION and RENEWAL_AND_GROWTH require CRM integration.

### Important Notes on Scores
- The `score` (general similarity) and `reRankingScore` (propensity-adjusted) are not directly comparable to each other
- Higher scores indicate stronger fit but do not guarantee response rates
- Recommendations refresh daily based on your latest platform and CRM activity
renewal-prep3.37 KB

View saved version →

---
name: renewal-prep
description: 'Prepare for a renewal by assembling pre-renewal context — value delivered and value moments, risk handles, and stakeholder state — from recent conversations and account_research. Identify the account by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "prep me for the Acme renewal", "what''s our case for renewal", "what are the risks going into this renewal", or wants a renewal brief. Strictly evidence-based: it does not assume the renewal date or terms; if those are not provided, it asks the user before drafting.'
---

# Renewal Prep

Build the case and the risk map for a renewal: where value has landed, what could derail it, and who decides — grounded in what was actually said.

## Prerequisites

`conversation_intelligence` requires at least one connected meeting or email source; `conversation_intelligence` and `account_research` consume AI credits. `browse_engagements` (optional cadence check) is free and needs an active integration. If no conversation data exists, build from `account_research` and say the value/risk read is limited, pointing the user to their ZoomInfo admin.

## Input

Provided via `$ARGUMENTS`:

- **Account** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`.
- **Renewal details** (ask if not given) — the renewal date, term, and ARR are often not in ZoomInfo data. Do not assume them. If they matter to the brief and were not provided, ask the user before drafting.

## Workflow

1. **Resolve the account.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
2. **Confirm the renewal basics.** If the renewal date/term/value are not supplied and the brief depends on them, ask the user once. Do not invent a renewal date — an unprompted wrong date is worse than an acknowledged unknown.
3. **Gather evidence.** Run `conversation_intelligence` scoped to the account for value moments (wins, outcomes, positive signals customers voiced), risks and unresolved concerns, and stakeholder engagement. Pull `account_research` for deal history and relationship context. Optionally use `browse_engagements` for recent cadence. Keep CI scoped to the account; it sees only the last few engagements.
4. **Assemble the brief.** Make the renewal case from evidence (specific value the customer acknowledged), map the risks with handles, and flag any assumption you could not verify.

## Output Format

### Renewal prep — [Company]

**Renewal basics** — date, term, ARR if known; otherwise "not provided — confirm with the user" (do not guess).

**The case for renewal** — value moments and outcomes the customer actually acknowledged, with source moments.

**Risks & handles** — each risk (with evidence), and a concrete way to address it before the renewal conversation.

**Stakeholders** — who holds the renewal, champion status, anyone who has gone quiet.

**Recommended plan** — one to three evidence-based moves leading into the renewal.

### Evidence discipline

Build the case from what the customer said, not from generic value claims. Mark assumptions clearly. Where you asked the user for renewal details, attribute them.

### When there is no data

If conversation data is unavailable, give the `account_research` view, note that value moments and conversational risk could not be assessed, and ask the user for the renewal specifics.
score-accounts18 KB

View saved version →

---
name: score-accounts
description: Score and rank a list of accounts (mixed ZoomInfo company IDs, names, or domains) by ICP fit + buying intent + recent triggers. Returns per-account composite score (0–100), tier (A/B/C), explainable component breakdown (fit / intent / trigger / engagement), a specific "why now" sentence per account, and the working weight set as a saveable search filter set. Resolves name/domain inputs via search_companies with explicit confirmation for ambiguous matches. Iteratively refinable — adjust weights, swap axes, retier, or drill into a specific account. Use for account-based selling, ABM list prioritization, territory planning, sales prospecting prioritization, signal-based selling, buyer intent ranking, B2B prospecting. Triggers on phrases like "score these accounts", "prioritize this list", "rank by ICP fit and intent", "which accounts should I work first", "build a tiered account list".
---

# Score Accounts

Rank a list of accounts by ICP fit + intent + trigger signals. Calls `get_gtm_context(detailed: true)` unconditionally, resolves mixed-identifier inputs explicitly surfacing ambiguity, scores each account on four axes, and presents both the ranking and the weight set as iteratively-refinable artifacts.

## The bar

1. **Resolution accuracy 100%** — every input auto-resolved / verified / ambiguous / failed. Nothing silently picked.
2. **Every score explainable** — composite is a transparent weighted sum, never an opaque number.
3. **"Why now" cites a specific signal** — not the composite restated.
4. **Every tier comes with a recommended action.**
5. **Weights and axes are exposed and overridable.**

Sellers reject black-box scores. Transparency + per-account "why now" are what make this skill trusted.

## Scope

Scores **company-level accounts**, not contacts. Persona-aware ranking is a chain target via `personalize-email` after tier-A is produced.

## Input

- **Accounts (required)** — list of ZI IDs / company names / domains / mixed CSV.
- **Use case (default `prospecting`)** — `prospecting`, `abm`, `territory_planning`, `pipeline_acceleration`. Affects tier thresholds + recommended actions.
- **Weight overrides (optional)** — `{fit, intent, trigger, engagement}` summing to 100.
- **Tier thresholds (optional)** — `{A, B}`. C is the remainder.
- **ICP override (optional)** — natural-language refinement on top of `get_gtm_context.icp`.
- **Intent topics (optional)** — explicit list overriding GTM-derived defaults.

## Four-axis framework

| Axis | Question | Source |
|---|---|---|
| **Fit** | Does this match our ICP? | `enrich_companies` vs `get_gtm_context.icp` |
| **Intent** | Are they actively researching topics we sell into? | `enrich_company_signals` (intent), matched to GTM priorities |
| **Trigger** | Fresh event creating a window? | `enrich_company_signals` (news + scoops), last 90d by signal date |
| **Engagement** | Already interacting with us? | `account_research` narrative for known accounts. If absent, weight redistributed. |

Each axis 0–100 independently. Composite is the weighted sum — never collapsed to an opaque number.

## Default weights

```
fit:        45%
intent:     25%
trigger:    25%
engagement:  5%   (redistributed if unavailable)
```

User overrides accepted. Weights are exposed in every output. Cache per-axis scores; recompute only the composite when weights change.

## Tier thresholds

| Tier | Composite | Recommended action |
|---|---|---|
| **A** | ≥ 75 | Route to AE for 1:1 outreach within 24h. Chain to `personalize-email`. |
| **B** | 50–74 | SDR sequence; ABM retargeting; nurture-to-meeting. |
| **C** | < 50 | Watchlist; monitor for tier-promotion signals. |

Use-case adjustments: `abm` → A=80/B=55 · `territory_planning` keeps defaults · `pipeline_acceleration` → A=65/B=40.

## Workflow

### 1. Pull GTM context (always)
`get_gtm_context(detailed: true)`. Capture ICP, personas, competitors, offerings, strategic priorities. ICP = fit-axis target; strategic priorities → intent-topic curation.

### 2. Honor input data first
Use user-supplied weights / thresholds / ICP refinements / intent topics. Fall back to GTM defaults only for missing fields.

### 3. Resolve identifiers (four-bucket routing)

- **Auto-resolved** — top match dwarfs alternatives. Score without confirmation.
- **Verified** — clear top match BUT plausible alternatives exist. Score; surface verification note.
- **Ambiguous** — no dominant match. Pause scoring; surface candidates.
- **Failed** — no match. List separately.

Routing by input type:
- **Numeric ZI ID** → auto-resolved.
- **Domain** (`.com` / `.io` / `.co` / `.ai`) → `search_companies(companyWebsite)`. Single match → auto-resolved. Multiple → ambiguous.
- **Name** → `search_companies(companyName)`.
  - Top match's size/revenue dwarfs alternatives → auto-resolved.
  - Clear top but 3+ plausible alternatives → verified with note.
  - No dominant match → ambiguous.
- **No match** → failed.

**Surface rule.** Never silently pick a winner. Present top 5 with attributes; ask user to confirm. Use GTM context as soft tiebreaker for `verified` (e.g., a B2B SaaS context defaults an ambiguous name to the SaaS-industry candidate over an unrelated-industry candidate, with a flag).

**Domain-confirmation gate (mandatory for high-collision names).** When `search_companies(companyName=X)` returns >100 matches AND no strong GTM tiebreaker exists, require domain confirmation. Surface top match's domain and ask. Never silently auto-pick — cost of getting it wrong is scoring the wrong company entirely.

**Duplicate-record detection (mandatory).** If top candidates share the same domain root (e.g., `acmeco.com` and `acmecoinc.com`) AND ≤20% revenue diff AND same metro/country → flag suspected duplicate. Surface both records and offer to union. For signal-heavy workflows, scoring both and unioning is the right default — signals may be split across records.

Resolution path must hit 100% accuracy. Score auto-resolved + verified immediately; pause ambiguous; list failed separately.

### 3.5. Relationship-context pre-flight (mandatory)

Tag each resolved account against GTM context. Tag visible on the row before the tier letter — sellers see relationship status BEFORE running the play.

- **`competitor`** ⚔️ — in `get_gtm_context.competitors`. Don't exclude from ranking (competitive intel matters) but make it impossible to miss visually.
- **`customer`** 🤝 — in `get_gtm_context.customers` / `proof_bank`. Shift recommended action to expansion / renewal.
- **`partner`** 🔗 — in `get_gtm_context.partners` / `integration_partners`. Shift to co-sell / integration angle.
- **`prospect`** — default; no tag.

In the row label: `⚔️ [Account] (B 62)`. Skill never silently produces "pursue this competitor" rankings.

### 4. Define the intent relevance set
From `get_gtm_context.strategicPriorities`, offerings, and competitor categories (or a user-supplied list), derive 5–10 themes you sell into. `enrich_company_signals` returns each company's active intent topics directly — there is no topic lookup or pre-query step — so these themes are the **match set** used in scoring (step 6): a returned topic counts toward intent only if it maps to one of them. Keep the themes; the matching happens per account during scoring.

### 5. Fetch data per account (parallel, batched ≤10; chunked for large lists)

Both calls below batch multiple accounts per request, so fetch a chunk of accounts together rather than one-by-one:
- `enrich_companies(zoominfoCompanyIds: [chunk], fields: industries, employeeCount, revenue, country, metroArea, businessModel, employeeCountByDepartment, foundedYear)` — up to 25 per call.
- `enrich_company_signals(zoominfoCompanyIds: [chunk], signalTypes: ["INTENT", "NEWS", "SCOOP"])` — up to 10 per call. Returns each account's recent intent topics (each with `signalScore` and `audienceStrength`), news (with `category`), and scoops (with `scoopType`), plus a `date` on every signal. Do **not** pre-filter on score, topic, category, or date — that is applied during scoring (step 6).

**Hard batch limit: ≤10 accounts per `enrich_company_signals` call (≤25 per `enrich_companies` call).**

**Batch + context-window discipline.** For lists >25 accounts, process in **chunks of ~25 accounts** end-to-end (resolve → fetch → score → compose row → write chunk → discard raw payloads) before moving to the next chunk. Don't accumulate full raw enrichment payloads for hundreds of accounts in working context — once per-axis scores + the winning trigger event + the winning intent topic are captured per account, drop the rest. For >100-account lists, summarize completed chunks into running totals (tier distribution, top-A list, multi-product anomalies, duplicate-suspected flags, missing-axes counts) and discard the per-account breakdowns from context. Output is built incrementally chunk-by-chunk so a long list doesn't blow context.

Skip `account_research` here; fire selectively in §7.5 for tier-A.

### 6. Score each axis

**Fit (0–100)** — compare `enrich_companies` to `get_gtm_context.icp`:

| Dimension | Max | Banded scoring |
|---|---|---|
| Industry / sub-industry | 25 | Primary = 25 · secondary = 15 · adjacent = 8 · none = 0 |
| Employee count band | 20 | In band = 20 · one off = 12 · two off = 4 · outside = 0 |
| Revenue band | 20 | Same banding |
| Geography | 15 | ICP country = 15 · in continent = 8 · outside = 0 |
| Business model | 10 | B2B/B2C match = 10 · mixed = 5 · mismatch = 0 |
| Technographic (optional) | 10 | Uses named tech-stack vendor = 10 · else 0. Verify via `search_contacts` + `techAttributeTagList` if needed. |

Cache per account; reuse across weight changes.

**Intent (0–100)** — from the `enrich_company_signals` intent topics, keep those that map to the relevance set (step 4) with `signalScore` ≥ 60 in roughly the last 30 days (use each signal's `date`). Score `max(signalScore × audienceStrengthFactor)` over the survivors. A=1.0 · B=0.85 · C=0.7 · D=0.55 · E=0.4 (from `audienceStrength`). Cap 100. Record the winning topic for "why now." If no relevant intent survives → 0 with "no relevant intent activity" flag.

**Trigger (0–100)** — from the `enrich_company_signals` news and scoop signals, kept to the last 90 days by each signal's `date` (drop older). Map each signal's news `category` or scoop `scoopType` to the weight below:

```
event_score = signal_type_weight × recency_factor
```

| Signal type | Weight |
|---|---|
| M&A, Funding, New CEO/C-suite hire | 95 |
| Product launch, Hiring surge, Earnings beat/miss | 75 |
| Partnership, New facility | 55 |
| Pain-point scoop, Other PERSON moves | 45 |
| Generic press release | 25 |

Recency: 0-14d=1.0 · 14-30d=0.7 · 30-60d=0.4 · 60-90d=0.2 · >90d=0.

Account trigger = `max(event_score)` capped at 100. Record winning event for "why now."

**Engagement (0–100)** — if `account_research` returns rich CRM context: active deal/renewal/champion = 80–100 · past meeting/known stakeholder = 40–70 · no history = null. If null, redistribute weight and surface gap.

### 7. Compute composite + assign tier

```
composite = round((fit × w_fit + intent × w_intent + trigger × w_trigger + engagement × w_engagement) / 100)
```

Assign per thresholds. Default A≥75 / B 50–74 / C<50 (use-case overrides apply).

### 7.5. Auto-pull `account_research` on tier-A rows (mandatory)

Tier A = "route to AE in 24h." Engagement-axis gap on tier-A is the highest-cost gap to close.

For each tier-A account (and ONLY tier-A — cost control): `account_research(zoominfoCompanyId, query="Open opportunities, active deal stages, named champion or blocker, last activity date, renewal timing")`. Parse for:
- **Open deal status** — stage, value, next step.
- **Renewal date** — surface prominently if within 90 days.
- **Named champion / blocker** — source-tag `[from account_research]`.
- **Last activity** — flag if >60 days old.

Append inline beneath the why-now:

```
| 1 | [Account] | 🤝 A | 84 | ... | [Trigger event] X days ago — [pain-bridge]
                                     ↳ Engagement: open deal $XXXk, champion [Name], last activity Xd ago [from account_research]
```

If no CRM history → annotate "no engagement signal — cold open."

For tier-B/C: skip — cost-to-value doesn't justify.

### 8. Compose "why now" per account

One sentence anchored on the strongest signal:

- **Trigger + in-tier fit** → cite event + date. "Closed [counterparty] acquisition 20 days ago."
- **High intent** → cite topic + score + recency. "Spiked on '[topic]' (score 92, audience A) over 14 days."
- **Strong fit, no fresh signal** → "Perfect-fit ICP — no fresh trigger; pursue on fit alone."
- **Engagement-driven** → "Active deal in flight; renewal due in 47 days."
- **Strong trigger BUT C-tier (fit mismatch)** → be explicit about routing: "Do not pursue — strong trigger (new CEO 10 days ago) but ICP mismatch ([reason]) keeps this low priority." Don't bury the trigger; surface BOTH signal and recommendation.
- **Low signal across all axes** → "Low signal — monitor only."

Never restate the composite as the why-now. Always cite the underlying axis driver.

### 9. Self-check before output

- ☑ Composite shown with component breakdown (fit / intent / trigger / engagement).
- ☑ "Why now" cites a specific signal, not the composite.
- ☑ Tier has a recommended next action.
- ☑ Weights + axes used exposed.
- ☑ Every input bucketed (resolved / ambiguous / failed) — none silently dropped.
- ☑ Ambiguous surfaced, not silently picked.
- ☑ Stale signals (>90d) contribute 0; not padded.
- ☑ Missing axes flagged + weights redistributed transparently.
- ☑ Iteration options offered.

### 10. Present + offer iteration

1. Accept ranking; save filter+weight set.
2. **Adjust weights** — re-rank without recomputing axes.
3. **Tighten / loosen tier thresholds.**
4. **Refilter** — remove tier C / specific industries.
5. **Swap ICP** — different ICP definition.
6. **Drill into one account** — chain to `personalize-email`.
7. **Add accounts** — extend list and re-score.

Re-execute step 5 only when account list changes. For weight / threshold / ICP changes → recompute from cached axis scores.

Terminate when user accepts, saves, or hands off.

## Anti-patterns — fail-fast checklist

1. **Black-box composite** — single number without component breakdown.
2. **"Why now" = composite restated.**
3. **Silent identifier resolution** on ambiguous names.
4. **Fixed weights not exposed.**
5. **Tier without action.**
6. **Stale signal padding** — events >90d contributing.
7. **Generic "why now"** — "good fit" applies to every account.
8. **Ignoring missing axes** — pretending engagement exists when null.
9. **Auto-accepting ambiguous matches.**
10. **No iteration affordance.**

## Fallback rules

- **`get_gtm_context` empty** → use user-supplied ICP override; surface gap.
- **No intent returned, or none matching the relevance set** → intent score = 0 (real signal, not a gap).
- **No news or scoops returned** → trigger = 0; flag.
- **Engagement unavailable** → weight = 0; redistribute proportionally.
- **All axes thin** → tier C "monitor only"; honest.
- **Resolution failure** → list separately; never silently drop.

Never block ranking on a single missing axis. Never invent data.

## Output Format

### TL;DR — Account Scoring · N accounts · Pass [M]

*Use case: [restate]. Weights · Thresholds A≥[X] · B[Y–Z].*

**Resolution:** [R resolved · A ambiguous · F failed]. [If A>0: "User confirmation required."]
**Tier distribution:** A: x · B: y · C: z.

**Top 3:**
1. [Account] (tier · composite) — [why now]
2. ...

---

### Resolution Summary

| Input | Resolved To | ZI ID | Confidence | Status |
|---|---|---|---|---|

`Status` legend: ✅ Auto-resolved · 🔍 Verified · ⚠️ Ambiguous · ❌ Failed.

**Ambiguous matches — please confirm:** [list top 5 candidates per ambiguous input with attributes].

### Ranked Accounts

*Sorted by composite descending. Engagement column `–` when redistributed.*

| # | Account | Tag | Tier | Composite | Fit | Intent | Trigger | Eng | Why now | ZI ID |

(Tier-A rows also carry an "↳ Engagement: ..." sub-line from §7.5.)

### Weights & Axes Used

```
fit:        [%]
intent:     [%]
trigger:    [%]
engagement: [%]   (redistributed if axis unavailable)
```

**Axes missing this run:** [list, or "none"].

### Recommended Actions per Tier

- **Tier A** — Route to AE for 1:1 outreach within 24h. Chain to `personalize-email`.
- **Tier B** — SDR sequence; ABM retargeting; cadence with the why-now as opener.
- **Tier C** — Monitor; re-score weekly.

### Iteration Options

1. Accept ranking; save filter+weight set.
2. Adjust weights.
3. Tighten thresholds.
4. Refilter.
5. Swap ICP.
6. Drill into one account.
7. Add accounts.

### Caveats (when relevant)

- **Ambiguous pending** — N accounts not yet scored.
- **Failed resolutions** — N inputs had no match.
- **Engagement axis unavailable** — surface per-account (`no CRM signal — consider cross-check`) for each tier-A row.
- **Signal depth** — `enrich_company_signals` returns the most recent signals per type (server-capped), so for very active accounts the intent/trigger axes reflect the most recent window rather than an exhaustive history.
- **Intent thin** — <3 topics resolved; intent directional.
- **Stale-signal cliff** — N accounts' best trigger >60d old.
- **Edge-of-recency** — N trigger events 80–90d.
- **GTM-context gap** — `icp` sparse; fit-axis precision reduced.

### Final Filter + Weight Set (on accept)

```json
{
  "icp": { /* GTM ICP or user override */ },
  "weights": {"fit": 45, "intent": 25, "trigger": 25, "engagement": 5},
  "tier_thresholds": {"A": 75, "B": 50},
  "intent_topics": ["..."],
  "use_case": "prospecting",
  "_meta": {"account_count": ..., "tier_distribution": {...}, "axes_missing": [...], "pass_count": ...}
}
```

### Chain Targets

- `personalize-email` per tier-A contact → grounded in the same "why now" signal.
- `build-list` to extend the universe.
- `find-similar` on a tier-A seed.
- `tam-sizer` with this filter set to confirm universe size.
score-leads17.9 KB

View saved version →

---
name: score-leads
description: Score and prioritize leads or cold contacts (mixed ZoomInfo person IDs, emails, or name+company rows). Returns Hot / Warm / Cold tier per lead with a response-time SLA tuned to the use case (live inbound routing, MQL triage, event follow-up, PQL triage, content follow-up, SDR queue ordering), per-axis breakdown (person fit · account fit · source signal · trigger), a "why now" reasoning snippet per lead, and recommended next action with verified contact data. Resolution by email is deterministic; name+company surfaces verification when needed; typo'd emails fail explicitly rather than fall back. Iteratively refinable. Triggers on phrases like "score these leads", "which lead/contact should I call first", "prioritize my MQLs", "rank inbound", "who should I prioritize?", "tier this list".
---

# Score Leads

Tier leads as Hot / Warm / Cold with a response-time SLA tuned to the use case. Calls `get_gtm_context(detailed: true)` unconditionally, resolves leads by email (deterministic) or name+company (surface ambiguity), scores on four axes, and presents a **scannable** per-lead output with a specific "why now" reasoning snippet so the rep can trust the tier.

## The bar

1. **Tier and SLA are the first thing the rep sees** — not buried under TL;DR or component breakdown.
2. **Resolution accuracy 100%** — every input bucketed; email typos fail loudly, never silent fallback to name search.
3. **Every Hot lead carries verified contact data** — phone + accuracy score visible. Bad data on a Hot lead = dial-the-wrong-number failure.
4. **Every tier comes with a concrete next action** — "Direct dial 555-1234. Lead with [signal]." Not "engage promptly."
5. **Every lead carries a "why now" reasoning snippet** — citing the specific axis driver (person seat × source × fresh trigger / intent / prior engagement). Never the composite restated; never generic ("strong fit"). Same trust discipline as `score-accounts`.
6. **Output scannable in <30 seconds per row.** Component breakdown below the fold.

## Scope

Scores **individual leads**, not accounts. Use `score-accounts` for company-level prioritization. For Hot leads, chain to `personalize-email`.

## Input

- **Leads (required)** — list of ZI person IDs / emails / name+company rows / mixed CSV.
- **Source (recommended)** — `demo_request`, `pricing_inquiry`, `free_trial`, `product_signup`, `content_download_high_intent`, `content_download_low_intent`, `webinar_attended`, `webinar_registered`, `newsletter_subscribe`, `cold_inbound`, `unknown`. If missing, ask once then default to `unknown` (source = 50, flagged).
- **Use case (default `inbound_routing`)** — `inbound_routing`, `event_followup`, `pql_triage`, `content_follow_up`. Drives SLA tuning.
- **Weight overrides (optional)** — `{person, account, source, trigger}` summing to 100.
- **Tier thresholds (optional)** — `{Hot, Warm}`. Cold is the remainder.

## Four-axis framework

| Axis | Question | Source | Default weight |
|---|---|---|---|
| **Person fit** | Is this individual a buyer persona? | `enrich_contacts` | **35%** |
| **Account fit** | Does their employer match ICP? | `enrich_companies` vs `get_gtm_context.icp` | **25%** |
| **Source signal** | What action got us this lead? | User-supplied | **25%** |
| **Trigger / intent** | Fresh event or intent at the employer? | `enrich_company_signals` (news + scoops + intent) | **15%** |

Weights overridable. Each axis 0–100; composite is the weighted sum.

## Tier + SLA (varies by use case)

SLA defaults below. `inbound_routing` is the live-triage motion where speed-to-lead dominates; other motions relax accordingly. Pick what fits — don't manufacture urgency the motion doesn't need.

| Tier | Composite | `inbound_routing` | `event_followup` / `pql_triage` | `content_follow_up` | Recommended action |
|---|---|---|---|---|---|
| **Hot 🔥** | ≥ 75 | < 5 min | < 1 hr | < 4 hr | Direct dial / personal outreach. Chain to `personalize-email`. |
| **Warm 🌤** | 50–74 | < 1 hr | same day | < 24 hr | SDR sequence with personalized opener. Multi-touch cadence. |
| **Cold ❄️** | < 50 | < 24 hr | < 48 hr | weekly nurture | Nurture cadence; tag for content drip; do not call. |

For high-intent sources (`demo_request`, `pricing_inquiry`, `free_trial`) in live-triage mode, fast response materially lifts qualification rate. Outside live-triage, the right SLA is longer.

## Resolution (four-bucket, lead-specific)

- **Auto-resolved** — high confidence; score immediately.
- **Verified** — match found with caveats (common name at large co); surface verification note.
- **Ambiguous** — multiple plausible matches, no clear winner; pause scoring.
- **Failed** — no match. **Never silently fall back to alternate identifier paths.**

Routing by type:
- **Numeric person ID** → auto-resolved.
- **Email** → `enrich_contacts(email)`. Email is a unique identifier. Match → auto-resolved. No match → failed. **Do NOT auto-route to name search** — a typo'd email (e.g., `firstname@compny.com`) must not silently resolve to a different real person.
- **Name + company** → `enrich_contacts(firstName/lastName/companyName)`. Single high-accuracy match → auto-resolved. Multiple plausible → verified with note. No match → failed.
- **Free-text "John Smith at Acme"** → parse and route to name+company path.

100% resolution accuracy is the gate.

## Workflow

### 1. Pull GTM context (always)
`get_gtm_context(detailed: true)`. Capture personas, ICP, strategic priorities (for intent-topic curation).

### 2. Honor input data first
Use user-supplied source / weights / thresholds / use case. If `source` is missing on a multi-row list, ask once then default to `unknown` (50, flagged).

### 3. Resolve identifiers
Per the four-bucket rules. Batch in groups of ≤10 concurrent.

### 3.5. Relationship-context pre-flight (mandatory)

Tag each lead's **company** against GTM context:
- **`competitor`** ⚔️ — in `get_gtm_context.competitors`. Hard-warn — most inbound from competitors is talent or competitive intel.
- **`customer`** 🤝 — in `get_gtm_context.customers` / `proof_bank`. Reroute to `expansion` / `discovery_follow_up`.
- **`partner`** 🔗 — in `get_gtm_context.partners`. Co-sell framing.
- **`prospect`** — default.

The relationship tag appears in the headline before the tier emoji.

For Hot leads at `customer` or `competitor` companies: pause before pushing to cold-outbound AE; surface the routing question first.

### 4. Define the intent relevance set (only if trigger weight > 0)
From `get_gtm_context.strategicPriorities` and offerings, derive 5–10 themes you sell into. `enrich_company_signals` returns each employer's active intent topics directly — no topic lookup or pre-query — so these themes are the **match set** for the intent portion of the trigger axis in step 6: a returned topic counts only if it maps to one.

### 5. Fetch data per lead (parallel, batched ≤10; chunked for large lists)
- `enrich_contacts(personId, fields: jobTitle, managementLevel, department, contactAccuracyScore, hasDirectPhone, hasMobilePhone, hasEmail, directPhone, mobilePhone, email)`.
- `enrich_companies(zoominfoCompanyId, fit-scoring fields)`.
- `enrich_company_signals(zoominfoCompanyIds: [unique employer IDs], signalTypes: ["NEWS", "SCOOP", "INTENT"])` for the employers — only if trigger weight > 0. One batched call (≤10 company IDs) covers news, scoops, and intent; dedupe employers across leads so a shared company is fetched once. No pre-filtering on score, category, topic, or date — applied in step 6.

**Batch + context-window discipline.** Process in **chunks of ~25 leads** end-to-end (resolve → fetch → score → compose row → write chunk → discard raw payloads) before moving to the next chunk. Don't accumulate full raw enrichment payloads for hundreds of leads in working context — once per-axis scores + the winning signal/topic strings are captured per lead, drop the rest. For >50-lead lists, summarize completed chunks into running totals (tier distribution, top-Hot list, missing-axes counts) and discard their per-lead breakdowns from context.

### 6. Score each axis

**Person fit (0–100)** — compare `enrich_contacts` to `get_gtm_context.buyerPersonas`:

| Dimension | Max | Banded |
|---|---|---|
| Management level | 30 | C = 30 · VP = 25 · Director = 18 · Manager = 10 · Non-Manager = 3 |
| Department | 25 | Primary persona dept = 25 · adjacent = 15 · unrelated = 0 |
| Job-title keyword | 20 | Exact = 20 · partial = 10 · none = 0 |
| Contact accuracy | 15 | ≥95 = 15 · 85–94 = 10 · 75–84 = 5 · <75 = 0 |
| Contact data completeness | 10 | email + direct + mobile = 10 · email + one phone = 7 · email only = 4 · none = 0 |

**Account fit (0–100)** — industry 30 · employee band 25 · revenue band 20 · geo 15 · business model 10.

**Source signal (0–100):**

| Source | Score |
|---|---|
| `demo_request` / `pricing_inquiry` | 100 |
| `free_trial` / `product_signup` | 90 |
| `content_download_high_intent` (comparison, RFP, pricing guide) | 75 |
| `webinar_attended` | 60 |
| `webinar_registered` | 50 |
| `content_download_low_intent` / `cold_inbound` | 35 |
| `newsletter_subscribe` | 25 |
| `unknown` | 50 (default; flag) |

**Trigger / intent (0–100)** — same logic as `score-accounts` (news, scoops, and intent come from `enrich_company_signals`, filtered to the last 90 days by each signal's `date`), with **seat-fit modifier**:
- `event_score = signal_type_weight × recency_factor × seat_fit`, where `signal_type_weight` maps from each signal's news `category` or scoop `scoopType`.
- Signal weights: 95 (M&A, funding, C-suite hire) · 75 (product launch, hiring surge, earnings) · 55 (partnership, new facility) · 45 (pain-point scoop, other PERSON moves) · 25 (generic press).
- Recency: 0-14d = 1.0 · 14-30d = 0.7 · 30-60d = 0.4 · 60-90d = 0.2 · >90d = 0.
- **Seat fit:** if event maps to the lead's seat (new CFO → CFO seat; product launch → CRO/CMO seat; hiring surge in dept X → leader of dept X) → 1.0. Otherwise 0.5. Prevents company-level triggers from inflating irrelevant leads.
- Intent: from the `enrich_company_signals` intent topics that map to the relevance set (step 4) with `signalScore` ≥ 60 in roughly the last 30 days (use each signal's `date`) — matching `score-accounts` — `max(signalScore × audienceStrengthFactor)`. A=1.0 · B=0.85 · C=0.7 · D=0.55 · E=0.4 (from `audienceStrength`).
- Take max(trigger event, intent). Cap 100.

### 7. Compute composite + assign tier
```
composite = round((person × w_p + account × w_a + source × w_s + trigger × w_t) / 100)
```
Per Hot/Warm/Cold thresholds.

### 8. Compose the per-lead row

First 30 seconds of read must contain, in order:

1. **Relationship tag** (if non-default): ⚔️ / 🤝 / 🔗.
2. **Tier emoji + label.**
3. **SLA** — tuned to the use case (see Tier + SLA table).
4. **Quality flags inline with SLA:**
   - `⚠️ verify title (record Xmo old)` — when `lastUpdatedDate` >6mo.
   - `📱 mobile only` vs `☎️ direct line`.
   - `⚠️ acc <85` — low contact-accuracy.
5. **"Why now" reasoning snippet** — one line, anchored on the strongest specific signal:
   - **Strong person + source + trigger** → "VP-Sales seat × demo request 3h ago × Series B closed 8d ago."
   - **High-source-only** → "Pricing inquiry from VP at perfect-ICP company; no fresh trigger."
   - **Trigger-anchored** → "Fresh CFO appointment 5d ago × CFO-seat lead — trigger × seat = direct match."
   - **Intent-driven** → "Spiked on '[topic]' (score 92, audience A) over 14d."
   - **Engagement-driven** (from `account_research`) → "Open opp at this account; named champion engaged 6d ago."
   - **Low signal across axes** → "Low signal — monitor only."
   Never restate the composite. Never use generic phrasing ("strong fit and engagement") — that applies to every Hot lead and tells the rep nothing.
6. **Recommended next action** — concrete, with phone number / channel.
7. **Contact data line** — email · phone · accuracy.

Example (stale-but-high-accuracy Hot lead, mobile only, `inbound_routing`):

```
🤝 🔥 Hot · Call within 5 min ⚠️ verify title (record 11mo old) · 📱 mobile only · acc 95
[First Last] · [Title] · [Company]
Why now: [Trigger event] X days ago × [seat] = direct match. (Source: [demo_request].)
Recommended: Direct dial 555-XXXX (mobile, verify title before dialing). Lead with [angle].
```

Component breakdown shown BELOW THE FOLD.

### 9. Self-check before output

- ☑ Tier + SLA (use-case-appropriate) visible in the first row of every output.
- ☑ Hot leads have verified phone + accuracy ≥85, or flag fires.
- ☑ **"Why now" snippet** on every lead — specific axis driver, never composite restated, never generic.
- ☑ Recommended next action is concrete with channel + signal.
- ☑ Component breakdown below the fold.
- ☑ Every input bucketed (auto-resolved / verified / ambiguous / failed) — none silently dropped.
- ☑ Failed emails NOT silently routed to name search.
- ☑ Source missing → flagged in caveats, not silently defaulted.
- ☑ Each row readable in <30s.
- ☑ Batch chunked when N > 25; intermediate payloads dropped from context.
- ☑ Iteration options offered.

### 10. Present + offer iteration

1. **Accept** — chain to `personalize-email` per Hot.
2. **Adjust weights.**
3. **Tighten / loosen thresholds.**
4. **Refilter** — show only Hot, exclude seats.
5. **Drill into a lead.**
6. **Add leads.**
7. **Backfill source** for unknowns.

Re-execute step 5 only when lead list changes; otherwise recompute from cached axis scores.

## Anti-patterns — fail-fast checklist

1. **Long preamble before the tier label.**
2. **Silent email→name fallback** on typo'd email.
3. **Source defaulted without flagging.**
4. **Generic "why now"** — "strong fit and engagement" applies to every Hot lead. Each row must cite the specific driver.
5. **Composite-as-rationale.** Re-stating the score number instead of the axis driver.
6. **Tier without SLA.**
7. **Hot lead with low-accuracy unflagged.**
8. **Component breakdown above the fold.**
9. **No drill-down to `personalize-email`** for Hot.
10. **Auto-accepting ambiguous matches** (e.g., 8 same-named contacts at a large enterprise).
11. **Forcing the live-triage SLA onto a non-live-triage use case.** Event follow-up, PQL triage, and content nurture motions have their own SLA bands; using the inbound-routing 5-min framing on them burns rep capacity on the wrong leads.

## Fallback rules

- **`get_gtm_context` empty** → use user-supplied personas/ICP if any; flag.
- **Source missing** → ask once; else 50 with flag.
- **Email no match** → failed; do NOT fall back to name search. If domain edit-distance ≤2 from a known-company domain (from GTM context or batch's resolved set), suggest the closest (e.g., `firstname@compny.com` → "did you mean `firstname@company.com`?").
- **Name + company multi-match** → verified with note OR ambiguous.
- **`enrich_company_signals` returns no relevant intent and no news/scoops for the employer** → trigger = 0; don't pad (absence of trigger is a real score, not a weight-redistribution case).
- **Contact accuracy <75** → flag on the row; recommend verification before dialing.

Never block tiering on a single missing axis. Never invent contact data or source.

## Output Format

### TL;DR — Lead Scoring · N leads · Pass [M]

*Use case: [restate]. SLA band: [restate]. Weights · Thresholds Hot≥[X] · Warm[Y–Z].*

**Tier distribution:** 🔥 Hot: X · 🌤 Warm: Y · ❄️ Cold: Z · ❌ Unresolved: W.

**🔥 Hot leads** (SLA per use case):

🔥 **Jordan Smith** · VP Sales at Acme Corp · **[SLA]** · *Why now: demo request × VP-Sales seat × fresh CEO hire 8d ago* · 📞 555-123-4567 · ✉ jordan@acme.com · acc 98
🔥 [next Hot lead...]

Hot listed first.

---

### Resolution Summary

| Input | Resolved To | ZI ID | Status |
|---|---|---|---|

`Status` legend: ✅ Auto-resolved · 🔍 Verified · ⚠️ Ambiguous · ❌ Failed.

### Ranked Lead List

*Hot first → Warm → Cold. Each row <30s read.*

| Tier | Name | Title | Company | SLA | Why now | Contact | Acc | Composite |
|---|---|---|---|---|---|---|---|---|

### Component Breakdown (below the fold)

| Lead | Person | Account | Source | Trigger | Composite | Tier |
|---|---|---|---|---|---|---|

### Weights & Axes Used

```
person:  [%]
account: [%]
source:  [%]
trigger: [%]
```

### Recommended Actions per Tier

SLAs adapt to the use case (see Tier + SLA table).

- **🔥 Hot — SLA per use case.** Direct dial / personal outreach. Chain to `personalize-email`. Verify phone if acc <85.
- **🌤 Warm.** SDR sequence; multi-touch cadence sized to use case.
- **❄️ Cold.** Nurture; content drip; do not call.

### Iteration Options

1. Accept → chain to `personalize-email`.
2. Adjust weights.
3. Tighten thresholds.
4. Backfill source for unknowns.
5. Drill into a lead.
6. Add leads.

### Caveats (when relevant)

- **Source missing on N leads** — defaulted to 50; backfill for precision.
- **Failed resolutions** — N unresolved; review.
- **Low contact accuracy on Hot leads** — N have acc <85; verify phone before dialing.
- **Signal depth** — `enrich_company_signals` returns the most recent signals per type, so the trigger axis reflects the most recent window for very active employers.
- **GTM-context gap** — personas sparse; person-fit reduced.
- **Stale records** — N leads' records >12mo old; current title may have changed.

### Final Filter + Weight Set (on accept)

```json
{
  "weights": {"person": 35, "account": 25, "source": 25, "trigger": 15},
  "tier_thresholds": {"Hot": 75, "Warm": 50},
  "buyer_personas": [...],
  "intent_topics": ["..."],
  "use_case": "inbound_routing",
  "_meta": {"lead_count": ..., "tier_distribution": {...}, "axes_missing": [...], "pass_count": ...}
}
```

### Chain Targets

- `personalize-email` per Hot lead → drafts grounded in the same axis driver that tiered the lead.
- `score-accounts` on the leads' companies → company-level prioritization alignment.
- `find-similar` on a Hot lead → lookalike prospects at same / similar companies.

Referenced files: 1

tech-stack-snapshot15.3 KB

View saved version →

---
name: tech-stack-snapshot
description: Produce a technology-stack snapshot for one or more companies — what CRM, marketing automation, sales engagement, data warehouse, analytics, conversation intelligence, and other tools they have tagged in ZoomInfo's database. Groups detected products by category, surfaces displacement plays for competitive tools, integration angles for partner tools, and coverage gaps honestly. Resolves mixed-identifier inputs (IDs / names / domains) with explicit ambiguity surfacing. Useful for sales prospecting, account-based selling, competitive battle-card prep, integration partner research, technographic signal analysis, B2B prospecting. Triggers on phrases like "what tech does X use", "tech stack for", "technographic snapshot", "what's in their stack", "do they use Salesforce", "competitive displacement angle".
---

# Tech Stack Snapshot

Per-company tech-stack snapshot grouped by category, with displacement angles for competitive tools and integration angles for partner tools — anchored on the user's GTM context. Resolves mixed-identifier inputs, queries `search_companies` with `techAttributeTagList` to check each product in a curated universe, and presents both the detected stack and the gaps honestly.

## How it works

`search_companies` accepts `techAttributeTagList` (tech-product IDs) as a filter:

```
search_companies(
  companyId="<input IDs, comma-separated>",
  techAttributeTagList=<one product ID>,
  pageSize=<N>
) → returns subset of input companies that have that product tagged
```

Iterate over a curated universe of ~30–50 high-relevance tech products → build a company × product matrix → group by category and pair with GTM-context-anchored plays.

## The bar

1. **Resolution accuracy 100%** — every input bucketed; never silently picked.
2. **Detections are binary and verified** — ✅ comes from a non-zero `search_companies` result; ❌ means no tag. Never invent presence.
3. **Output is grouped by category.**
4. **Recommended plays anchor on GTM context.**
5. **Coverage gaps surfaced honestly** — absence = "no tag detected", not "no tool used."

## Always-on context: `get_gtm_context`

Every run calls `get_gtm_context(detailed: true)`. Drives:
- Which categories are in scope (sales-focused vs. dev-focused).
- Which detected tools map to displacement vs. integration angles.
- Framing of recommended plays (anchored on specific value props).

## Scope

Snapshots are **company-level**. Per-person tech-skill data is out of scope.

## Input

- **Companies (required)** — list of ZI IDs / names / domains / mixed CSV.
- **Categories of interest (optional)** — any of: `sales`, `marketing`, `analytics`, `data`, `conversation_intelligence`, `intent_abm`, `cdp`, `devops`, `security`, `customer_service`, `collaboration`. Default = first 7 (B2B SaaS sales motion).
- **Custom universe (optional)** — `["product_id_1", ...]` to override curated default.
- **Use case (default `sales_prep`)** — `sales_prep`, `battle_card`, `integration_partner_research`, `displacement_targeting`. Affects play framing.

## The curated universe (default)

~30 anchor products across 7 categories. The skill resolves vendors and products at runtime via `lookup` — see §3.5 below for the canonical enumeration paths. The default anchor set:

| Category | Anchor vendors | Anchor products |
|---|---|---|
| **CRM** | Salesforce, HubSpot, Microsoft | Salesforce (generic 713) + Salesforce Sales Cloud, HubSpot CRM, Microsoft Dynamics CRM |
| **Marketing Automation** | Marketo, HubSpot, Salesforce, Oracle | Marketo Engage + Marketo (generic 172), HubSpot Marketing Hub + HubSpot (generic 248), Salesforce Pardot, Salesforce Marketing Cloud, Eloqua |
| **Sales Engagement** | Outreach, Salesloft, Salesforce | Outreach, Salesloft, Salesforce Inbox |
| **Data Warehouse** | Snowflake, Google, Databricks, Amazon | Snowflake, BigQuery, Databricks, Redshift |
| **BI / Analytics** | Salesforce, Microsoft, Google, Mixpanel, Amplitude | Tableau, PowerBI, Looker, Mixpanel, Amplitude |
| **Conversation Intelligence** | Gong, ZoomInfo | Gong, Chorus |
| **Intent / ABM** | 6sense, Demandbase, ZoomInfo | 6sense, Demandbase, ZoomInfo Intent |
| **CDP** | Segment, Treasure Data | Segment, Treasure Data |

**Always include both generic vendor IDs AND specific sub-products** — companies tagged with the generic ID won't surface if only sub-products are checked. Salesforce has 70+ tagged products; the universe must include each vendor's major sub-products.

User can extend / narrow per run.

## Enumerating the full tech taxonomy via `lookup`

The orchestrator does NOT need to memorize ZoomInfo's tech taxonomy — every list is enumerable from `lookup` at runtime. Three calls give you the entire surface area:

| Goal | `lookup` call | Returns |
|---|---|---|
| **All tech categories** | `lookup` with `fields: [{fieldName: "tech-categories"}]` | The full enum of top-level categories (20 categories like Sales, Marketing, IT Infrastructure, DevOps, Security, etc.) with their sub-category trees. Use this to decide which categories are in scope or to extend beyond the default 7. |
| **Vendors in a category** | `lookup` with `fields: [{fieldName: "tech-vendors"}]` + `category` or `parentCategory` filter (or `fuzzyMatch=<vendor name>` for a single-vendor lookup) | The full enum of vendors. Filter by category to expand the universe systematically (e.g., all CDP vendors); filter by `fuzzyMatch` to resolve a specific vendor name. |
| **Products for a vendor** | `lookup` with `fields: [{fieldName: "tech-products"}]` + **required** `vendor` (or `category` / `parentCategory`) filter | All products that vendor has tagged. `tech-products` REQUIRES at least one of `vendor`, `category`, or `parentCategory` — calling it without a filter returns 0. Note that single vendors can have many sub-products (e.g., Salesforce has 70+ products tagged). |

Use this path when the user asks "what categories of tech does ZI track?" / "what vendors exist in the [X] category?" / "what are all the products for [vendor]?" — and when extending the universe beyond the default 7 categories without hardcoding new entries.

`lookup` quirk to respect: multi-field requests with per-field `fuzzyMatch` can silently fail on the second field. Call once per fieldName when using `fuzzyMatch`.

## Workflow

### 1. Pull GTM context (always)
`get_gtm_context(detailed: true)`. Capture competitors (displacement framing), offerings (integration framing), strategic priorities, ICP (sanity-check).

### 2. Honor input data first
Use user-supplied categories / custom universe / use case. Default only for missing fields.

### 3. Resolve identifiers (four-bucket routing — same as `score-accounts`)

- **Numeric ZI ID** → auto-resolved.
- **Domain** → `search_companies(companyWebsite)`. Single match → auto-resolved. Multiple → ambiguous.
- **Name** → `search_companies(companyName)`. Dominant top match → auto-resolved. Clear top with plausible alternatives → verified. No dominant winner → ambiguous.
- **No match** → failed.

100% resolution accuracy. Probe only resolved + verified rows.

**Domain-confirmation gate (mandatory for high-collision names).** When `search_companies(companyName=X)` returns >100 matches AND no strong GTM tiebreaker, require domain confirmation. Never silently auto-pick — the cost is wasted MCP calls AND misleading output.

**Duplicate-record detection (mandatory).** If two+ candidates share same domain root, ≤20% revenue diff, AND same metro/country → flag suspected duplicate. **Probe BOTH records and union the detections** — tags may be split across entries (record A might have Salesforce; record B might have HubSpot). Annotate `[from A]` / `[from B]` in the output.

Probing one record and reporting "no detections" is the failure mode this rule prevents.

### 4. Build the product universe

For each category in scope:
- `lookup tech-vendors fuzzyMatch=<vendor>` — one call per anchor vendor (multi-field fuzzyMatch is unreliable). For category-wide expansion, use `lookup tech-vendors` with a `category` or `parentCategory` filter instead of fuzzyMatch — returns the full vendor list for that category.
- `lookup tech-products vendor=<resolved-vendor-name>` — returns the vendor's full product catalogue; select anchor products by name match. Requires at least one of `vendor`, `category`, or `parentCategory`.
- Aggregate to `{product_id, product_name, category, vendor}`.

To enumerate the full tech taxonomy (categories → vendors → products) instead of hardcoding, see the table in "Enumerating the full tech taxonomy via `lookup`" above.

If custom universe supplied, skip this step; attach category metadata for grouping.

### 5. Probe each product against the input company list

For each product ID, run **one batched call** (not one-per-company):

```
search_companies(
  companyId="<resolved IDs, comma-separated>",
  techAttributeTagList=<product-id>,
  pageSize=<N>
)
```

Cache per (product × company) into a matrix.

**Batch limit:** ≤10 concurrent `search_companies` calls. For 30 products, 3 sequential batches of 10.

### 6. Build per-company snapshots

For each company:
- Group detections by category.
- **Multi-product anomaly.** If ≥3 products in the same category are tagged (Marketo + Pardot + Marketing Cloud), surface "multi-product anomaly" flag. Don't pick a "primary." Common causes: multi-BU, stale tagging from acquisitions, ZI overlap. Surface so the user investigates.
- **Stack signature.** Top 4-5 detected tools as a short label (`Salesforce + Marketo + Snowflake + Mixpanel`). If <3 detections, label "sparse — likely incomplete coverage."
- Identify coverage gaps — categories with no detected product.
- **Size vs. universe mismatch.** If `employeeCount` < 50 AND universe is enterprise-default, surface: "small company / enterprise universe — default universe may be blind to SMB tools (Pipedrive, Mailchimp, Zoho). Recommend switching to SMB universe or extending."

### 7. Map to displacement / integration angles

For each detected tool, apply the GTM-context-anchored angle library:

- **In `get_gtm_context.competitors`** → displacement angle anchored on a GTM offering / value prop.
- **In `get_gtm_context.offerings.integration_partners`** → integration angle.
- **Neither** → neutral note; don't fabricate.
- **Category gap mapping to a GTM offering** → opportunity flag (e.g., "No intent/ABM tool detected — greenfield for [the matching GTM-context offering]").

### 8. Self-check before output

- ☑ Resolution buckets clean.
- ☑ No fabricated detections (every ✅ from a non-zero `search_companies` result).
- ☑ Detections grouped by category.
- ☑ Stack signature surfaced (or "sparse" label).
- ☑ Coverage gaps explicit.
- ☑ Plays anchored on GTM context (not generic).
- ☑ "What we didn't check" caveat included.
- ☑ Stale-tag caveat included.
- ☑ Iteration options offered.

### 9. Present + offer iteration

1. **Accept** — save universe + snapshot.
2. **Extend the universe** — add products/vendors.
3. **Drill into a category** — broaden the product list.
4. **Drill into a company** — full vendor-by-vendor detail or run `account_research` for deal-context layered on top.
5. **Switch use case** — battle-card / integration-partner-research / displacement-targeting.
6. **Chain to `personalize-email`** for a contact at a detected-competitor account.

## Anti-patterns

1. **Fabricating tech presence.** Never claim a tool is present if `search_companies` returned 0.
2. **Overclaiming coverage.** Default universe is ~30–50 of thousands of products; say so.
3. **Absence-as-evidence-of-no-tool.** "No tag detected" ≠ "company doesn't use this." Could be data gap, recent adoption, or non-standard naming.
4. **Generic displacement angles.** "We're better than Salesforce" is not a play. Every angle anchored on GTM context.
5. **Flat product list.** Category grouping is mandatory.
6. **Single-product vendor check.** Salesforce has 70 tagged products — the universe must include each vendor's major sub-products.
7. **No GTM context** → block the run; skill can't produce plays.
8. **Silent auto-pick on ambiguous resolution.**

## Fallback rules

- **`get_gtm_context` empty** → continue with detections only; suppress angle library; surface "no GTM context — generic angles only."
- **Vendor lookup fails** for a category → drop that vendor; flag.
- **All products return 0 for a company** → "No tag matches in the universe checked. Could be ICP-mismatch (too small / wrong industry) or a data gap. Recommend manual verification."
- **Ambiguous resolution** → pause; never silently pick.
- **Failed resolution** → list separately.

## Output Format

### TL;DR — Tech Stack Snapshot · N companies · Pass [M]

*Use case: [restate]. Universe: [N products across M categories].*

**Resolution:** [R resolved · A ambiguous · F failed].

**Coverage snapshot:**
- Most-detected category: [e.g., "CRM (3 of 3 companies)"]
- Most-frequent product: [e.g., "Salesforce: 2 of 3"]
- Notable gap: [e.g., "Intent/ABM detected at 0 of 3 — greenfield for [matching offering]"]

---

### Resolution Summary

| Input | Resolved To | ZI ID | Status |
|---|---|---|---|

(Four-bucket framework as in `score-accounts`.)

### Per-Company Snapshots

For each resolved company:

```
## [Company Name] · ZI ID [id]
Stack signature: [tool] + [tool] + [tool] + [tool]

By category:
- CRM:                ✅ [Detected]  · ❌ [Not detected — list products checked]
- Marketing Auto:     ✅ [Detected]  · ❌ [Not detected]
- Sales Engagement:   — ([products checked]: no tag)
- Data Warehouse:     ✅ [Detected]  · ❌ [Not detected]
- BI / Analytics:     ✅ [Detected]  · ❌ [Not detected]
- Conversation Intel: — ([products]: no tag)
- Intent / ABM:       — ([products]: no tag) ← gap
- CDP:                — ([products]: no tag)

Recommended plays:
- [Detected tool] (integration partner / displacement): [GTM-context-anchored angle].
- [Category gap]: [opportunity framing tied to a GTM offering].

Caveats:
- N products across M categories checked.
- Absence = no tag in ZI; could be data gap or non-standard naming.
- ZI tech-tagging refreshes on cycles; some tags may be 6+ months stale.
```

### Cross-Company Comparison (when N > 1)

| Product | Category | Acct A | Acct B | Acct C |
|---|---|---|---|---|

### Universe Reference

| Category | Products |
|---|---|

### Iteration Options

1. Accept — save universe + snapshot.
2. Extend the universe.
3. Drill into a category.
4. Drill into a company.
5. Switch use case.
6. Chain to `personalize-email` for a detected-competitor account.

### Caveats (when relevant)

- **Universe scope** — N products / M categories. Not exhaustive.
- **Absence is absence.** No tag ≠ "doesn't use." Could be data gap, recent adoption, non-standard naming.
- **Stale-tag risk.** ZI tech-tagging refreshes on cycles; cross-check for high-stakes deal contexts.
- **Vendor resolution failures.** Any vendor that failed lookup is excluded from the universe; flag separately.
- **GTM-context gaps.** Sparse competitors / offerings → generic angles. Recommend richer GTM context.

### Chain Targets

- `score-accounts` on the same list with technographic-weighted fit.
- `personalize-email` for a contact at a detected-competitor account — anchor on the displacement angle.
- `find-similar` on a company with a strong stack — find more accounts with the same signature.
- `account-research` to pair technographics with deal narrative.
why-now3.31 KB

View saved version →

---
name: why-now
description: Build a "why now" case for reaching out to a company — the timing thesis and the specific hooks to lead with — by combining company signals (intent, news, scoops), account_research, your GTM context, and web research. Identify the company by ZoomInfo company ID (preferred) or name/domain (triggers a lookup). Use when someone asks "why should I reach out to Acme now", "what's our angle into this account", "give me a reason to call", or is planning outbound and needs timely, evidence-based hooks. Each hook ties a real signal to one of your offerings.
---

# Why Now

Answer the question a seller actually has before reaching out: why this account, why now, and what to lead with.

## Prerequisites

`enrich_company_signals` charges data credits — each signal returned counts as a record, but companies already under management (enriched within the last 12 months by your organization) are free. `account_research` consumes AI credits. `get_gtm_context` and `WebSearch` are free. Intent, news, and scoop availability depends on your ZoomInfo package; if a signal type is empty, work with what is available rather than treating it as "nothing happening".

## Input

Provided via `$ARGUMENTS`:

- **Company** (required) — ZoomInfo company ID (preferred), or a name/domain to resolve via `search_companies`. If none is supplied, ask which company.
- **Your angle** (optional) — what you sell into them, or the play you are running. Sharpens the hooks.

## Workflow

1. **Anchor on your side.** Call `get_gtm_context` (free) for offerings, ICP, competitors, and priorities. The "why now" only matters relative to what you sell.
2. **Resolve the company.** Use the ZoomInfo ID directly, or resolve a name/domain via `search_companies`.
3. **Pull the signals and context.** Run `enrich_company_signals` for the company with `signalTypes: ["INTENT", "NEWS", "SCOOP"]` (or omit `signalTypes` entirely, which returns all three) and `account_research` for deal/relationship and firmographic context, in parallel.
4. **Corroborate and extend with web research.** Use `WebSearch` for recent public developments that ZoomInfo may not carry (announcements, initiatives, leadership statements, funding) and to confirm anything time-sensitive. Capture URLs. Cross-check anything that looks stale.
5. **Synthesize the case.** Identify the strongest timing reasons — a signal that maps to one of your offerings or to a named risk/initiative. Build the thesis, then derive specific hooks. Ground every hook in a real signal with a date and source. If the signals are thin, say the timing case is weak rather than manufacturing urgency.

## Output Format

### Why now — [Company]

**Timing thesis** — 2-3 sentences on why this account is worth reaching out to now, framed by what you sell.

**Signals behind it** — the specific intent topics, news, and scoops driving the thesis, most compelling first, each with a date and source (URL for web items).

**Hooks** (2-4) — each:
- **Angle** — the opening idea.
- **Built on** — the signal it rests on (with source).
- **Maps to** — the offering or value it connects to.
- **Opener** — one line you could actually send or say.

**If the case is weak** — if signals are thin or stale, say so plainly and note what would change it (a trigger to watch for), rather than inventing a reason to reach out.
Technical details
First seen
Sep 30, 2026 · 22:02 UTC
Last seen
Oct 1, 2026 · 12:00 UTC
Collection status
Collected

plugin_asdk_app_698a340b9230819188ba5a5eea79022d

Download listing JSON