Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Apollo Enrichment

ASecurity

Find verified emails for a list of leads via Apollo's bulk match (batches of 10), update the Airtable rows with email + company + title + location, and create Apollo contacts under a named label so the leads show up in your Apollo CRM workflows. Phase 3 of both pipelines, runnable standalone if you have an Airtable table populated by the loader.

113 stars
0 votes
0 copies
0 views
Added 9/19/2026
businessgoreactdatabase

Security Analysis

A100/100

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add gethouston/houston --skill apollo-enrichment --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Apollo Enrichment?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Apollo Enrichment
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gethouston-apollo-enrichment/badge)](https://www.skillsdirectory.com/skills/gethouston-apollo-enrichment)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: apollo-enrichment
description: "Find verified emails for a list of leads via Apollo's bulk match (batches of 10), update the Airtable rows with email + company + title + location, and create Apollo contacts under a named label so the leads show up in your Apollo CRM workflows. Phase 3 of both pipelines, runnable standalone if you have an Airtable table populated by the loader."
version: 1
category: Outbound
featured: no
image: magnifying-glass-tilted-left
integrations: [airtable, apollo]
x_houston:
  created_by: houston
  skill_schema: 1
---


# Apollo Enrichment

Take a list of leads in an Airtable table and find verified emails for as many as possible via Apollo's bulk match endpoint. Updates the Airtable rows in place with email + company + title + location, and creates Apollo contacts under a named label so the leads land in your Apollo CRM workflows. Match rate is highly audience-dependent  -  expect 50-70% on US founder / operator audiences, lower on consumer or non-US audiences.

## When to use

- "Enrich these leads with Apollo: <Airtable table>".
- "Find emails for the rows in this table".
- Phase 3 of either LinkedIn pipeline (called by the orchestrator).
- You have an Airtable table populated with `Profile URL`s and want emails attached.

## When NOT to use

- The leads aren't in Airtable yet  -  load them first with `airtable-lead-loader`.
- You only want to **read** Apollo data, not modify Airtable  -  this skill writes back to Airtable as part of its contract; if you only need a one-shot Apollo lookup, do it manually.

## Connections I need

- **Airtable** (database) - Required. I read the rows, then write the enrichment fields back.
- **Apollo** (enrichment) - Required. I use the `apollo_people_bulk_match` endpoint and the `apollo_contacts_create` endpoint via Composio.

If either is missing I stop and ask you to connect it.

## Information I need

- **The Airtable base ID + table ID** - Required. If called from an orchestrator, both are passed in. If called standalone, I list bases and tables and ask which one if there's any ambiguity.
- **An Apollo contact label** - Optional. Defaults to `LinkedIn {sourceType} - {sourceAuthor} Post`, derived from the table's `Source Type` and `Source Author` fields (every row in a given table has the same source). Override per call.

## Steps
<!-- houston-workflow:v1 -->

1. **Pull all records.** Page through the Airtable table 100 records at a time until done. Collect rows where `Email` is empty (don't re-enrich rows that already have an email). Stash the source `Profile URL`, `Full Name`, `Headline`, and Airtable `record_id` for each.

2. **Batch into groups of 10.** Apollo's `apollo_people_bulk_match` accepts up to 10 lookups per call. Split the not-yet-enriched rows into chunks of 10.

3. **Bulk match in parallel.** Spawn parallel agents (4 at a time, same as the loader) and call `apollo_people_bulk_match` with each chunk. Per row in the request, send `linkedin_url: profileUrl` as the primary key, plus `name: fullName` as a fallback for Apollo's matcher. Wait for all calls to complete.

4. **Map results back to Airtable rows.** Apollo returns an array per call in the same order as the request. Per result:
   - **Verified email returned**  -  set `Email`, `Email Confidence: "verified"`, `Company`, `Title`, `Location`, `Apollo Contact URL`, `Enriched At`.
   - **Guessed email returned** (Apollo flags lower-confidence matches)  -  same fields, but `Email Confidence: "guessed"`. The downstream `instantly-campaign` skill drops these by default.
   - **No match**  -  set `Email Confidence: "no-match"` only. Leave `Email`, `Company`, `Title` empty.

5. **Update Airtable in batches.** Update 10 records per `update records` call (Airtable's actual batch limit on update, unlike create). Spawn parallel update agents.

6. **Create Apollo contacts under the label.** For every row that came back with a verified or guessed email, call `apollo_contacts_create` with the contact's Apollo person ID and the chosen label. Apollo deduplicates contacts by email, so re-running this step on the same data is idempotent.

7. **Re-fetch enriched rows.** Page the table again, collect rows where `Email Confidence: "verified"`. Save them to `runs/{runId}/contacts.json` in the shape `instantly-campaign` expects:

   ```jsonc
   {
     "firstName": "Jane",
     "fullName": "Jane Doe",
     "email": "jane@northwind.example",
     "company": "Northwind",
     "title": "VP Operations",
     "linkedinUrl": "https://www.linkedin.com/in/janedoe",
     "personalizationFields": {
       "topRole": "VP Operations at Northwind",
       "topSchool": "Stanford",
       "topSkills": ["Operations", "Process Design"]
     }
   }
   ```

   `personalizationFields` only populated for reaction-source tables (where the loader wrote `Top Role`, `Top School`, `Top Skills`). For comment-source tables this object is empty.

8. **Update `leads.json`.** For every row enriched, find the matching `profileUrl` in `leads.json` and set `email`, `emailConfidence`, `company`, `title`, `location`, `enrichedAt`. Read-merge-write atomically.

9. **Append to `outputs.json`.** One row: `{type: "enrichment", title: "Apollo enrichment - {tableName}", summary: "Matched {M} of {N} ({M/N}% match rate). {V} verified emails ready for outreach.", path: "runs/{runId}/contacts.json", status: "ready", domain: "enrichment"}`.

10. **Summarize to user.** One block:
    - Total rows processed.
    - Verified emails found (count + percentage).
    - Guessed emails found (count + percentage).
    - No-match count.
    - "Verified emails saved for the next phase. Guessed emails stay in Airtable for your review."

## Outputs

- Airtable rows updated with email + company + title + location + Apollo URL + confidence.
- New Apollo contacts under the label `LinkedIn {sourceType} - {sourceAuthor} Post`.
- `runs/{runId}/contacts.json`  -  verified-email contacts ready for `instantly-campaign`.
- `leads.json`  -  enrichment fields backfilled on matching `profileUrl`s.
- `outputs.json`  -  one row, `type: "enrichment"`, `domain: "enrichment"`.

## Common failure modes

| Failure | Why | Fix |
|---|---|---|
| Match rate under 40% | Audience is consumer-heavy, non-US, or junior-titled (Apollo's database is enterprise-skewed) | Normal for some audiences; proceed with what you have |
| Cached data missing emails on the re-fetch | Airtable read returned a stale cache | Wait 30 seconds and re-page; if still missing, the update writes silently failed - check for rate-limit errors in the run notes |
| Apollo rate-limit on bulk match | Too many parallel agents on a small Apollo plan | Drop to 2 parallel agents instead of 4 |
| Apollo returns a 422 on `linkedin_url` | The URL format doesn't match what Apollo expects (trailing slash, `/in/` vs `/pub/`) | Normalize to `https://www.linkedin.com/in/<slug>` before sending; strip trailing slashes |

## What I never do

- **Re-enrich rows that already have an email.** I check `Email` is empty before including a row in the bulk-match batches. Saves Apollo credits and avoids overwriting good data.
- **Push guessed emails into the Instantly campaign.** Guessed emails stay in Airtable for your review. Only verified emails make it to `runs/{runId}/contacts.json`.
- **Send emails directly through Apollo.** Apollo's send endpoints exist, but cold campaigns belong in a dedicated sender (Instantly) for deliverability tracking.
- **Hardcode the Apollo label format or the bulk-match endpoint name.** All discovered via Composio at runtime.

Attribution

gethoustongethouston
View sourceMore from gethouston →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Solution Architect

Designs system architecture, component specifications, and technical integration strategy. Use when: designing solutions, system architecture, technology stack, or integration approaches.

192 votes

Akorchak:Venture Assessment

Generate a comprehensive VC investment assessment report for a company

72 votes

Stock Analysis

Analyze stocks and cryptocurrencies using Yahoo Finance data. Supports portfolio management (create, add, remove assets), crypto analysis (Top 20 by market cap), and periodic performance reports (daily/weekly/monthly/quarterly/yearly). 8 analysis dimensions for stocks, 3 for crypto. Use for stock analysis, portfolio tracking, earnings reactions, or crypto monitoring.

6511 votes

Just Fucking Cancel

Find and cancel unwanted subscriptions by analyzing bank transactions. Detects recurring charges, calculates annual waste, and helps you cancel with direct URLs and browser automation. Use when: 'cancel subscriptions', 'audit subscriptions', 'find recurring charges', 'what am I paying for', 'save money', 'subscription cleanup', 'stop wasting money'. Supports CSV import (Apple Card, Chase, Amex, Citi, Bank of America, Capital One, Mint, Copilot) OR Plaid API for automatic transaction pull. Out...

6511 votes

Telegram Compose

Compose rich, readable Telegram messages using HTML formatting via direct Telegram API. Use when: (1) Sending any Telegram message beyond a simple one-line reply, (2) Creating structured messages with sections, lists, or status updates, (3) Need formatting unavailable via Clawdbot's Markdown conversion (underline, spoilers, expandable blockquotes, user mentions by ID), (4) Sending alerts, reports, summaries, or notifications to Telegram, (5) Want professional, scannable message formatting wit...

6511 votes
View all in business →