Apollo + Hunter Integration Hub
This is a merged hub covering two B2B contact enrichment vendors used in a cascade pattern: Apollo.io (organization-level enrichment, free tier) → Hunter.io (email finder fallback, 50-credit/month free tier). The cascade is implemented in il-marketplace-pull/scripts/enrich-contacts.js, which enriches InvestorLift wholesaler company records and writes results to the wholesaler_contacts table in Supabase (CCP project). Read this hub before modifying the enrichment pipeline, rotating API keys, or spending Hunter credits.
⚠️ SOURCE MISSING
Both KB directories are stub-only:
workspace/knowledge-base/apollo-io/— contains only_auditfile; no API.md, WEBHOOKS.md, or CREDENTIALS.mdworkspace/knowledge-base/hunter-io/— contains only_auditfile; no API.md or CREDENTIALS.md
This hub is authored entirely from ~/.claude/skills/il-marketplace-pull/SKILL.md and the enrich-contacts.js script. Field names, rate limits, and endpoint paths are derived from the skill + script inspection, not from authoritative KB docs. Any deep API work should verify against live vendor docs at https://apolloio.github.io/apollo-api-docs/ and https://hunter.io/api-documentation/.
Apollo.io
Quick reference
| Field | Value |
|---|---|
| Vendor | Apollo.io |
| URL | https://app.apollo.io |
| API Docs | https://apolloio.github.io/apollo-api-docs/ |
| KB doc | SOURCE MISSING — workspace/knowledge-base/apollo-io/ is _audit stub only |
| Auth method | API key (Bearer or api_key param) |
| Auth credential | op://Aurora/apollo/api-key |
| Cred-proxy port | pending (B1-B6 ratification per nemoclaw-audit-2026-05-03) |
| Webhook port | n/a (outbound calls only) |
| Outbound API base | https://api.apollo.io/v1 |
| Rate limits | Free tier: ~50 org enrichments / day (NEEDS VERIFICATION — no KB doc) |
| Rate-limit action | 429 → skip account, log warning, continue to next; Discord ops if sustained |
| Cost | Free tier available; paid plans for higher volumes (NEEDS VERIFICATION) |
| Backup/recovery | Vendor-owned; no local backup of raw Apollo responses |
| Status | production (free tier) |
Organization enrichment endpoint
Used by enrich-contacts.js to find wholesaler company domain and LinkedIn URL:
POST /v1/organizations/enrich
Body: { "domain": "<company-domain>" }
OR
{ "name": "<company-name>" }
Response keys used (NEEDS VERIFICATION against live response):
organization.website_url → company domain
organization.linkedin_url → company LinkedIn
organization.name → canonical company name
Fallback when Apollo returns nothing: enrich-contacts.js falls back to a heuristic domain: lowercase(company_name).replace(/\s+/g, '') + ".com". This is used only when Apollo has no record (small wholesalers not indexed).
Free tier constraint
Apollo’s free tier indexes primarily mid-market and enterprise companies. Small regional wholesalers (common in IL) may have no Apollo record. The cascade is designed for this: Apollo miss → Hunter email-finder with heuristic domain.
Hunter.io
Quick reference
| Field | Value |
|---|---|
| Vendor | Hunter.io |
| URL | https://hunter.io |
| API Docs | https://hunter.io/api-documentation |
| KB doc | SOURCE MISSING — workspace/knowledge-base/hunter-io/ is _audit stub only |
| Auth method | API key (api_key query param) |
| Auth credential | op://Aurora/hunter/api-key |
| Cred-proxy port | pending |
| Webhook port | n/a (outbound calls only) |
| Outbound API base | https://api.hunter.io/v2 |
| Rate limits | Free tier: 50 credits/month — 1 credit per successful email-finder match |
| Rate-limit action | 429 → stop enrichment for current run; log remaining budget; do NOT exceed monthly cap |
| Cost | Free: 50 credits/month; Starter: 500 credits (99/mo) |
| Backup/recovery | Vendor-owned |
| Status | production (free tier) |
Email-finder endpoint
Used by enrich-contacts.js as the fallback step when Apollo provides a domain but no verified email:
GET /v2/email-finder
Params:
domain=<company-domain> (from Apollo enrichment or heuristic)
first_name=<contact-first> (if available from IL account data)
last_name=<contact-last> (if available)
api_key=<from op://Aurora/hunter/api-key>
Response keys used (NEEDS VERIFICATION against live response):
data.email → dispositions manager email address
data.score → confidence score (0-100)
data.sources[] → provenance of email
Credit budget enforcement
The enrich-contacts.js --budget=<N> flag limits Hunter calls per run. Default budget: 50 (matches monthly free tier cap). Do NOT run enrichment without --budget — unrestricted runs can exhaust the month’s credits in a single pass on a large account list.
# Safe: respects monthly budget
node ~/.claude/skills/il-marketplace-pull/scripts/enrich-contacts.js --top=50 --budget=50
# Dangerous: no budget cap — do NOT run without explicit authorization
node ~/.claude/skills/il-marketplace-pull/scripts/enrich-contacts.js --top=200Cascade flow
The cascade implements a priority ordering that maximizes enrichment quality while respecting Hunter’s 50-credit/month free tier ceiling.
For each unique account_id in acquisition_deals:
│
├─ Step 1: Apollo /v1/organizations/enrich
│ Input: company_name from IL account data
│ Output: domain, linkedin_url, canonical_name
│ Cost: FREE (Apollo free tier, ~50 orgs/day limit)
│ On hit: write domain + linkedin → wholesaler_contacts; continue to Step 2
│ On miss: heuristic domain (lowercase company.com); continue to Step 2
│
├─ Step 2: Hunter /v2/email-finder
│ Input: domain (from Apollo or heuristic) + name fields if available
│ Output: dispositions manager email + confidence score
│ Cost: 1 Hunter credit per match
│ Budget: --budget flag (default 50 = monthly free tier ceiling)
│ On hit: write email + score → wholesaler_contacts
│ On miss: leave email NULL in wholesaler_contacts
│ On 429: stop run; log remaining budget; alert Discord #ops
│
└─ Step 3: Write to wholesaler_contacts (Supabase CCP svueekfvfrvhylxygktb)
Table: wholesaler_contacts
Key: account_id (upsert — safe to re-run)
Fields: account_id, company_name, domain, linkedin_url, email,
email_score, enriched_at, source (apollo | hunter | heuristic)
When to run
Recommended cadence: after each batch of new IL deals synced (post investorlift-daily-sync.sh), targeting only accounts not yet enriched (WHERE email IS NULL). Use --dry-run to audit before spending Hunter credits.
# Dry-run first
node ~/.claude/skills/il-marketplace-pull/scripts/enrich-contacts.js \
--top=50 --budget=50 --dry-run
# Live run after dry-run looks clean
node ~/.claude/skills/il-marketplace-pull/scripts/enrich-contacts.js \
--top=50 --budget=50Components
~/.claude/skills/il-marketplace-pull/scripts/enrich-contacts.js— cascade orchestrator (Apollo + Hunter)~/.claude/skills/il-marketplace-pull/scripts/account-rollup.js— analytics: top wholesalers by deal volume (read-only; no API calls)~/.claude/skills/il-marketplace-pull/SKILL.md— full skill spec including failure modes + triggersworkspace/knowledge-base/apollo-io/_audit— vendor audit stub (SOURCE MISSING: no API.md)workspace/knowledge-base/hunter-io/_audit— vendor audit stub (SOURCE MISSING: no API.md)
How it’s used
- Trigger: User says “enrich IL wholesaler contacts” / “find IL wholesaler emails” / “top IL wholesalers” — routes to
/il-marketplace-pullskill - Workflow:
enrich-contacts.jsqueriesacquisition_dealsfor unique account_ids → Apollo → Hunter → upsertwholesaler_contacts→ optional HubSpot contact create via hubspot-deal-ingest - Agents involved: _summary (consumes enriched contacts for outreach), _summary (data ops)
- Failure mode 1: Hunter 429 — budget exhausted. Recovery: wait until next month’s credit reset; run with smaller
--budgetnext time - Failure mode 2: Apollo returns nothing for small wholesalers — cascade continues with heuristic domain. Expected behavior, not an error.
- Failure mode 3:
wholesaler_contactstable missing — apply schema migration (HANDOFF-FOR-KIMI Phase 0). Error:relation "wholesaler_contacts" does not exist - Success criteria:
wholesaler_contactsrows upserted with non-NULLemailfields;email_score >= 70for high-confidence matches; Hunter credits remaining > 0.
Cross-links
Agents that touch this
- _summary — primary consumer; uses enriched emails for wholesaler outreach
- _summary — data ops; runs enrichment cron and monitors Hunter credit budget
Skills that invoke this
- il-marketplace-pull — direct owner; enrich-contacts.js is a skill script
- acquisitions-outreach — downstream consumer of enriched wholesaler contacts
Plans that govern this
- openclaw-self-improvement-layer-2026-05-03 — OSIL B13: IL AI replication track
- osil-il-ai-replication-2026-05-03 — B13 displacement track (replicate IL AI using HubSpot + InvestorBase + enriched contacts)
- project_acquisition_deals_centralized_schema.md —
wholesaler_contactsschema decision (renamed fromdata_il_marketplace_contacts)
Feedback rules
- feedback_credentials_via_1password_cli — Apollo + Hunter key rotation pattern via
opCLI - feedback_no_plaintext_creds — G-NO-PLAINTEXT-CREDS; both API keys MUST be in 1Password Aurora vault
- feedback_il_enrichment_runs_on_mac_ultra — upstream: IL scraping on Mac; enrichment runs on VPS
- feedback_il_contact_precedence_rule — IL contact precedence when multiple enrichment sources conflict
- reference_il_marketplace_pipeline — full IL pipeline reference; Apollo+Hunter is the enrichment layer
KB / source docs
- SOURCE MISSING:
workspace/knowledge-base/apollo-io/API.md— only_auditstub exists. Apollo API: https://apolloio.github.io/apollo-api-docs/ - SOURCE MISSING:
workspace/knowledge-base/hunter-io/API.md— only_auditstub exists. Hunter API: https://hunter.io/api-documentation - investorlift — upstream data source;
acquisition_dealstable feeds enrich-contacts.js - supabase —
wholesaler_contactstable (CCP projectsvueekfvfrvhylxygktb)
System maps
- agents-tier-structure — Acquisitions agent tier (consumer of enriched data)
- integrations — external integrations topology showing Apollo+Hunter as enrichment layer
Related: Credential layer cluster
1password is the cluster anchor:
- 1password —
op://Aurora/apollo/api-key+op://Aurora/hunter/api-key. Both keys live in 1Password vault Aurora. Access viaopCLI:op read "op://Aurora/apollo/api-key". See reference_1password_op_access foropCLI auth pattern viaOP_SERVICE_ACCOUNT_TOKEN. - All integration hubs that consume API keys are cluster members under the 1password anchor.
Related: Real-estate data platform cluster
Apollo+Hunter feeds enriched contact data back into the real-estate pipeline:
- investorlift — caller: provides
account_id+ company names that drive Apollo queries - supabase — destination:
wholesaler_contactstable (CCPsvueekfvfrvhylxygktb) - hubspot — downstream: enriched emails used to find/create HubSpot contacts in the acquisition pipeline
Open issues / TODOs
- G-KB-SYNC-WITH-CLAUDEMD gap: Neither
apollo-ionorhunter-iohas a proper KB directory. Both are_auditstubs. CreateAPI.mdfiles + update CLAUDE.md platforms list. - Hunter credit monitoring: No automated check on remaining Hunter credits before enrichment runs. Risk: silent exhaustion. Wire a pre-run credit check (
GET /v2/account→data.requests.searches.used) and abort if budget < 5. - Apollo rate limit not confirmed: Free tier daily org-enrichment limit is NEEDS VERIFICATION. Run a test batch and monitor for 429s.
- wholesaler_contacts schema migration: Confirm migration applied in CCP (table renamed from
data_il_marketplace_contacts). RunSELECT table_name FROM information_schema.tables WHERE table_name = 'wholesaler_contacts'against CCP to verify. - Heuristic domain quality: Apollo-miss →
company_name.toLowerCase().replace(/\s+/, '') + ".com"heuristic is low-quality for company names with punctuation or abbreviations. NEEDS VERIFICATION that Hunter accepts these without burning credits on zero-confidence results. - Credit tier upgrade: At IL enrichment scale (thousands of accounts), 50 free credits/month is a ceiling. Evaluate Hunter Starter ($49/mo, 500 credits) when enrichment volume warrants.
Recent activity
- 2026-05-03: hub created (W2-S8 sub-agent); SOURCE MISSING flagged for both KB dirs; cascade flow documented from SKILL.md + enrich-contacts.js
- 2026-04-28:
enrich-contacts.jscreated as net-new il-marketplace-pull v2 piece (Apollo+Hunter cascade) - 2026-04-28:
wholesaler_contactstable schema decision (renamingdata_il_marketplace_contacts) perproject_acquisition_deals_centralized_schema.md