skills/orthogonal-gtm-enrichment-smart/SKILL.md
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.
npx skillsauth add orthogonal-sh/skills gtm-enrichment-smartInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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
Required:
[email protected])Optional:
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.
Run ALL of these simultaneously:
1a. Apollo People Match ($0.01):
orth run apollo /api/v1/people/match --body '{
"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):
orth run hunter /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):
orth run brand-dev /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):
orth run hunter /v2/email-verifier --query 'email={email}'
Extract: data.status (valid/invalid/accept_all/webmail/disposable/unknown), data.result (deliverable/undeliverable/risky).
After all Phase 1 calls complete, merge data:
Person merge rules:
linkedin_url, fallback to Hunter linkedin_handle (prepend https://linkedin.com/in/)confidence = "high"confidence = "medium"confidence = "low"Company merge rules:
funding_events and total_fundingtechnologiessocials (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 agreemedium: 1 source has signallow: weak inference only (e.g., "tech company" but no explicit AI/B2B terms)2a. Apollo Organization Enrich ($0.01 — ONLY if Apollo Phase 1 returned NO funding_events or funding data is empty):
orth run apollo /api/v1/organizations/enrich -q '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):
orth run tomba /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.
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):
orth run sixtyfour /enrich-lead --body '{
"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.
orth run sixtyfour /enrich-company --body '{
"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"
}
}'
Gate: Only run Phase 4 if the company is:
4a. Brand.dev AI Products ($0.03 — extracts products, pricing tiers, and features from the website):
orth run brand-dev /v1/brand/ai/products --body '{
"domain": "{domain}"
}'
From the products response, extract buying signals:
target_audience arrays across products4b. Apollo Job Postings ($0.01 — ONLY if organization_id was captured from Phase 1):
orth run apollo /api/v1/organizations/{organization_id}/job_postings -q '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.
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):
orth run scrapecreators /v1/twitter/profile -q 'handle={twitter_handle}'
Extract: legacy.followers_count, legacy.friends_count, legacy.statuses_count, legacy.description.
Merge all phase results into the output format. Track which phases ran.
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"
}
}
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:
status='error' and a clear error message. Never silently skip failures.status='skipped', cost='$0.00', and reason in error field (e.g., "Skipped: free email provider").status='partial', list what was returned and what was missing.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 |
Input: [email protected]
Expected flow:
acme.com, is_free_email = falsetechnologies array is the only source of tech stack data — valuable for technical buyerstesting
Download videos from YouTube, Bilibili, Twitter, and thousands of other sites using yt-dlp. Use when the user provides a video URL and wants to download it, extract audio (MP3), download subtitles, or select video quality. Triggers on phrases like "下载视频", "download video", "yt-dlp", "YouTube", "B站", "抖音", "提取音频", "extract audio".
business
Send messages and manage Slack channels. Use when asked to send Slack messages, post to channels, list channels, or fetch message history.
development
Evaluate YC batch companies for investment — scrapes the YC directory, researches each company and its founders (work history, LinkedIn, website), assesses founder-company fit, and exports to Google Sheets with priority rankings. Use when asked to evaluate YC companies, research a YC batch, screen startups, or do due diligence on YC companies.
development
Take screenshots of websites and web pages