GTM Enrichment — Smart (Multi-Provider Waterfall)

Multi-provider waterfall lead enrichment.

How to use it

  1. Hit Copy the whole skill.
  2. Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
    ChatGPT: make a Project and paste it into Instructions.
    Neither? Paste it at the top of a new chat — it works for that chat.
  3. Describe your job in plain words. The AI follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit gooseworks-ai/goose-skills/skills/lead-generation/capabilities/gtm-enrichment-smart#main ~/.claude/skills/gtm-enrichment-smart

For one project only, change the path to .claude/skills/gtm-enrichment-smart.

Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Show the full text424 lines
gtm-enrichment-smart/SKILL.md424 lines17.6 KBpushed 38d agoRawView on GitHub

GTM Enrichment — Smart (Multi-Provider Waterfall)

Setup

Choose the available runtime before doing any credential setup:

  • Terminal-free client: skip the shell commands below. Use connected MCP tools. For ScrapeCreators operations, read scrapecreators-api and prefer call_data_provider. If a required enrichment provider has no connected tool, report that part of the waterfall as unavailable rather than fabricating enrichment data.
  • Local terminal: use the GooseWorks credentials and proxy commands below.

Read your credentials from ~/.gooseworks/credentials.json:

export GOOSEWORKS_API_KEY=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json'))['api_key'])")
export GOOSEWORKS_API_BASE=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json')).get('api_base','https://api.gooseworks.ai'))")

If ~/.gooseworks/credentials.json does not exist, tell the user to run: npx gooseworks login

The local proxy endpoints use Bearer auth: -H "Authorization: Bearer $GOOSEWORKS_API_KEY". ScrapeCreators operation descriptions below remain environment-neutral in both runtimes.

Enrich a lead from an email address (+ optional name) using a waterfall strategy: start with cheap APIs ($0.01 each), cross-reference for confidence, then use expensive AI agents only for gaps. Spends proportionally to lead quality.

Cost: $0.04 (best) to ~$0.12 (typical with buying signals) to ~$0.26 (worst, Sixtyfour fallback) Latency: ~5-15s typical, up to 60s if Sixtyfour fallback triggers

Input

Required:

Optional:

  • name — full name if known (improves match rate)

Workflow

Step 0: Extract Domain + Free Email Check

Extract the domain from the email. Check if it's a free email provider.

Free email providers (skip Brand.dev if match): gmail.com, yahoo.com, hotmail.com, outlook.com, aol.com, icloud.com, mail.com, protonmail.com, zoho.com, yandex.com, gmx.com, live.com

Set is_free_email = true/false — this gates whether Brand.dev runs in Phase 1.


PHASE 1 — Core (always run, parallel) — ~$0.03-$0.06

Run ALL of these simultaneously:

1a. Apollo People Match ($0.01):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"apollo","path":"/api/v1/people/match"}'
  "email": "{email}",
  "reveal_personal_emails": true
}'

Extract: person.name, person.title, person.linkedin_url, person.city, person.state, person.country, person.organization.name, person.organization.id (save org_id for Phase 4), person.organization.industry, person.organization.estimated_num_employees, person.organization.keywords, person.organization.funding_events, person.organization.total_funding.

1b. Hunter Combined Enrichment ($0.01):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"hunter","path":"/v2/combined/find","query":{"email":"{email}"}}'

Extract: data.person.first_name, data.person.last_name, data.person.linkedin_handle, data.person.title, data.company.name, data.company.domain, data.company.industry, data.company.description, data.company.headcount, data.company.technologies, data.company.twitter, data.company.category.

1c. Brand.dev Retrieve ($0.03 — CONDITIONAL: only if is_free_email == false):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"brand-dev","path":"/v1/brand/retrieve","query":{"domain":"{domain}"}}'

Extract: title (company name), description, industries (including eic code), socials (twitter URL, github URL, linkedin URL), employeeCount, foundedYear, location.

SKIP this call if is_free_email == true — saves $0.03.

1d. Hunter Email Verifier ($0.01):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"hunter","path":"/v2/email-verifier","query":{"email":"{email}"}}'

Extract: data.status (valid/invalid/accept_all/webmail/disposable/unknown), data.result (deliverable/undeliverable/risky).


PHASE 1 MERGE — Cross-Reference & Confidence

After all Phase 1 calls complete, merge data:

Person merge rules:

  1. Full name: prefer Apollo (structured), cross-ref with Hunter
  2. Title: prefer Apollo, cross-ref with Hunter
  3. LinkedIn URL: prefer Apollo linkedin_url, fallback to Hunter linkedin_handle (prepend https://linkedin.com/in/)
  4. Location: prefer Apollo (structured city/state/country)
  5. If Apollo and Hunter agree on name+title: confidence = "high"
  6. If only one source has data: confidence = "medium"
  7. If they disagree on name or title: flag conflict, keep both, confidence = "low"

Company merge rules:

  1. Name: prefer Apollo org name, cross-ref with Hunter + Brand.dev
  2. LinkedIn URL: prefer Brand.dev socials, fallback Apollo
  3. Description: prefer Brand.dev (richer), fallback Hunter
  4. Employee count: prefer Apollo, cross-ref with Brand.dev + Hunter headcount
  5. Funding: use Apollo funding_events and total_funding
  6. Geo: prefer Apollo org location, cross-ref with Brand.dev
  7. Tech stack: use Hunter technologies
  8. Social URLs: use Brand.dev socials (twitter, github)

AI/B2B Classification (zero extra cost):

Cross-reference three sources from Phase 1:

Source AI Signals B2B Signals
Brand.dev description + industries.eic Parse description for: AI, ML, machine learning, deep learning, neural, LLM, GPT, NLP, computer vision Parse for: SaaS, B2B, enterprise, platform, API, developer tools, infrastructure
Apollo keywords[] + industry Match keywords against AI terms Match keywords against B2B terms
Hunter category + company description Check for AI/ML terms Check for software/SaaS/B2B terms

Confidence rules:

  • high: 2+ sources agree
  • medium: 1 source has signal
  • low: weak inference only (e.g., "tech company" but no explicit AI/B2B terms)

PHASE 2 — Gap-Fill (conditional) — $0.00-$0.02

2a. Apollo Organization Enrich ($0.01 — ONLY if Apollo Phase 1 returned NO funding_events or funding data is empty):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"apollo","path":"/api/v1/organizations/enrich","query":{"domain":"{domain}"}}'

Extract: organization.funding_events[], organization.total_funding, organization.latest_funding_stage, organization.latest_funding_amount, organization.estimated_num_employees, organization.annual_revenue.

2b. Tomba Enrich ($0.01 — ONLY if Apollo and Hunter disagree on person name OR title):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"tomba","path":"/v1/enrich","query":{"email":"{email}"}}'

Use as tie-breaker. If Tomba agrees with Apollo: use Apollo data. If Tomba agrees with Hunter: use Hunter data. If all three disagree: keep Apollo as primary, flag conflict.


PHASE 3 — Sixtyfour Fallback (conditional, expensive) — $0.00-$0.20

3a. Sixtyfour Enrich Lead ($0.10 — ONLY if person NOT found after Phases 1-2, meaning no name AND no title AND no LinkedIn URL from any source):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"sixtyfour","path":"/enrich-lead"}'
  "lead_info": {
    "email": "{email}",
    "domain": "{domain}"
  },
  "struct": {
    "full_name": "Full legal name of this person",
    "title": "Current job title",
    "linkedin_url": "LinkedIn profile URL (full URL)",
    "city": "City",
    "state": "State or region",
    "country": "Country"
  }
}'

3b. Sixtyfour Enrich Company ($0.10 — ONLY if company has major gaps AND org has >500 employees):

Major gaps = missing 2+ of: LinkedIn URL, description, employee count, funding data.

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"sixtyfour","path":"/enrich-company"}'
  "target_company": {
    "domain": "{domain}"
  },
  "struct": {
    "company_name": "Official company name",
    "description": "One-paragraph description",
    "linkedin_url": "LinkedIn company page URL",
    "employee_count": "Number of employees",
    "total_funding_usd": "Total funding raised in USD",
    "latest_funding_date": "Most recent funding round date",
    "latest_funding_stage": "Most recent round stage",
    "latest_funding_amount_usd": "Most recent round amount"
  }
}'

PHASE 4 — Buying Signals (qualified leads only) — $0.00-$0.04

Gate: Only run Phase 4 if the company is:

  • Funded (total_funding > 0) AND
  • Classified as B2B (is_b2b_saas = true) AND
  • Has >50 employees

4a. Brand.dev AI Products ($0.03 — extracts products, pricing tiers, and features from the website):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"brand-dev","path":"/v1/brand/ai/products"}'
  "domain": "{domain}"
}'

From the products response, extract buying signals:

  • has_enterprise_plan: Check if any product has "enterprise" in name, tier, or target_audience
  • has_self_serve: Check if any product has a listed price (self-serve) vs "Contact sales" pricing
  • target_market: Infer from target_audience arrays across products

4b. Apollo Job Postings ($0.01 — ONLY if organization_id was captured from Phase 1):

curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
  -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"api":"apollo","path":"/api/v1/organizations/{organization_id}/job_postings","query":{"organization_id":"{organization_id}"}}'

Search job postings for enterprise sales signals: titles containing "Enterprise", "Account Executive", "Solutions Engineer", "Sales Director", "Customer Success". If found, set hiring_enterprise_reps = true.


PHASE 5 — Cheap/Free Signals — $0.00-$0.01

5a. GitHub Stars (free — ONLY if Brand.dev socials or Apollo data returned a GitHub URL):

# Extract org name from GitHub URL, e.g., https://github.com/ngrok -> ngrok
# Use the GitHub public API (no auth needed for public repos):
curl -s "https://api.github.com/orgs/{org_name}/repos?sort=stars&per_page=5" | jq '[.[] | {name: .name, stars: .stargazers_count}]'

Sum the top repo stars or report the flagship repo star count.

5b. Twitter/X Followers (Scrape Creators — ONLY if a Twitter handle was found in Brand.dev socials or Apollo data):

provider: scrapecreators
method: GET
path: /v1/twitter/profile
query:
  handle: "{twitter_handle}"

Extract: legacy.followers_count, legacy.friends_count, legacy.statuses_count, legacy.description.


FINAL — Compile & Output

Merge all phase results into the output format. Track which phases ran.

Output Format

Present the results as a JSON code block:

{
  "person": {
    "full_name": "string",
    "title": "string",
    "linkedin_url": "string",
    "location": {"city": "string", "state": "string", "country": "string"},
    "email_verified": "deliverable | undeliverable | risky | unknown",
    "confidence": "high | medium | low",
    "source": "apollo | hunter | sixtyfour | tomba | merged"
  },
  "company": {
    "name": "string",
    "domain": "string",
    "linkedin_url": "string",
    "description": "string",
    "geo": {"city": "string", "state": "string", "country": "string"},
    "employee_count": "number | null",
    "founded_year": "number | null",
    "funding": {
      "total_amount": "number | null",
      "total_amount_printed": "string | null",
      "latest_round_date": "string | null",
      "latest_round_stage": "string | null",
      "latest_round_amount": "number | null",
      "rounds": [{"date": "", "type": "", "amount": 0, "investors": ""}],
      "confidence": "high | medium | low"
    },
    "classification": {
      "is_ai": {"value": true, "confidence": "high", "evidence": ["Brand.dev description mentions ML", "Apollo keywords include 'artificial intelligence'"]},
      "is_b2b_saas": {"value": true, "confidence": "high", "evidence": ["Hunter category: software", "Apollo industry: SaaS"]}
    },
    "buying_signals": {
      "has_enterprise_plan": "boolean | null",
      "has_self_serve": "boolean | null",
      "hiring_enterprise_reps": "boolean | null",
      "website_traffic_rank": "number | null",
      "github_stars": "number | null",
      "twitter_followers": "number | null",
      "tech_stack": ["array | null"]
    },
    "confidence": "high | medium | low",
    "source": "apollo | hunter | brand-dev | sixtyfour | merged"
  },
  "meta": {
    "total_cost": "$0.XX",
    "api_calls": [
      {
        "api": "apollo",
        "endpoint": "/api/v1/people/match",
        "status": "success",
        "cost": "$0.01",
        "latency_ms": 1200,
        "fields_returned": ["name", "title", "linkedin_url", "organization"],
        "fields_missing": [],
        "error": null
      }
    ],
    "phases_run": [1, 2, 4, 5],
    "enrichment_timestamp": "ISO datetime"
  }
}

Error Visibility

Track EVERY API call in the meta.api_calls array with this structure:

{
  "api": "string (apollo | hunter | brand-dev | sixtyfour | tomba | scrapecreators | github)",
  "endpoint": "string",
  "status": "success | partial | error | skipped",
  "cost": "$0.XX",
  "latency_ms": 0,
  "fields_returned": [],
  "fields_missing": [],
  "error": "string | null"
}

Rules:

  • If an API call fails, returns empty data, or times out: include it with status='error' and a clear error message. Never silently skip failures.
  • If an API call was skipped due to gating logic (e.g., Brand.dev skipped for free email): include it with status='skipped', cost='$0.00', and reason in error field (e.g., "Skipped: free email provider").
  • If an API call returns partial data: use status='partial', list what was returned and what was missing.

Cost Tracking

Sum all API call costs and report in meta.total_cost:

API Endpoint Cost When
Apollo /api/v1/people/match $0.01 Always (Phase 1)
Hunter /v2/combined/find $0.01 Always (Phase 1)
Brand.dev /v1/brand/retrieve $0.03 Phase 1, skip for free email
Hunter /v2/email-verifier $0.01 Always (Phase 1)
Apollo /api/v1/organizations/enrich $0.01 Phase 2, only if funding missing
Tomba /v1/enrich $0.01 Phase 2, only if person data conflicts
Sixtyfour /enrich-lead $0.10 Phase 3, only if person not found
Sixtyfour /enrich-company $0.10 Phase 3, only if major gaps + >500 employees
Brand.dev /v1/brand/ai/products $0.03 Phase 4, only if funded + B2B + >50 employees
Apollo /organizations/{id}/job_postings $0.01 Phase 4, only if org_id available
Scrape Creators /v1/twitter/profile ~$0.01 Phase 5, only if Twitter handle found
GitHub API public $0.00 Phase 5, only if GitHub URL found

Example

Input: [email protected]

Expected flow:

  1. Domain: acme.com, is_free_email = false
  2. Phase 1 (parallel): Apollo people/match, Hunter combined, Brand.dev retrieve, Hunter email-verifier
  3. Phase 1 merge: Cross-reference person data, classify AI/B2B from descriptions+keywords
  4. Phase 2: Check if Apollo returned funding — if not, call Apollo org enrich. Check if person data conflicts — if so, call Tomba.
  5. Phase 3: Skip if person found and company data sufficient
  6. Phase 4: If company is funded + B2B + >50 employees, run Brand.dev AI products + Apollo job postings
  7. Phase 5: If GitHub URL found, grab star counts. If Twitter handle found, grab follower count via Scrape Creators
  8. Compile and output JSON

Tips

  • Phase 1 calls should all fire simultaneously — they're independent
  • Apollo's people/match is the single best-value call — it returns person AND embedded company data including funding events
  • Brand.dev is the richest source for company description, industry classification, and social URLs — but costs 3x more than Apollo/Hunter, so skip it for free email providers
  • The AI/B2B classification uses data already returned by Phase 1 — no extra API calls needed
  • Hunter's technologies array is the only source of tech stack data — valuable for technical buyers
  • Phase 3 (Sixtyfour) should be rare — Apollo + Hunter find most people. Only trigger for truly obscure leads
  • Phase 4 buying signals are the most actionable data for GTM — but gate them to avoid wasting $0.04 on unqualified leads
  • GitHub stars and Twitter followers are cheap/free social proof signals — always grab them if URLs/handles are available
1---
2name: gtm-enrichment-smart
3description: Multi-provider waterfall lead enrichment. Takes an email (+ optional name) and returns person + company data by cross-referencing cheap APIs first, using expensive AI agents only as fallback. Cost-efficient (~$0.04-$0.10/lead) with confidence scoring and full error visibility.
4source: orthogonal
5---
6 
7 
8# GTM Enrichment — Smart (Multi-Provider Waterfall)
9 
10## Setup
11 
12Choose the available runtime before doing any credential setup:
13 
14- **Terminal-free client:** skip the shell commands below. Use connected MCP tools. For ScrapeCreators operations, read `scrapecreators-api` and prefer `call_data_provider`. If a required enrichment provider has no connected tool, report that part of the waterfall as unavailable rather than fabricating enrichment data.
15- **Local terminal:** use the GooseWorks credentials and proxy commands below.
16 
17Read your credentials from ~/.gooseworks/credentials.json:
18```bash
19export GOOSEWORKS_API_KEY=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json'))['api_key'])")
20export GOOSEWORKS_API_BASE=$(python3 -c "import json;print(json.load(open('$HOME/.gooseworks/credentials.json')).get('api_base','https://api.gooseworks.ai'))")
21```
22 
23If ~/.gooseworks/credentials.json does not exist, tell the user to run: `npx gooseworks login`
24 
25The local proxy endpoints use Bearer auth: `-H "Authorization: Bearer $GOOSEWORKS_API_KEY"`. ScrapeCreators operation descriptions below remain environment-neutral in both runtimes.
26 
27 
28Enrich a lead from an email address (+ optional name) using a waterfall strategy: start with cheap APIs ($0.01 each), cross-reference for confidence, then use expensive AI agents only for gaps. Spends proportionally to lead quality.
29 
30**Cost**: $0.04 (best) to ~$0.12 (typical with buying signals) to ~$0.26 (worst, Sixtyfour fallback)
31**Latency**: ~5-15s typical, up to 60s if Sixtyfour fallback triggers
32 
33## Input
34 
35Required:
36- **email** — the lead's email address (e.g., `[email protected]`)
37 
38Optional:
39- **name** — full name if known (improves match rate)
40 
41## Workflow
42 
43### Step 0: Extract Domain + Free Email Check
44 
45Extract the domain from the email. Check if it's a free email provider.
46 
47**Free email providers** (skip Brand.dev if match): `gmail.com`, `yahoo.com`, `hotmail.com`, `outlook.com`, `aol.com`, `icloud.com`, `mail.com`, `protonmail.com`, `zoho.com`, `yandex.com`, `gmx.com`, `live.com`
48 
49Set `is_free_email = true/false` — this gates whether Brand.dev runs in Phase 1.
50 
51---
52 
53### PHASE 1 — Core (always run, parallel) — ~$0.03-$0.06
54 
55Run ALL of these simultaneously:
56 
57**1a. Apollo People Match** ($0.01):
58 
59```bash
60curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
61 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
62 -H "Content-Type: application/json" \
63 -d '{"api":"apollo","path":"/api/v1/people/match"}'
64 "email": "{email}",
65 "reveal_personal_emails": true
66}'
67```
68 
69Extract: `person.name`, `person.title`, `person.linkedin_url`, `person.city`, `person.state`, `person.country`, `person.organization.name`, `person.organization.id` (save org_id for Phase 4), `person.organization.industry`, `person.organization.estimated_num_employees`, `person.organization.keywords`, `person.organization.funding_events`, `person.organization.total_funding`.
70 
71**1b. Hunter Combined Enrichment** ($0.01):
72 
73```bash
74curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
75 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
76 -H "Content-Type: application/json" \
77 -d '{"api":"hunter","path":"/v2/combined/find","query":{"email":"{email}"}}'
78```
79 
80Extract: `data.person.first_name`, `data.person.last_name`, `data.person.linkedin_handle`, `data.person.title`, `data.company.name`, `data.company.domain`, `data.company.industry`, `data.company.description`, `data.company.headcount`, `data.company.technologies`, `data.company.twitter`, `data.company.category`.
81 
82**1c. Brand.dev Retrieve** ($0.03 — CONDITIONAL: only if `is_free_email == false`):
83 
84```bash
85curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
86 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
87 -H "Content-Type: application/json" \
88 -d '{"api":"brand-dev","path":"/v1/brand/retrieve","query":{"domain":"{domain}"}}'
89```
90 
91Extract: `title` (company name), `description`, `industries` (including `eic` code), `socials` (twitter URL, github URL, linkedin URL), `employeeCount`, `foundedYear`, `location`.
92 
93**SKIP this call if `is_free_email == true`** — saves $0.03.
94 
95**1d. Hunter Email Verifier** ($0.01):
96 
97```bash
98curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
99 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
100 -H "Content-Type: application/json" \
101 -d '{"api":"hunter","path":"/v2/email-verifier","query":{"email":"{email}"}}'
102```
103 
104Extract: `data.status` (valid/invalid/accept_all/webmail/disposable/unknown), `data.result` (deliverable/undeliverable/risky).
105 
106---
107 
108### PHASE 1 MERGE — Cross-Reference & Confidence
109 
110After all Phase 1 calls complete, merge data:
111 
112**Person merge rules:**
1131. Full name: prefer Apollo (structured), cross-ref with Hunter
1142. Title: prefer Apollo, cross-ref with Hunter
1153. LinkedIn URL: prefer Apollo `linkedin_url`, fallback to Hunter `linkedin_handle` (prepend `https://linkedin.com/in/`)
1164. Location: prefer Apollo (structured city/state/country)
1175. If Apollo and Hunter **agree** on name+title: `confidence = "high"`
1186. If only one source has data: `confidence = "medium"`
1197. If they **disagree** on name or title: flag conflict, keep both, `confidence = "low"`
120 
121**Company merge rules:**
1221. Name: prefer Apollo org name, cross-ref with Hunter + Brand.dev
1232. LinkedIn URL: prefer Brand.dev socials, fallback Apollo
1243. Description: prefer Brand.dev (richer), fallback Hunter
1254. Employee count: prefer Apollo, cross-ref with Brand.dev + Hunter headcount
1265. Funding: use Apollo `funding_events` and `total_funding`
1276. Geo: prefer Apollo org location, cross-ref with Brand.dev
1287. Tech stack: use Hunter `technologies`
1298. Social URLs: use Brand.dev `socials` (twitter, github)
130 
131**AI/B2B Classification (zero extra cost):**
132 
133Cross-reference three sources from Phase 1:
134 
135| Source | AI Signals | B2B Signals |
136|--------|-----------|-------------|
137| Brand.dev `description` + `industries.eic` | Parse description for: AI, ML, machine learning, deep learning, neural, LLM, GPT, NLP, computer vision | Parse for: SaaS, B2B, enterprise, platform, API, developer tools, infrastructure |
138| Apollo `keywords[]` + `industry` | Match keywords against AI terms | Match keywords against B2B terms |
139| Hunter `category` + company description | Check for AI/ML terms | Check for software/SaaS/B2B terms |
140 
141Confidence rules:
142- `high`: 2+ sources agree
143- `medium`: 1 source has signal
144- `low`: weak inference only (e.g., "tech company" but no explicit AI/B2B terms)
145 
146---
147 
148### PHASE 2 — Gap-Fill (conditional) — $0.00-$0.02
149 
150**2a. Apollo Organization Enrich** ($0.01 — ONLY if Apollo Phase 1 returned NO `funding_events` or funding data is empty):
151 
152```bash
153curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
154 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
155 -H "Content-Type: application/json" \
156 -d '{"api":"apollo","path":"/api/v1/organizations/enrich","query":{"domain":"{domain}"}}'
157```
158 
159Extract: `organization.funding_events[]`, `organization.total_funding`, `organization.latest_funding_stage`, `organization.latest_funding_amount`, `organization.estimated_num_employees`, `organization.annual_revenue`.
160 
161**2b. Tomba Enrich** ($0.01 — ONLY if Apollo and Hunter **disagree** on person name OR title):
162 
163```bash
164curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
165 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
166 -H "Content-Type: application/json" \
167 -d '{"api":"tomba","path":"/v1/enrich","query":{"email":"{email}"}}'
168```
169 
170Use as tie-breaker. If Tomba agrees with Apollo: use Apollo data. If Tomba agrees with Hunter: use Hunter data. If all three disagree: keep Apollo as primary, flag conflict.
171 
172---
173 
174### PHASE 3 — Sixtyfour Fallback (conditional, expensive) — $0.00-$0.20
175 
176**3a. Sixtyfour Enrich Lead** ($0.10 — ONLY if person NOT found after Phases 1-2, meaning no name AND no title AND no LinkedIn URL from any source):
177 
178```bash
179curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
180 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
181 -H "Content-Type: application/json" \
182 -d '{"api":"sixtyfour","path":"/enrich-lead"}'
183 "lead_info": {
184 "email": "{email}",
185 "domain": "{domain}"
186 },
187 "struct": {
188 "full_name": "Full legal name of this person",
189 "title": "Current job title",
190 "linkedin_url": "LinkedIn profile URL (full URL)",
191 "city": "City",
192 "state": "State or region",
193 "country": "Country"
194 }
195}'
196```
197 
198**3b. Sixtyfour Enrich Company** ($0.10 — ONLY if company has major gaps AND org has >500 employees):
199 
200Major gaps = missing 2+ of: LinkedIn URL, description, employee count, funding data.
201 
202```bash
203curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
204 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
205 -H "Content-Type: application/json" \
206 -d '{"api":"sixtyfour","path":"/enrich-company"}'
207 "target_company": {
208 "domain": "{domain}"
209 },
210 "struct": {
211 "company_name": "Official company name",
212 "description": "One-paragraph description",
213 "linkedin_url": "LinkedIn company page URL",
214 "employee_count": "Number of employees",
215 "total_funding_usd": "Total funding raised in USD",
216 "latest_funding_date": "Most recent funding round date",
217 "latest_funding_stage": "Most recent round stage",
218 "latest_funding_amount_usd": "Most recent round amount"
219 }
220}'
221```
222 
223---
224 
225### PHASE 4 — Buying Signals (qualified leads only) — $0.00-$0.04
226 
227**Gate**: Only run Phase 4 if the company is:
228- Funded (total_funding > 0) AND
229- Classified as B2B (is_b2b_saas = true) AND
230- Has >50 employees
231 
232**4a. Brand.dev AI Products** ($0.03 — extracts products, pricing tiers, and features from the website):
233 
234```bash
235curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
236 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
237 -H "Content-Type: application/json" \
238 -d '{"api":"brand-dev","path":"/v1/brand/ai/products"}'
239 "domain": "{domain}"
240}'
241```
242 
243From the products response, extract buying signals:
244- **has_enterprise_plan**: Check if any product has "enterprise" in name, tier, or target_audience
245- **has_self_serve**: Check if any product has a listed price (self-serve) vs "Contact sales" pricing
246- **target_market**: Infer from `target_audience` arrays across products
247 
248**4b. Apollo Job Postings** ($0.01 — ONLY if `organization_id` was captured from Phase 1):
249 
250```bash
251curl -s -X POST $GOOSEWORKS_API_BASE/v1/proxy/orthogonal/run \
252 -H "Authorization: Bearer $GOOSEWORKS_API_KEY" \
253 -H "Content-Type: application/json" \
254 -d '{"api":"apollo","path":"/api/v1/organizations/{organization_id}/job_postings","query":{"organization_id":"{organization_id}"}}'
255```
256 
257Search job postings for enterprise sales signals: titles containing "Enterprise", "Account Executive", "Solutions Engineer", "Sales Director", "Customer Success". If found, set `hiring_enterprise_reps = true`.
258 
259---
260 
261### PHASE 5 — Cheap/Free Signals — $0.00-$0.01
262 
263**5a. GitHub Stars** (free — ONLY if Brand.dev socials or Apollo data returned a GitHub URL):
264 
265```bash
266# Extract org name from GitHub URL, e.g., https://github.com/ngrok -> ngrok
267# Use the GitHub public API (no auth needed for public repos):
268curl -s "https://api.github.com/orgs/{org_name}/repos?sort=stars&per_page=5" | jq '[.[] | {name: .name, stars: .stargazers_count}]'
269```
270 
271Sum the top repo stars or report the flagship repo star count.
272 
273**5b. Twitter/X Followers** (Scrape Creators — ONLY if a Twitter handle was found in Brand.dev socials or Apollo data):
274 
275```yaml
276provider: scrapecreators
277method: GET
278path: /v1/twitter/profile
279query:
280 handle: "{twitter_handle}"
281```
282 
283Extract: `legacy.followers_count`, `legacy.friends_count`, `legacy.statuses_count`, `legacy.description`.
284 
285---
286 
287### FINAL — Compile & Output
288 
289Merge all phase results into the output format. Track which phases ran.
290 
291## Output Format
292 
293Present the results as a JSON code block:
294 
295```json
296{
297 "person": {
298 "full_name": "string",
299 "title": "string",
300 "linkedin_url": "string",
301 "location": {"city": "string", "state": "string", "country": "string"},
302 "email_verified": "deliverable | undeliverable | risky | unknown",
303 "confidence": "high | medium | low",
304 "source": "apollo | hunter | sixtyfour | tomba | merged"
305 },
306 "company": {
307 "name": "string",
308 "domain": "string",
309 "linkedin_url": "string",
310 "description": "string",
311 "geo": {"city": "string", "state": "string", "country": "string"},
312 "employee_count": "number | null",
313 "founded_year": "number | null",
314 "funding": {
315 "total_amount": "number | null",
316 "total_amount_printed": "string | null",
317 "latest_round_date": "string | null",
318 "latest_round_stage": "string | null",
319 "latest_round_amount": "number | null",
320 "rounds": [{"date": "", "type": "", "amount": 0, "investors": ""}],
321 "confidence": "high | medium | low"
322 },
323 "classification": {
324 "is_ai": {"value": true, "confidence": "high", "evidence": ["Brand.dev description mentions ML", "Apollo keywords include 'artificial intelligence'"]},
325 "is_b2b_saas": {"value": true, "confidence": "high", "evidence": ["Hunter category: software", "Apollo industry: SaaS"]}
326 },
327 "buying_signals": {
328 "has_enterprise_plan": "boolean | null",
329 "has_self_serve": "boolean | null",
330 "hiring_enterprise_reps": "boolean | null",
331 "website_traffic_rank": "number | null",
332 "github_stars": "number | null",
333 "twitter_followers": "number | null",
334 "tech_stack": ["array | null"]
335 },
336 "confidence": "high | medium | low",
337 "source": "apollo | hunter | brand-dev | sixtyfour | merged"
338 },
339 "meta": {
340 "total_cost": "$0.XX",
341 "api_calls": [
342 {
343 "api": "apollo",
344 "endpoint": "/api/v1/people/match",
345 "status": "success",
346 "cost": "$0.01",
347 "latency_ms": 1200,
348 "fields_returned": ["name", "title", "linkedin_url", "organization"],
349 "fields_missing": [],
350 "error": null
351 }
352 ],
353 "phases_run": [1, 2, 4, 5],
354 "enrichment_timestamp": "ISO datetime"
355 }
356}
357```
358 
359## Error Visibility
360 
361Track EVERY API call in the `meta.api_calls` array with this structure:
362 
363```json
364{
365 "api": "string (apollo | hunter | brand-dev | sixtyfour | tomba | scrapecreators | github)",
366 "endpoint": "string",
367 "status": "success | partial | error | skipped",
368 "cost": "$0.XX",
369 "latency_ms": 0,
370 "fields_returned": [],
371 "fields_missing": [],
372 "error": "string | null"
373}
374```
375 
376Rules:
377- **If an API call fails, returns empty data, or times out**: include it with `status='error'` and a clear error message. Never silently skip failures.
378- **If an API call was skipped due to gating logic** (e.g., Brand.dev skipped for free email): include it with `status='skipped'`, `cost='$0.00'`, and reason in error field (e.g., "Skipped: free email provider").
379- **If an API call returns partial data**: use `status='partial'`, list what was returned and what was missing.
380 
381## Cost Tracking
382 
383Sum all API call costs and report in `meta.total_cost`:
384 
385| API | Endpoint | Cost | When |
386|-----|----------|------|------|
387| Apollo | /api/v1/people/match | $0.01 | Always (Phase 1) |
388| Hunter | /v2/combined/find | $0.01 | Always (Phase 1) |
389| Brand.dev | /v1/brand/retrieve | $0.03 | Phase 1, skip for free email |
390| Hunter | /v2/email-verifier | $0.01 | Always (Phase 1) |
391| Apollo | /api/v1/organizations/enrich | $0.01 | Phase 2, only if funding missing |
392| Tomba | /v1/enrich | $0.01 | Phase 2, only if person data conflicts |
393| Sixtyfour | /enrich-lead | $0.10 | Phase 3, only if person not found |
394| Sixtyfour | /enrich-company | $0.10 | Phase 3, only if major gaps + >500 employees |
395| Brand.dev | /v1/brand/ai/products | $0.03 | Phase 4, only if funded + B2B + >50 employees |
396| Apollo | /organizations/{id}/job_postings | $0.01 | Phase 4, only if org_id available |
397| Scrape Creators | /v1/twitter/profile | ~$0.01 | Phase 5, only if Twitter handle found |
398| GitHub API | public | $0.00 | Phase 5, only if GitHub URL found |
399 
400## Example
401 
402**Input**: `[email protected]`
403 
404**Expected flow**:
4051. Domain: `acme.com`, `is_free_email = false`
4062. **Phase 1** (parallel): Apollo people/match, Hunter combined, Brand.dev retrieve, Hunter email-verifier
4073. **Phase 1 merge**: Cross-reference person data, classify AI/B2B from descriptions+keywords
4084. **Phase 2**: Check if Apollo returned funding — if not, call Apollo org enrich. Check if person data conflicts — if so, call Tomba.
4095. **Phase 3**: Skip if person found and company data sufficient
4106. **Phase 4**: If company is funded + B2B + >50 employees, run Brand.dev AI products + Apollo job postings
4117. **Phase 5**: If GitHub URL found, grab star counts. If Twitter handle found, grab follower count via Scrape Creators
4128. Compile and output JSON
413 
414## Tips
415 
416- Phase 1 calls should all fire simultaneously — they're independent
417- Apollo's people/match is the single best-value call — it returns person AND embedded company data including funding events
418- Brand.dev is the richest source for company description, industry classification, and social URLs — but costs 3x more than Apollo/Hunter, so skip it for free email providers
419- The AI/B2B classification uses data already returned by Phase 1 — no extra API calls needed
420- Hunter's `technologies` array is the only source of tech stack data — valuable for technical buyers
421- Phase 3 (Sixtyfour) should be rare — Apollo + Hunter find most people. Only trigger for truly obscure leads
422- Phase 4 buying signals are the most actionable data for GTM — but gate them to avoid wasting $0.04 on unqualified leads
423- GitHub stars and Twitter followers are cheap/free social proof signals — always grab them if URLs/handles are available
424 

Discussion

Alternatives

Also in Company & contact data