DEEP DIVE · AI-OPERATED OUTBOUND

How I Actually Run Email with Claude Code

Not "I use AI to write emails." An AI agent runs the whole campaign pipeline: it pulls the right companies from our sales database, enforces do-not-email rules it cannot skip, matches each company to a pitch that has already won us customers, and writes a unique email for every person with about twenty AI writers working in parallel. I describe the campaign in plain English and approve at the two moments that matter.

daily production process Claude Code agent Python stages local sales database HubSpot read-only EmailBison / Lemlist ~20 parallel AI writers
The Workflow

Brain dump in, validated campaign out

A campaign starts as a sentence: "Target VPs of Marketing at mid-market SaaS companies." Claude Code reads the system's instruction file, copies a campaign template, fills in the campaign settings from the brain dump, shows it to me for confirmation, then runs six stages, each writing a checkpoint file so any failure resumes instead of restarting, and every stage asking before proceeding.

flowchart TD
  DUMP["Brain dump:
'target VPs of Marketing at mid-market SaaS'"] --> YAML[Claude fills in the campaign settings,
shows them for confirmation] YAML --> S1[Stage 1 · Pull target companies
from a local pre-scored database
fit, tier, and size filters] S1 --> S2[Stage 2 · HubSpot enrich
read-only: contacts, deals,
lifecycle, company props] S2 --> S3[Stage 3 · Find the right people
CRM first, then our database,
outside lookups only for gaps] S3 --> S4[Stage 4 · VOC play scoring
7 plays, signal + persona fit] S4 --> PAUSE{{HUMAN GATE
review play assignments}} PAUSE --> S5[Stage 5 · Play-aware scaffolds
hook, pain, mechanism, CTA
+ customer quotes per play] S5 --> S6[Stage 6 · Copy generation
~20 parallel AI writers
~4 leads each, unique copy] S6 --> VAL[Validators:
spam words, word count,
play alignment, resolved vars] VAL --> SAMPLE{{HUMAN GATE
review sample emails}} SAMPLE --> UP[Upload to EmailBison
create leads → attach to campaign] S1 -.checkpoint.-> CK[(accounts.json)] S3 -.checkpoint.-> CK2[(contacts.json)] S6 -.checkpoint.-> CK3[(leads_final.csv)]

The data compounds. Across my work we were dealing with tens of thousands of accounts and hundreds of thousands of contacts, and every campaign made those databases better: fit scores, enriched profiles, and buying signals accumulated just by doing the job regularly. Outside lookup tools (Apollo, LeadMagic, Exa) only fill gaps, and every result is cached so a credit is never spent twice on the same person.

The Guardrails

Exclusion rules the AI cannot skip

The instruction file marks these mandatory at every stage: account pull, contact discovery, and final output all re-check them. This is the difference between "AI helps with email" and "AI can be trusted with the send button":

GateRule
DB-only targetingOnly companies in the sales DB get emailed. External tools detect signals and enrich, they never inject net-new companies into a campaign.
Customer exclusionChecked in two places (account flag AND customer table) at three stages. Either flag excludes.
Pipeline protectionHubSpot lifecycle = customer/opportunity, or any open deal, blocks the account, catching CRM truth the local DB hasn't synced yet.
Recently contactedThe email platform itself is the source of truth for who was messaged recently, and accounts a rep is actively working get a longer buffer than unowned ones. Relationships get protected automatically.
Domain matchEnriched emails must match the target company's domain, with known aliases mapped, no Frankenstein contacts.
Final preflightBefore any upload: a preflight script re-checks customers/deals, plus a title and location review, plus a pre-delivery sample. Never skipped.
Ask, don't assume
Some campaigns (cohort invites, events) intentionally target customers. The rule isn't "always exclude", it's "exclude by default, and explicitly ask before finalizing." Encoding when to ask is as important as encoding what to block.
The Copy Engine

Voice-of-customer plays + 1:1 generated copy

Play selection is scored, not vibes. Every account is scored against 7 plays derived from actual customer call analysis, each play defined in a settings file with its signals, weights, persona fit, employee ranges, and real customer quotes. A weak match falls back to a default play, and the assignment file pauses for my review before any copy gets written.

Every lead gets unique copy. The default is not "one template with merge tags." Stage 6 groups leads into batches of ~4, generates play-aware prompts, and launches ~20 AI writers in parallel. Each email is structurally unique while holding the play's messaging, an anti-fingerprinting defense that also just reads better. Templates exist as a speed fallback, not the default.

Then machines check the machines. Validators scan every generated email: banned spam-trigger words, unresolved variables, word count in the 80–200 band, play alignment, and formatting rules (like never using em dashes, and simple HTML instead of pre-wrapped plaintext that breaks on mobile).

flowchart LR
  MSG[messages.csv
play context per lead] --> PREP[--prepare
batch into prompts] PREP --> SA1[Subagent 1
4 leads] PREP --> SA2[Subagent 2
4 leads] PREP --> SA3[...] PREP --> SA20[Subagent ~20
4 leads] SA1 --> CONS[--consolidate
merge JSON outputs] SA2 --> CONS SA3 --> CONS SA20 --> CONS CONS --> VAL[--validate
spam words · word count
play alignment · vars resolved] VAL --> FINAL[(leads_final.csv)] FINAL --> BISON[EmailBison API
create leads → attach to campaign]
Why It Works

Operational conventions that make an agent reliable

"I describe a campaign in one sentence. The system pulls scored accounts from a local DB, enriches through the CRM, picks a voice-of-customer play per account, pauses for my review twice, writes unique copy per lead with twenty parallel agents, validates every email, and uploads. The AI does the volume; the gates make sure I'd sign every send."

Want systems like these at your org?

Contact Me 727-637-2778