Skip to content
Marketing
Skill

/06-resolution-email-person

Turn a company domain (plus an optional person name or job title) into a verified, send-safe email address - the deliverability-first "resolution" layer of a cold-email pipeline. Use when the user wants to find or verify a work email, enrich a list or file of domains into

From plugin
headless-gtm
2817 skills
Install
$ npx -y skills add Zevenue/headless-gtm --skill 06-resolution-email-person --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/06-resolution-email-person

Context preview

The summary Claude sees to decide when to auto-load this skill.

Turn a company domain (plus an optional person name or job title) into a verified, send-safe email address - the deliverability-first "resolution" layer of a cold-email pipeline. Use when the user wants to find or verify a work email, enrich a list or file of domains into

SKILL.md

06-resolution-email-person.SKILL.md
name: 06-resolution-email-person
description: >-
  Turn a company domain (plus an optional person name or job title) into a verified,
  send-safe email address - the deliverability-first "resolution" layer of a cold-email
  pipeline. Use when the user wants to find or verify a work email, enrich a list or file
  of domains into decision-maker contacts, or resolve "who is the [title] at [company]
  and what's their email." Works standalone or as Layer 06 in the API-First GTM stack.
  Cost-ordered waterfall: AI Ark → Prospeo → Blitz → Findymail with ZeroBounce
  validation; a rung is skipped when its API key is absent, and it never spends
  enrichment credit without an explicit go-ahead.

Resolution - Email + Person

Turn `{domain (required), optional person_name, optional job_title}` into a **verified, send-safe email**.

The one principle that governs every decision here: **bounce rate, not find rate, is the signal that matters.** A found-but-undeliverable email is worse than no email - it burns sender reputation. So this skill optimizes for *deliverable* contacts at *minimum credit cost*, and it never spends enrichment credit without the user's explicit go-ahead.

`domain` is the one mandatory input across every tool. Everything else can be asked for, inherited from upstream, or derived.

Provider + auth setup

Each provider reads its API key from an **environment variable** - `AIARK_API_KEY`, `PROSPEO_API_KEY`, `BLITZ_API_KEY`, `FINDYMAIL_API_KEY`, `ZEROBOUNCE_API_KEY` - never hardcode a key. This skill calls the providers with curl, and **a `.env` file is not visible to curl** - load it into the shell in the same command as the call, otherwise an empty auth header comes back as a provider auth error rather than a missing-key one:

set -a; [ -f .env ] && . ./.env; set +a

An exported variable or a secrets manager takes precedence and needs no prelude. **The skill runs with as few as one key set:** at startup, detect which keys are present, use only those rungs, and skip the rest (log which rungs were skipped and why). Read **`references/providers.md`** for endpoints, request shapes, billing rules, and rate limits before making any call.

  • **AI Ark** - rung 0, **conditional**: runs only if `AIARK_API_KEY` is set. Two modes. **(a) Passthrough:** a row that already carries an AI Ark-verified email (source flag `ai_ark`/`pre_verified`, or the caller says the list is an AI Ark export) is accepted as-is - don't re-find what's already verified. **(b) Finder:** `POST /people/export/single` turns a **LinkedIn profile URL or AI Ark person id** (not name+domain) into a BounceBan-verified email - 1 credit per valid email, 0 on a miss. Strong on **SMB operators** where Prospeo is weak. The `POST /people` *search* bills separately (~0.5 credit per returned profile), so keep searches tightly filtered and prefer `/people/export/single`.
  • **Prospeo** - title-first finder, strong on mid-market + enterprise. Charged only when a request returns results (misses are free).
  • **Blitz** - domain-first finder, strong on SMB. Free on Blitz's Unlimited plan (verify your own plan before treating it as free). Two steps: `domain-to-linkedin` → `employee-finder` (native `job_level`/`job_function` filters); returns the person but not the email.
  • **Findymail** - email finder by name+domain (`POST /api/search/name` - NOT `/api/find`, which 405s; see `references/providers.md`).
  • **ZeroBounce** - independent email validation (`GET /v2/validate`). If its key isn't set, fall back to the finding provider's bundled verdict. Explicit `catch-all` status (no false "ok" on catch-all domains), and **unknown results consume no credit**.

Shape of a run

Classify the input, dedupe by domain, show the estimation gate, then waterfall, validate, and emit records. The two gates below are the only fixed stops - everything else is judgment.

**Input.** Three shapes arrive: a domain + job title (confirm the title and how many people they want - don't guess the count), a domain + person name (require the full name; several people sharing it → return them all, noted), or a bulk file. Bulk JSONL from an upstream skill (01–04) is the chain standard - inherit its fields and ask only for genuine gaps. CSV/Excel: read the headers, inspect the actual cell data, remap any mislabeled columns and report what you remapped - a mislabeled column wastes credit on garbage, so reason about messy data *before* spending anything. `references/input-handling.md` has the full normalization table.

A missing domain can be derived from an email (everything after `@`) or a URL - flag the record `derived`. A *personal* LinkedIn profile URL (`linkedin.com/in/…`) is itself a person identifier and bypasses the domain requirement (resolve via Blitz email-enrichment or Findymail); a LinkedIn *company* URL is not - extract the domain from it instead.

**Dedupe.** Before anything costly, normalize each domain (lowercase; strip scheme, `www.`, paths, and sub-domains like `careers.acme.com` → `acme.com`), keep one record per domain, and report `N duplicates → M unique`. The waterfall runs once per unique company. Also check prior `runs/` folders for an already-resolved domain/person - never pay twice for the same contact.

Gate 1 - Estimation (mandatory, before any spend)

Run cheap count/preview queries (Prospeo's search returns matches without charging on a miss) and show, before spending any enrichment credit:

1. People found for the requested titles 2. People not found 3. Closest (similar-title) people available for the not-found 4. How many have emails 5. How many have LinkedIn 6. **Credit + $ cost to enrich all** 7. Companies with zero contacts 8. **Coverage %** (found ÷ requested)

Then get an explicit yes before enriching. Never auto-proceed - this gate is what makes the skill safe to point at a 5,000-row list.

Gate 2 - Validation-retry (optional, opt-in)

After enrichment is approved, offer one more opt-in: if a found email

Read more
Ships withheadless-gtm

GTM without the SaaS layer. An outbound pipeline built as agent skills for Claude Code and Codex: describe an ICP in plain English and the chain takes it from company discovery to verified, signal-ranked contacts - every step running on raw vendor APIs, not

Get the whole plugin
Stats
28
Stars
6
Forks
Maintained
Maintenance
Python
Language
MIT
License
1mo ago
Last commit
4mo ago
Created

Repo: Zevenue/headless-gtm

Other skills on headless-gtm.