---
name: moltsets-build-target-list
description: Use this skill when the user wants to build a complete, enriched prospect list from scratch - defining a company ICP and ending up with names, companies, LinkedIn profiles, and contact data ready for outreach.
---

# Build Target List

End-to-end: define company ICP to search to enrich to export ready-to-use contact list.

## Triggers

"build me a prospect list", "create a target list", "I need contacts at [type of company] with emails", "generate outbound list", "find and enrich prospects at [type of company]". Full end-to-end ICP-to-contact-list workflow.

## Chain

```
company + people ICP criteria
  to search_people  (find people at matching companies)
  to linkedin_to_business_email     (per-URL parallel calls - business emails)
  to linkedin_to_mobile_phone              (batch array - mobile, optional)
```

## Set Expectations

Before firing any calls, give the user a brief, dry heads-up. Deadpan over enthusiastic - no filler, no corporate speak.

Facts to work with:
- 2 phases: search (paginated at 25/call) then batch enrich
- 50 prospects: ~30–60 seconds total; 100+ prospects: ~60–120+ seconds
- If paginating: search phase = X pages × ~3–5 seconds, then enrichment on top
- Include the target count and which data types will be fetched

## Step 0 - Input Quality Gate

Before proceeding, assess how much the user has provided. If no company attribute is specified, **pause and ask before searching**.

### Minimum viable input
`search_people` accepts both company and people-level filters. Gather at least one of:
| Field | Param | Example |
|---|---|---|
| Free-text (name / role / company) | `query` | "Jane Smith", "VP Sales", "Stripe" |
| Company name | `company` | "Stripe", "HubSpot" |
| Exact domain | `company_domain` | "stripe.com" |
| Industry | `industry` | "Information Technology", "Finance and Banking" |
| Seniority | `seniority` | "Director", "VP", "C Suite" |
| Department / functional area | `department` or `functional_area` | "Sales", "Marketing", "Engineering" |
| Country | `country` | "United States" |
| Target count | - | "50 contacts", "100 records" |

People filters DO exist as request params: `country`, `seniority`, `industry`, `department`, `functional_area` (use enum values), and `query` searches across name + company + title. Employee/revenue size are company filters on `search_companies` - resolve a company first if you need to scope by size.

### Vague input triggers
Trigger this gate if the user gives no company anchor, e.g.:
- "find me some prospects"
- "I need leads" (no company, industry, or size)

### Response when input is vague

Say something like:

> "To build a list I need something to scope on. Which of these can you fill in?
>
> - **Company** - name or domain, e.g. "Stripe", stripe.com
> - **Industry** - e.g. Information Technology, Finance and Banking
> - **Seniority** - e.g. Director, VP, C Suite
> - **Department** - e.g. Sales, Marketing, Engineering
> - **Country** - e.g. United States
> - **How many contacts** - e.g. 50, 100, 250"

Wait for user response before proceeding to Step 1.

### Tips to share if user asks what makes a good search
- **Industry + seniority + department** is a strong combo for role-based ICP targeting across many companies
- **Domain** (`company_domain`) is the most precise scope for a single company
- For enterprise vs. SMB targeting, resolve companies by `employee_range`/`revenue_range` on `search_companies` first

## Step 1 - Define ICP

Gather from user (confirm or fill any still missing after Step 0):
- Company name / domain
- Industry
- Seniority / department (role-level ICP)
- Country
- Target count (how many records needed)

## Step 2 - Credit check (required)

Call `MoltSets:get_billing` and `MoltSets:get_usage` with `period: billing_cycle` in parallel (free).

Estimate:
```
N prospects × linkedin_to_business_email cost = email cost
N prospects × linkedin_to_mobile_phone cost    = phone cost (if requested)
Total:                             = ~XXX credits
Current balance:                   = XXX credits
```

If estimated cost > balance: stop. Report shortfall, how many records the balance covers, ask whether to proceed partially or top up.

## Step 3 - Search

`search_people` accepts company and people filters: `query` (free-text across name / company / title), `company` (name), `company_domain` (exact), `industry`, `seniority`, `department` or `functional_area`, `country`, plus `limit`/`offset`. Use the exact enum values (seniority: Intern, Entry, Senior, Manager, Director, VP, Head, C Suite, Owner, Partner; department/functional_area: Operations, Sales, Information Technology, Education, Engineering, Finance, Medical & Health, Marketing, Human Resources, Design, Consulting, Legal - use one, not both). Title also returns as a response field for ranking.

Probe first: run `search_people` with `limit: 1` (using whatever filters apply). Check top result quality.
- Good match to scale to desired limit (max 25 per call)
- Poor match to adjust filters before scaling

For N > 25: paginate with `offset` (25, 50, 75...) until target count reached.

## Step 4 - Deduplicate

Remove duplicate LinkedIn URLs before enrichment.

## Step 5 - Bulk enrich

Business email is often already on the search records - check first and only enrich the gaps. For the LinkedIn URLs that still need data:
- `linkedin_to_business_email` takes a SINGLE `linkedin_url` - fire one call per URL, in parallel (there is no email batch array)
- `linkedin_to_mobile_phone` takes a `linkedin_urls` array (max 100) - one batch call (if phone requested)

Fire the per-URL email calls in parallel; chunk the phone array at 100 if needed. Timing is N parallel single email calls, not one batch.

## Step 6 - Output

| Name | Title | Company | Country | LinkedIn | Business Email | Mobile |
|---|---|---|---|---|---|---|

**Summary:**
```
Prospects found:   X
Business emails:   X/N (XX%)
Mobile numbers:    X/N (XX%)
Credits used:      ~XXX
```

Offer to format as a copyable CSV-style table for export.

## Edge cases

- Low email/phone hit rates are normal - credits only charged on hits
- `search_people` max 25/call - loop with `offset` for larger lists
- If filters produce < target count, suggest broadening one constraint at a time
- Stop immediately if credits run out mid-enrichment - output completed rows, report resume point
