The Cookbook · 02
Sales
Channel-by-channel sales automation: lead context, follow-up, Apollo-driven outreach, and creative DM tactics.
Marketing fills the funnel. Sales is what happens when a real human shows up in it. The leverage looks different — fewer leads, more context per lead, much higher cost-permistake. An agent in your sales seat is not there to spam. It is there to never forget, never lose context, and never wait until tomorrow to follow up. The principle for this whole section: your agent should know every word that has been said to or about a lead — across every channel — and act on that context the way the best operator on your team would, in your voice, before you've finished your first coffee. A few rules up front: Drafts before sends. Until the voice is dialed, the agent drafts and you approve. Earned auto-send is a destination, not a starting point. One brain across every channel. WhatsApp, Telegram, Gmail, LinkedIn DMs, your CRM, your note-taker — if the agent can't see it, the agent can't follow up on it. Personalization is the moat. Generic outreach is dead. The whole back half of this section is about how cheap real personalization gets when the agent does the research. Cron the boring parts. Every morning, ghosting check. Every booking, research email. Every call, post-call recap. None of these are decisions; they're rules. Approval gates compress, not vanish. Day one: every send needs your approval. Month three: pre-call emails auto-send, follow-ups still drafted. Earn the autonomy.
1. Connect Every Channel
Before any sales automation works, the agent needs read access to everywhere prospects talk to you. This is the boring foundation tip nobody wants to do — until they realize that every "follow-up assistant" without it is just a generic reminder app.
Tip 1.1 — Plug your agent into every channel you talk to prospects on
What it does: Connects your agent to every messaging surface where deals actually happen — WhatsApp, Telegram, Gmail, Slack, LinkedIn DMs, Instagram DMs, whatever you actually use. Read access first; send access later, per channel, after the voice is dialed. Why it wins: Most sales operators talk to prospects on 3-5 channels and have CRM notes on maybe two of them. The agent that has read access to all of them has a context advantage your competitors literally cannot match. "I see Sarah DM'd you on LinkedIn three
weeks ago about pricing and you replied on WhatsApp two days later" — that's a sentence no CRM can produce on its own. Tools: WhatsApp via the native desktop app's SQLite DB (Mac) or WhatsApp Web + a browser-relay extension; Gmail via Google Workspace API (OAuth); Telegram via Bot API or a userbot client; LinkedIn via a session-cookie scraper (e.g. linkedin-scraper GitHub repos); Slack via the official Slack API; Instagram via Instaloader. agent-browser covers any web channel that doesn't have a clean API. How to wire it:
- List every channel where prospects message you. Be honest — include the ones you wish you didn't use.
- For each channel, pick the cheapest read access path:
- WhatsApp (Mac): the native app keeps a SQLite DB at ~/Library/Group Containers/group.net.whatsapp.WhatsApp.shared/ChatStorage.sqlite . Grant your runtime (Node.js, Python, whatever) Full Disk Access in macOS Privacy & Security. Now your agent can SELECT every message.
- WhatsApp (everywhere else): WhatsApp Web in Chrome with a browser-relay extension. Agent reads the DOM, no Business API needed, no ban risk (it's the official client).
- Gmail: Google Cloud project → enable Gmail API → OAuth Desktop creds → scopes gmail.readonly (read), gmail.compose (drafts), and only later gmail.send .
- Telegram: Bot API for groups you control; userbot (Telethon) for everything else, including 1:1 DMs you actually have on Telegram.
- LinkedIn: open-source scraper repo, burner-account cookie, low throughput. Don't blow up your main account.
- Slack: OAuth app with channels:history , im:history , groups:history , users:read . Free.
- Map each channel's identifier back to a single canonical lead record (more on this in 2.1). Email is usually the spine.
- Index everything into a queryable store — flat JSON per lead, or a Postgres/DuckDB you can SQL against. Doesn't have to be fancy. Has to be searchable.
- Test by asking the agent: "Pull every message I've ever exchanged with Sarah Chen across every channel, in chronological order." If it can't do that in 10 seconds, the connection isn't done. Example prompt to your agent: I want you to have read access to every channel where I talk to prospects. List them: WhatsApp (Mac native, SQLite at ~/Library/Group
), Gmail (Google Workspace API, OAuth creds in ~/secrets/gmail.json ), Telegram (userbot with session in ~/secrets/telegram.session ), LinkedIn DMs (burner session cookie in ~/secrets/linkedin.json ), Slack (OAuth token in env SLACK_BOT_TOKEN ). For each channel, write a thin read-only adapter that exposes fetch_messages(contact_identifier, since_date) and list_threads(since_date) . Save the adapters as _skillsanonymized/channels/
Tip 1.2 — Voice skill per channel (trained on your last 100 sent messages there)
What it does: A separate voice skill for each channel you send on — WhatsApp, email, Telegram, LinkedIn DMs, Slack. Each skill is built by feeding the agent the last 100-ish messages you actually sent on that channel and asking it to extract the patterns. Why it wins: Your WhatsApp voice is not your email voice. WhatsApp is "yessir, dropping the link", lowercase, no apostrophes, 1-2 sentences per bubble. Email is "Hey Ed, looking forward to Wednesday — quick thought before the call." If the agent sends an email in your WhatsApp voice, it reads insane. If it sends a WhatsApp in your email voice, it reads stiff. Per-channel voice skills are non-negotiable. Tools: Whatever pulled the messages in 1.1, plus your agent's skill creator. How to wire it:
1. Tell your agent to pull the last 100 outbound messages you sent on each channel,
filtered to business contacts only. Personal voice will poison the training set fast (and you really don't want the agent telling a CFO "love you bro"). 2. For each channel, tell the agent to identify: capitalization patterns, message length distribution, greeting and closing styles, slang, abbreviations, emoji density, multibubble cadence (do you send one long message or six short ones?), opinions you keep returning to, phrases you overuse, anti-patterns (corporate things you'd never say). 3. Save as voice-skill-template — one instance per channel ( whatsapp-voice , email-voice , etc.). The template is production-grade; per-channel instances are patternonly — tell your agent to build each one from your sent-message history.
Tip 1.3 — CRM connection (Attio, HubSpot, Pipedrive — pick one, wire it deep)
What it does: Gives the agent full read/write to one CRM that is the canonical source of truth for every lead, every deal, every stage, every note. Not three CRMs. One. The agent reads from it before every action and writes back after every action. Why it wins: Without a CRM, your agent will rediscover who Sarah is every time it sees her name. With one, it loads the deal record, sees the stage, sees the last call notes, sees the open tasks, and acts in context. The CRM is the agent's memory. Tools: Pick one of Attio (clean API, modern, our default recommendation), HubSpot (huge ecosystem, free tier is generous, API is verbose), Pipedrive (sales-team-first, great pipeline UI), Salesforce (only if you already pay for it), or Notion (DIY but free if you already use Notion). How to wire it: 1. Stop using two CRMs. If you have leads in three places, consolidate first. The agent multiplies whatever mess it inherits. 2. Define your schema. Minimum fields per lead: name, primary email, company, stage (cold / warm / call booked / proposal / closed-won / closed-lost / ghosted), last contact date, last contact channel, source, notes, deal value, booking link clicks (if you track them). 3. Tell your agent: "Connect my CRM for me — pull a workspace-scoped API token, store it safely, and never forget you have access." Keep the scope locked to one workspace. 4. Build a thin CRM skill: crm.get_lead(identifier) , crm.update_stage(lead, stage) , crm.append_note(lead, note) , crm.list_leads(filter) . One adapter, every other skill calls into it. 5. Bidirectional sync: when a call happens (Fathom transcript appears), the agent writes a note. When a follow-up is sent, the agent writes a note. When a lead replies, the agent updates last_contact_date . The CRM stays clean automatically. 6. Audit weekly: have the agent flag any leads with no activity in 30+ days, no stage change in 60+ days, or no notes at all. Decide: revive, archive, or close-lost. Example prompt to your agent: Wire me into [chosen CRM]. API token is in ~/secrets/
email, company, stage, last_contact_date, source). Show me the dedupe candidates before merging — never auto-merge. Watch out for: Don't let the agent auto-merge duplicate leads. False merges are very expensive to unwind. Always present candidates for human approval the first month. Lock down API token scope. A leaked HubSpot token with admin scope is a bad day. Avoid building your own CRM in a spreadsheet or Notion unless you're under 50 leads. The moment you cross that, the queries get painful. If your CRM has custom fields you don't actually fill, delete them. The agent will spend tokens reading them. Skill file: _skills-anonymized/attio-crm/ (or your CRM's equivalent), with a generic crm-adapter-template/ for porting.
2. Lead Context On Demand
Once every channel is wired and the CRM is the spine, the unlock is being able to ask one question — "what's the deal with Sarah?" — and get the full picture in 30 seconds.
Tip 2.1 — "Get the context on" any lead — full pull across CRM, channels, calls,
notes
What it does: A single skill that, given any lead identifier (name, email, company), produces a complete situational brief: who they are, what their company does, every message ever exchanged across every channel, every call transcript, every CRM note, current stage, sentiment trend, what they last asked, what you last promised, and a recommended next action. Why it wins: Before this skill, opening a deal means 10 minutes of tab-switching: CRM, Gmail, WhatsApp scrollback, Fathom recordings, LinkedIn. After it, you ask once and the brief lands on Telegram in 30 seconds. Multiply that by the number of leads you touch in a week and the time savings are obscene. More importantly: you walk into every conversation primed. Tools: Your CRM skill from 1.3, your channel adapters from 1.1, your note-taker from 2.2. A single lead-status skill stitches them together. How to wire it: 1. Define what "full context" means in your business. Default suggestion: - Identity: name, email, company, role, LinkedIn URL, source.
- CRM stage: current stage, deal value, last update.
- Conversation: every message across every channel in chronological order, with channel tags.
- Calls: every transcript / summary from Fathom (or Otter / Fireflies / Granola / Read.ai).
- Promises: anything you said you'd do that's still open (the agent extracts these from transcripts and DMs).
- Open questions from them: anything they asked you that's still unanswered.
- Sentiment trend: positive / neutral / cooling / cold based on reply latency and tone.
- Recommended next action: one line.
- The skill takes any identifier and resolves it to the CRM record first. If multiple matches, asks you to disambiguate. Never guess on identity — wrong-person messages are a fireable mistake.
- Output goes to Telegram (or wherever you prefer to be pinged) in a scannable format. 60-second read max.
- Add to your shortcut: ask it from your phone in 5 seconds before walking into any call. Example prompt to your agent: Build a lead-status skill. Input: any identifier (name, email, company). Process: (1) resolve to CRM record — if ambiguous, ask me; (2) pull every message across WhatsApp, email, Telegram, LinkedIn, Slack for that lead in chronological order; (3) pull every Fathom transcript involving them; (4) extract from transcripts + DMs: open promises I made, open questions they asked, sentiment trend; (5) format as a onepage Telegram brief — identity block, CRM stage block, recent conversation timeline (last 10 exchanges), open promises, open questions, sentiment, recommended next action. Cap output at 600 words. Add the /last_call_summary link if a Fathom recording exists. Use _skills-anonymized/lead-status/ as the base — your job is to wire it to my channels. Watch out for: Identity collisions are the silent killer. Two "John Smiths." A lead who switched companies. A spouse on the same shared email. Always disambiguate when in doubt; never guess. Don't dump every message — cap to last 20 exchanges or last 90 days, whichever is smaller. Dumping everything is unreadable and wastes tokens. The "recommended next action" is the most valuable line — it's also the easiest to make generic. Force the agent to be specific: "send the proposal you promised on Tuesday" not "follow up."
Skill file: _skills-anonymized/lead-status/ (production skill — directly liftable).
Tip 2.2 — Note-taker connection (Fathom) and what your agent does with
transcripts
What it does: Connects your agent to your call note-taker (Fathom, Otter, Fireflies, Granola, Read.ai) so it can pull every call transcript on demand and act on it — extracting key points, pain points, objections, promises, next steps, and feeding all of that into the CRM and follow-up pipeline. Why it wins: Your call transcripts are the highest-information document about any deal. They have the real objections, the budget signals, the timeline pressure, the words the prospect actually used. Most operators leave that data buried in 47 PDF transcripts they never reopen. The agent reads them, extracts what matters, and surfaces it the moment it's useful. Tools: Fathom is the default we recommend (its API exposes meetings, transcripts, attendees). Otter, Fireflies, Granola, and Read.ai all have APIs. Pick one. Sign up, then tell your agent: "I have a Fathom account — connect it for me and do everything you need to never forget you have access." How to wire it: 1. Sign up for the note-taker (Fathom or equivalent). Then tell your agent: "Connect this for me — get whatever you need from the dashboard, store it safely, and verify you can pull recent meetings." 2. Build a fathom-transcripts skill (or equivalent) with: list_recent_calls(since) , get_transcript(meeting_id) , get_summary(meeting_id) , attendees(meeting_id) . 3. Set up matching: every transcript needs to resolve to a CRM lead via attendee email. If the email doesn't match any CRM record, flag it for manual review — don't guess. 4. On every new transcript (poll every 15 minutes or use a webhook), the agent: - Pulls the transcript and summary. - Extracts: top 3 pain points, top objections, budget signals, timeline mentions, promises you made ("I'll send you the proposal Friday"), promises they made ("I'll loop in our CFO"), explicit next steps. - Appends as a structured note to the CRM lead. - If you promised to send something, drafts it (using the right channel voice skill) and queues for your approval. - If they promised to loop someone in and 5 days pass with no update, the agent flags it.
1. Search across all transcripts is a side benefit: "find every call where someone mentioned
a competitor by name" becomes a one-line query. Example prompt to your agent: Wire me into Fathom. Build a fathom skill at _skills-anonymized/fathom-transcripts/ exposing: list_recent_calls, get_transcript, get_summary, attendees. Every 15 minutes, poll for new calls since the last run. For each new transcript: (1) match to CRM via attendee email — skip if no match, alert me; (2) extract pain points, objections, budget signals, timeline mentions, my promises, their promises, next steps; (3) append structured note to CRM; (4) for any promise I made, draft the deliverable in the right voice and queue for approval; (5) for any promise they made, set a 5-day reminder. Send me a daily 8am digest: yesterday's calls, what got extracted, what's queued for approval. Watch out for: Transcripts have transcription errors. The agent should never quote a transcript verbatim back to a prospect without verifying — names, numbers, and product names get mangled all the time. Long calls (60+ min) overflow context windows fast. Have the agent chunk-summarize first, then operate on the summary. Don't write transcripts directly into the CRM record body — they balloon the record and bog every read. Store transcripts separately; write extracted notes into the CRM with a link. Skill file: _skills-anonymized/fathom-transcripts/ , plus _skillsanonymized/post-call-autopilot/ for the post-call extraction pipeline.
Tip 2.3 — Pre-call research auto-sent to your email on booking
What it does: The moment a prospect books a call (Cal.com / Calendly webhook fires), your agent kicks off a deep research pass — company website, LinkedIn of the booker, recent news, funding, tech stack, what they probably want — and emails the brief to you so you read it on your phone over coffee before the call. Why it wins: Walking into a call cold is malpractice in 2026. Walking in with a one-page brief that mentions the funding round they closed last week is a different conversation. Most sales reps "do their research" by glancing at the LinkedIn for 90 seconds before the call. The agent does 20 minutes of research and condenses it to a 60-second read. Tools: Cal.com webhooks (or Calendly's), agent-browser or Scrapling for site scraping, LinkedIn scraper, a news API (or just SerpAPI/SearXNG), your email skill.
How to wire it: 1. Tell your agent to wire the booking webhook for you — "set up the BOOKING_CREATED webhook from my Cal.com pointing to your handler." Hard rule baked in: first-booking only. Returning prospects don't trigger this — they trigger post-call autopilot (6.3). 2. On webhook fire, the agent receives: name, email, booking time, any answers to your booking form questions. 3. Research pass — fan out subagents in parallel: - Subagent A: company website. Read their homepage, about, pricing, careers page. Extract what they do, vibe, customer base, size signals. - Subagent B: LinkedIn. Pull the booker's profile, current role, tenure, recent posts. Pull the company page for headcount, growth signals. - Subagent C: news. Search "[company name] last 90 days" — funding, hires, launches, layoffs. - Subagent D: tech stack via BuiltWith or Wappalyzer if relevant to your offer. 1. Synthesize to a 1-page brief: who, what they do, why they probably booked (your best guess based on their booking-form answers + their company stage), 3 things to mention to show you did homework, 3 likely objections, suggested opening question. 2. Email the brief to yourself with subject 📋 Pre-call:
Research takes 30-90 seconds. Don't promise yourself you'll only book calls 24 hours out — sometimes prospects book the same day, so the brief needs to land in your inbox within 5 minutes of booking. Some prospects have zero digital footprint. The agent should say "minimal public info — recommend you ask X, Y, Z early" rather than padding with garbage. Skill file: _skills-anonymized/pre-call-research/ (production skill), wired through _skills-anonymized/lead-monitor/ for the webhook listener.
3. Follow-Up Automation
Follow-up is where deals die. Not because the agent forgot — the human did. The agent never forgets. This is the highest-ROI section in this whole document if you have a pipeline of warm leads sitting cold.
Tip 3.1 — "Who do I need to follow up with, check all channels" — one prompt,
full sweep
What it does: A single prompt that sweeps every channel and your CRM for any conversation where you owe someone a reply, you've ghosted, you got ghosted, or there's a promised next step that's slipping. Output: a prioritized list with one-line context and a recommended action per lead. Why it wins: This is the killer demo of having every channel wired. Most operators have a vague mental list of "people I should get back to" — usually 3-5 names — when the real list is 25+. The agent shows you the full list and ranks it so you can act on the top 5 today. Tools: Everything from Section 1, plus your CRM. The skill itself is a synthesis layer. How to wire it: 1. Define "needs follow-up" rules. Default suggestion: - 🔴 URGENT — they messaged me, I haven't replied in 24h (you're ghosting an active lead) - 🟡 MEDIUM — I messaged, no reply in 3 days (they're cooling) - 🟠 STALE — open deal in CRM, no contact 7+ days (warm lead going cold) - ⚫ DROPPED — open deal, no contact 14+ days (last-chance nudge) - 🟣 PROMISE BROKEN — call transcript says I'd send X by Y, Y has passed, X hasn't sent (you broke a promise; this is the worst kind) 1. The agent scans all channels + CRM + transcript-extracted promises (from 2.2) and tags each one with the right bucket.
2. Output: a single Telegram message, sorted urgent → stale, max 20 items, each one a
single line with: lead name, bucket, channel, days since last action, one-line context. 3. Each line has a one-tap response: "draft", "snooze 3d", "archive", "open lead". 4. On "draft," the agent runs Tip 3.2 for that specific lead. Example prompt to your agent: Build a followup-sweep skill. When I send "who needs follow-up", scan all channels (WhatsApp, email, Telegram, LinkedIn, Slack) and the CRM and the Fathom-extracted promises log. Tag each candidate as: URGENT (they messaged, I haven't replied in 24h), MEDIUM (I messaged, no reply 3d), STALE (open CRM deal, no contact 7d), DROPPED (open deal, no contact 14d), PROMISE BROKEN (I promised X by Y, Y passed, X unsent). Return a single Telegram message: max 20 items, sorted urgent first, each line = lead, bucket, channel, days, one-line context, "draft" button. Don't include closed-won or closed-lost. Don't include leads I've snoozed. Watch out for: Calibrate the day thresholds to your sales cycle. SaaS 14-day cycles use different numbers than enterprise 6-month cycles. Don't show more than 20 items in one message. Past 20, people freeze. If there are 50, the agent should say "showing top 20 — 30 more flagged, run again after you clear these." Be ruthless about excluding noise. Newsletters in your Gmail aren't follow-up candidates. Mailing list replies aren't either. Skill file: _skills-anonymized/stale-lead-blitz/ is the closest production skill — extend it to cover the full multi-channel sweep.
Tip 3.2 — Followup-checker skill: detects ghosting (both directions), drafts in
voice, sends or holds for approval
What it does: Given a specific lead flagged for follow-up, the skill pulls full context (via Tip 2.1), classifies the situation (you ghosted, they ghosted, promise broken, stale check-in), picks the right channel (whatever you last used with them, or whatever your lead.preferred_channel says), drafts the message in the voice skill for that channel, and either sends or queues for your approval. Why it wins: Without this, "follow up" means typing the same 4-line message 12 times across 12 different threads. With this, the agent does the typing, and you spend your attention on the exceptions — the ones where the draft is wrong and you need to write it yourself.
Tools: Lead-status (Tip 2.1), per-channel voice skills (Tip 1.2), CRM (Tip 1.3), channel send adapters (Tip 1.1's send-side). How to wire it: 1. Input: a lead identifier + the bucket (URGENT / STALE / etc). 2. Pull lead-status (2.1) to load full context. 3. Classify the situation precisely. Examples: - "You ghosted them mid-conversation, they last asked about pricing" → respond with the pricing answer, not a generic check-in. - "They ghosted you after a discovery call, last touch was your proposal email 9 days ago" → gentle nudge tied to what was last discussed. - "You promised to send the case study Tuesday, it's Friday" → send the case study with a "sorry for the delay" preamble (or no preamble if your voice doesn't apologize). - "Stale — open deal, last contact 12 days ago, last action was a positive call" → check-in tied to the call's next steps. 1. Pick the channel: whatever the last conversation was on, unless lead.preferred_channel overrides. 2. Draft in the appropriate voice skill (1.2). Cap length per channel norms (WhatsApp short, email medium). 3. For URGENT and PROMISE BROKEN: present draft on Telegram for one-tap send. For STALE and DROPPED: also draft but lower priority. 4. Track sent state in sdr-sent.json (or equivalent) to prevent double-sends. Example prompt to your agent: Build a followup-checker skill. Input: lead identifier + situation tag. Process: pull lead-status, classify the situation precisely (don't write generic "checking in"), pick the channel (last-used unless overridden), draft in the matching voice skill. Output: Telegram message with the draft, "send / edit / skip / snooze" buttons. On send: dispatch via the channel adapter, log to sdr-sent.json with channel, message body, timestamp, and lead ID. Never send to a lead with status = "do_not_contact" . Never send if a draft to this lead was sent in the last 24h (prevents double-tap loops). Cadence-aware tone: 1-2d recap, 3-5d soft nudge, 7-13d gentle wake-up, 14+d "last attempt" framing. Watch out for: Approval gates first. Don't unlock auto-send for at least two weeks of supervised drafts. Earn it.
"Just checking in" is the worst message. Hard-code a ban on that phrase across all voice skills. The follow-up must reference something specific from the last conversation. Time-zone awareness matters more than you'd think. Don't ping a prospect in Tokyo at 3am their time. The agent should know the prospect's likely TZ from their company/profile and respect a 9am-6pm send window. Don't follow up with closed-lost leads inside the cool-off window (usually 90 days). It's annoying and burns the relationship. Skill file: _skills-anonymized/pipeline-sdr/ , _skills-anonymized/emailfollowups/ , _skills-anonymized/outreach-drafter/ .
Tip 3.3 — Cron the follow-up sweep (daily morning brief)
What it does: Schedule the full follow-up sweep to run automatically. Every morning at 7am local, the agent runs Tip 3.1, drafts the top 5 follow-ups via Tip 3.2, and pings you on Telegram with the queue ready for one-tap approvals. You drink coffee, tap five times, the day's follow-ups are done. Why it wins: "I'll do follow-ups after lunch" never survives lunch. Putting it on a cron + a morning ping + one-tap UX means follow-ups actually happen daily. This is the difference between operators who close cleanly and operators who lose deals to ghosting. Tools: Whatever cron mechanism your agent harness uses, your Telegram bot, your followup sweep + checker skills. How to wire it: 1. Define the cadence. Default: daily 7am local. Also useful: a Sunday-evening "weekly review" run that pulls anything that's been stale 14+ days. 2. The morning run pipes Tip 3.1's output into Tip 3.2 for the top 5 highest-priority items. 3. Telegram message format: ``` 📋 Morning follow-ups (5) 1. 🔴 Sarah @ Acme — you owe pricing reply (2d). Draft: "Hey Sarah..." [send/edit/skip] 2. 🟡 Tom @ Initech — no reply in 4d. Draft: "...". [send/edit/skip] ... `
- Each line is one tap to send, one tap to edit, one tap to skip.
- Anything skipped today auto-reappears tomorrow unless explicitly snoozed.
- Weekly summary on Fridays: how many sent, reply rate, leads revived, leads written off. Example prompt to your agent: Schedule a daily 7am cron that runs followup-sweep then followup-checker on the top 5 items. Output a Telegram message in this format: "📋 Morning follow-ups (N)"
then one line per item with bucket emoji, lead, situation, draft preview (60 chars), three buttons (send/edit/skip). Items skipped today reappear tomorrow unless I send "/snooze [lead] 7d". On Fridays, also send a weekly summary: items sent this week, reply rate, leads revived, leads written off. Use Sonnet for the cron (cheaper than Opus, plenty smart for drafting). Log every action to sdr-sent.json . Watch out for: Don't let the agent send before you're awake. Pin the cron to local time, not UTC. 5 items is the right number. 10 overwhelms; 3 misses things. Tune to 5. Make "skip" cheap and "send" cheap. Editing should be the rare friction step. If the agent's reply rate drops below ~25% over 30 days, the voice skill is stale or the buckets are mis-tuned. Investigate. Skill file: Composite — wires _skills-anonymized/stale-lead-blitz/ , _skillsanonymized/pipeline-sdr/ , and the channel voice skills.
4. Personalized Cold Outreach (the Apollo pipeline)
Cold outreach is not dead. Generic cold outreach is dead. The whole pipeline below produces messages where the prospect can't tell you didn't write each one yourself, because the agent did real research before writing each one. The volume tradeoff is intentional: 10-15 sends per day per address, not 500. Deliverability stays clean; reply rates run 5-15% instead of <1%. That's the math.
Tip 4.1 — ICP conversation + Apollo sourcing to spreadsheet
What it does: You have a 20-minute conversation with the agent about your ICP — what they do, what they spend on, where they live, what they're titled, what stage their company's in, what stack signals matter. The agent translates that into Apollo filters, pulls the matching leads, and dumps a clean spreadsheet. Why it wins: Apollo's filters are powerful but tedious. Most people use them badly because they don't actually know their ICP precisely enough — so they pull a noisy list and the open rate suffers. A guided conversation with the agent forces you to articulate specifics. The agent does the click-work; you do the thinking. Tools: Apollo.io (paid — the cheapest plan with API access is fine; you don't need Pro). Their REST API. A Google Sheet (or Airtable, or local CSV) for the output. How to wire it: 1. Sign up for Apollo. Then tell your agent: "I have an Apollo account — connect it and do whatever you need so you can run searches from here."
2. Build a apollo skill exposing: search_contacts(filters, limit) ,
enrich_contact(email_or_id) , list_saved_searches() .
- The ICP conversation prompt (below) walks the agent through: industry, geography, headcount range, revenue range (if known), titles, technographic signals, exclusion criteria. The agent translates your answers into Apollo filter JSON.
- Pull a sample first. 50 leads. Audit it manually for 10 minutes — does this match the ICP you described? If not, refine the filters and pull again.
- Once the sample is right, pull the full list. Cap each batch at 500-2000 — Apollo throttles hard above that anyway.
- Output: a sheet with columns: name | title | company | headcount | linkedin_url | website | email | location | apollo_id | enrichment_status | research_status | personalization_status | message |
. 7. Save the filter set as a named "ICP" in the agent's config so you can re-run sourcing whenever inventory runs low. Example prompt to your agent (the ICP conversation): Help me get specific about my ICP for cold outreach. I'll answer your questions; you write Apollo filter JSON. Ask me about: industry (be specific — "B2B SaaS" is too broad), geography, headcount range, revenue band if known, exact titles (and the title variants — VP Eng, Head of Engineering, Director of Engineering), seniority floor, technographics if relevant (we sell into Stripe shops vs. Adyen shops? Different list), and exclusion criteria (no agencies, no enterprise above 5k headcount, etc). When we're done, output the filter JSON, pull a 50-lead sample via Apollo's API, and show me the first 10 with a one-line justification each ("matches because: VP Eng, 47 headcount, US"). I'll tell you which 3 are misses and you'll re-tune the filters. Once I approve, pull the full list (cap 2000) and dump to a Google Sheet at the URL I give you. Watch out for: "List quality > list size" is so true it should be tattooed. 200 perfect leads outperform 2000 noisy ones. Apollo's data freshness varies. Verify a sample's emails are still valid before sending — use NeverBounce or Apollo's own verification. Don't pull the same ICP twice. Track which leads you've already messaged in your CRM and exclude them at the Apollo step, not after. Title variants are the most common ICP miss. "Head of Sales" and "VP Sales" and "Director of Sales" are different lists. Be exhaustive. Skill file: Pair an Apollo (or Clay/Lemlist) adapter with attio-crm for dedup against existing leads. Pattern only — no standalone Apollo skill in this version. Tell your agent to write the sent_status
adapter from this recipe.
Tip 4.2 — Agent enrichment pass (LinkedIn, site, news)
What it does: For every lead in the sheet, the agent does a second-pass enrichment beyond what Apollo provides — scrape their LinkedIn, read their company site, check news for the last 90 days, note anything specific. Output: a "research" column populated per lead with 2-3 sentences of real specifics. Why it wins: Apollo data tells you who they are. Real personalization needs you to know what they're doing right now. A funding round, a hire, a product launch, a tweet from last week. The enrichment pass is what turns "I see you're at Acme" into "I saw Acme just raised your Series B — congrats." Tools: Your LinkedIn scraper (1.1), agent-browser or Scrapling for sites, a news API (SerpAPI, NewsAPI, or just Google News scrape), Whisper for any video they've published (the free open-source model is fine). How to wire it: 1. The sheet has a research_status column. Default pending . 2. Cron a daily enrichment job: for the next N pending rows (cap 50/day to respect LinkedIn rate limits), spawn the enrichment subagents: - Subagent A — LinkedIn: profile, headline, last 5 posts. Capture verbatim hooks from posts (these become personalization fuel in 4.3). - Subagent B — Company site: about, blog, careers page (careers reveals what they're scaling). Capture the company's tone of voice. - Subagent C — News: "[company] last 90 days" via SerpAPI. Capture funding, hires, launches, layoffs, awards, mentions. - Subagent D — Personal news / podcast / interview if any. Anything where they spoke recently. 1. Synthesize each lead's research into 2-3 specific sentences in the sheet's research column. Examples: > "Just raised $4.2M Series A (May 5). Posted last week about hiring 5 engineers. CEO's recent podcast: focused on developer experience as moat." 1. Mark research_status = done . Move to next. 2. Fail-soft: if a subagent finds nothing (very low public footprint), write research_status = thin and tag the lead — these get a different message template than the richresearch ones.
Example prompt to your agent:
For the sheet at [URL], find rows where research_status = pending . Pick the next
50 (LinkedIn rate limits). For each, spawn parallel enrichment: (A) LinkedIn profile + last
5 posts, capture hooks verbatim; (B) company website read; (C) news search last 90
days via SerpAPI; (D) any podcasts/interviews. Synthesize per lead into 2-3 specific
sentences in the research column. Specific = funding round names, headcount
numbers, named products, dates. Not specific = "growing company." Mark
research_status = done or thin if footprint is too low. Cap 50 leads/day. Run daily
at 4am.
Watch out for:
LinkedIn blocks aggressive scraping fast. Hard cap 50/day per session. Rotate sessions
if you need more.
"Public" doesn't mean "use without thought." Don't surface things from their personal
social that they'd be uncomfortable being referenced in a cold email.
Research that goes stale fast (news older than 90 days) shouldn't be the personalization
hook. The agent should weight recency.
If enrichment surfaces a competitor signal (they're using your competitor's product), tag
that — different sales motion.
Skill file: Composite — uses `linkedin-scraper` and `agent-browser`, with a leadenrichment skill on top. The enrichment skill is pattern-only — tell your agent to write one
from this recipe.
Tip 4.3 — Personalized-message skill built from your best examples
What it does: You hand the agent 5-10 of your absolute best, shortest, most personalized cold messages — ones you wrote by hand that actually got replies. The agent builds a skill that captures how you personalize: the open, the specific reference, the bridge to your offer, the soft ask. Then it drafts a custom message per row in the sheet using each lead's research. Why it wins: The skill captures your style of personalization, which is the moat. Generic "I noticed [thing]" templates land like robot mail. Your specific phrasing — the kind that made the last 5 founders reply — generalizes when the agent treats your examples as the style guide. Tools: Your agent's skill creator. The 5-10 best example messages you've ever sent. The enriched sheet from 4.2. How to wire it:
- Pick your 5-10 best cold messages. Real ones, that got real replies. Not templates. Not what you wish you'd written. 2. For each one, annotate: who it was sent to, why you personalized it that way, what the reply was. This context matters — the agent needs to know what's working. 3. Feed all of it to the agent: "Build a skill called personalized-outreach . Read these 10 messages. Don't summarize them. Identify the structure of my personalization: how I open, how I reference the specific thing, how I bridge to my offer, how I ask. Identify the length distribution. Identify what I never do (no 'I noticed' opens, no 'quick question', no 'wondering if', etc)." 4. The skill outputs: a draft message per lead, written using the lead's research from 4.2, in your structure, under N characters (set per channel: 75 words for email, 50 for LinkedIn, 25 for WhatsApp/SMS). 5. Drop the draft into the sheet's message column. Mark personalization_status = drafted . 6. Audit a sample of 20 manually before sending any. Tune the skill from the rejects. Example prompt to your agent (skill build): Build a personalized-outreach skill. I'm giving you my 10 best cold messages [paste them inline]. Don't summarize. Identify (1) how I open — first 8 words; (2) how I reference the specific personalization fact; (3) the bridge to my offer; (4) the ask; (5) length range; (6) what I never do — list 15 phrases I avoid. Save as a SKILL.md. Then, for the sheet at [URL] where personalization_status = pending , draft a custom message per row using each lead's research column. Length cap: 75 words for email, 50 for LinkedIn DM, 25 for WhatsApp. Write the draft to the message column. Mark drafted rows personalization_status = drafted . Don't send yet — I'll audit. Example prompt to your agent (drafting per lead): For lead [name] in the sheet, draft a cold outreach message using the personalizedoutreach skill. Use their research column for the specific reference. Channel: email. Length cap: 75 words. Send the draft to me on Telegram for approval before queuing. Watch out for: The first 50 drafts will sound formulaic. Tune the skill (add anti-patterns, add more examples) and re-draft. Don't ship formulaic. Specificity is binary. Either the personalization references a concrete fact (named product, named round, named recent post) or it doesn't. "I see you're in SaaS" is not specificity. Don't let the agent write subject lines that look like cold-outreach. The subject is half the open rate. "Quick thought on [their named product]" beats "Hi, quick question."
Skill file: Builds on outreach-drafter plus a per-user voice skill (see voice-skilltemplate). Pattern only — no standalone skill in this version. Tell your agent to wire one from these.
Tip 4.4 — Send cadence (10-15/day) for deliverability — your address or a
delegated one
What it does: Send the drafted messages at a deliverability-safe rate: 10-15 per day per sending address, with natural human pacing (not all in a 5-minute burst). Either from your own address (highest reply rates, ties to your identity) or from a delegated address (preserves your main inbox if volume is higher). Why it wins: Deliverability is the silent killer of cold outreach. The platforms (Google, Microsoft) silently mark you as a spammer the moment you spike volume or pattern-send. 10-15/day is the safe band that almost never trips filters. Anything beyond that needs serious warmup and inbox rotation infrastructure. Tools: For send: your Gmail / Outlook account directly via API, or a dedicated cold-outreach tool that handles warmup (Instantly, Smartlead, lemlist, Apollo's own sequences). For a delegated address: a separate Google Workspace user (cheap), warmed up for 2-3 weeks before going live. How to wire it: 1. Single-address case (recommended for under 50 sends/day): send directly from your address via Gmail API. The agent picks N drafts from the sheet each morning (where N = 10-15), sends them with 2-8 minute randomized delays between each, marks the sheet sent_status = sent , and writes the lead + message to your CRM. 2. Multi-address case (if you need 50+/day): spin up a fresh Google Workspace user for outreach. Warm it up first: 2-3 weeks of low-volume reciprocal mail (a warmup tool handles this) before sending any cold. Then ramp 5→10→15 over the first 7-10 days. 3. Set send window: 9am-5pm in the recipient's timezone if known, else your timezone. 4. Skip weekends for B2B unless your ICP works weekends. 5. Reply detection: any reply to a sent message pauses follow-up automation for that lead. The agent flags it, you take the conversation manually until you decide otherwise. 6. Follow-up sequence: if no reply in 4-7 days, the agent drafts one (not three, not seven — one) softer follow-up tied back to the first message. Most over-aggressive sequencing destroys reply rates more than it adds them. Example prompt to your agent: Every weekday 9am local, pick 12 leads from the sheet where personalization_status = approved and sent_status = pending . Send each via
Gmail API from [my address], with 2-8 minute random delays between sends. Subject: use the draft's subject. Body: use the draft's message. After each send: mark sent_status = sent , log to CRM as a new touch, log to outreach-sent.json with lead, timestamp, message body, subject. Skip weekends. Send window 9am-5pm recipient TZ (use lead.timezone , fallback my TZ). On any inbound reply to a sent message: stop the follow-up sequence for that lead, ping me on Telegram with the reply, tag the lead status = replied in CRM. For leads with no reply in 5 days, draft ONE follow-up (not multiple) softer than the original. Watch out for: Warmup is non-negotiable for new addresses. A fresh address sending 15 cold emails on day one gets nuked. Don't rotate sending domains to game volume. The platforms see through that. Just send less per address and accept the cap. If reply rates drop below 5% over a 50-send sample, the personalization is generic or the offer is wrong. Don't blame deliverability first. Watch the SPF/DKIM/DMARC stack on your domain. Misconfigured DNS is the #1 silent deliverability tax. Test with mail-tester.com before launching. Don't link-track on the first message. Link tracking pixels are correlated with spam classification. Plain-text first send wins on deliverability. Skill file: Composite — wires google-workspace for send + attio-crm for CRM updates. Pattern only — no standalone send adapter in this version. Tell your agent to wire one from these.
Tip 4.5 — KILLER: social-media personalization (scrape their socials, transcribe
their videos, "I loved your recent post about X")
What it does: Push personalization one layer deeper. Before drafting each message, the agent scrapes the lead's recent social activity — LinkedIn posts, X threads, Instagram captions, YouTube videos, TikToks. For any video content, it pulls the audio and transcribes with Whisper. Then the agent has real specifics — their words, on their thing, from last week — to reference. "Hey — loved your recent post on shipping in 30-day cycles" replaces "I see you're in SaaS." Why it wins: This is the line that crosses from "cold outreach" to "this person actually paid attention." Reply rates jump from 5% to 15-25% when the personalization is specific to something they made recently. Most operators don't do this because it's tedious by hand. The agent does it in 30 seconds per lead.
The full the operator take: "I loved your recent post about X" lands an order of magnitude harder than "I researched your company." Tools: LinkedIn: linkedin-scraper GitHub repos (give the agent the URL and it'll install one). Burner session, low volume. X / Twitter: Nitter (if it's up — flaky), or a paid X API tier, or agent-browser against the logged-in site. Instagram: Instaloader (the cleanest public-post scraper). YouTube: yt-dlp for video download, Whisper for transcription. The free open-source model is fine; transcription costs are negligible either way. TikTok: open-source scraper repos (rotate — they break fast). How to wire it: 1. Build a meta-skill social-media-personalization that takes a lead's social handles and returns recent content. 2. For each platform, the skill calls the right scraper, pulls the last 10 posts / 5 videos / 5 reels, captures the post text or transcript. 3. For video: tell your agent to download the audio and transcribe it with Whisper, then capture the transcript. 4. Score each piece of content for "personalization-fit" — recent (last 30 days), specific (named topic, takeaway, opinion), non-controversial (avoid political posts, avoid anything about a death/loss). 5. Pick the top 1-2 hooks per lead. Drop them into the lead's research column with a verbatim quote and a one-line agent note on why this is the right hook. 6. The personalized-outreach skill (4.3) then drafts using those specific hooks. 7. Cron the whole thing: nightly, the agent pre-scrapes the next day's outreach batch so the morning send has fresh research. Example prompt to your agent: Build a social-media-personalization skill. Input: lead with social handles in the sheet (linkedin_url, twitter_handle, instagram_handle, youtube_channel — any subset). For each platform present: pull last 10 posts (or 5 videos), capture text or transcribe video via Whisper. Score each piece for personalization fit: recent (≤ 30 days = +3, ≤ 90d = +1), specific (named topic / takeaway / opinion = +2), safe (no political / personal loss / NSFW = required, else discard). Pick top 1-2 hooks. Drop into the lead's research column as: verbatim quote (≤ 25 words), platform, date, one-line take. Cron nightly at 3am, processing the next day's outreach batch only — 30 leads max per night to respect rate limits across platforms.
Watch out for: This is the move that makes a cold message feel like an inbound. Don't dilute it with five more facts. One specific reference > five generic ones. Avoid emotional posts entirely. A lead posted about a family loss — your outreach engine doesn't get to reference it. Hardcode the safe filter; don't trust the model to "be sensitive." Don't be the LinkedIn weirdo who quotes someone's post back at them word-for-word with no take. Riff with your own quick reaction, then the bridge. Refresh the scraper repos every 2-3 months. The platforms break them on purpose. Skill file: Composite — pair linkedin-scraper + agent-browser + per-platform opensource scrapers (see the Marketing section's social-scraper sub-section for the canonical list). Pattern only — no standalone skill in this version. Tell your agent to wire one from these.
5. Creative Outreach (the site-mockup DM)
This is the highest-conversion outreach motion in this whole document if you sell into local businesses without websites — or any prospect for whom a visual artifact lands harder than a text message. The thesis: generate the prospect a deliverable they didn't ask for, send it, and let the deliverable carry the pitch. Important framing: the deliverable is an image of a homepage. Not a real site. The token cost difference between "generate an image of a homepage" and "build the actual site" is roughly 1:50. Until the prospect says yes, the image is what closes them.
Tip 5.1 — Local-business scanner
Cross-link: This is the sales-side of the same loop as Marketing Section 5 — Tip 5.1 (nowebsite scanner). Marketing produces the list; this section runs the per-lead research, mockup, and DM. For the story version, see Wild Examples #2 — The Site-Mockup Cold DM. What it does: A scanner that crawls a target geography for local businesses that don't have a website (or have an awful Wix template from 2014). Output: a clean list of prospects ripe for the mockup-DM play below. Why it wins: This is a market segment with high conversion potential and low competition — sales people don't cold-DM laundromats. The agent does, with a deliverable in hand, and closes 1-3% which is wild for cold.
Tools: Google Places API (paid, but cheap — $200/mo gets you tens of thousands of lookups), agent-browser for the website-existence check, your CRM. How to wire it: 1. Pick the geography and the categories. Example: Chiang Mai + ["dentist", "physiotherapist", "private chef", "personal trainer", "boutique hotel", "yoga studio", "Pilates studio", "med spa"]. Categories matter — pick ones with average ticket size > $500 so a website actually pays back. 2. Hit Google Places nearbySearch per category, paginate. Capture: name, address, phone, website (if any), rating, review count. 3. For each result with no website: confirm by also searching "agent-browser + a thin Google Places API wrapper. Pattern only — no standalone skill in this version. Tell your agent to write one from this recipe.
Tip 5.2 — Research-the-business skill
What it does: For each lead in the scanner output, the agent does a deep research pass on what this specific business is, who they serve, the vibe of their brand (from Google reviews, Instagram, Facebook — they almost always have one of these), what their location is like, what their pricing seems to be. Output: a 1-paragraph "soul of the business" brief that the design skill (5.4) will use to tailor the mockup. Why it wins: The mockup has to look like it could be theirs. A generic mockup gets ignored — "this is just a template, they didn't actually look at us." A mockup that uses the right vibe (warm earth tones for the yoga studio; clean clinical white for the dental practice; vintagemeets-modern for the artisan coffee shop) feels personal. The research is what makes that possible. Tools: agent-browser to read their Google profile + Instagram + Facebook. SerpAPI or Google Reviews scrape for review text. Optionally image-gen or even a vision model to assess the vibe of their existing photos. How to wire it: 1. For each business: pull their Google Business Profile (description, photos, top reviews verbatim), Instagram (if linked — last 12 posts), Facebook page (if linked). 2. Extract: what they offer (specifically — not "salon" but "vegan organic salon specializing in box braids"), who they serve (demographic signal from reviews), the brand vibe in 3 adjectives, color/aesthetic signals from their photos, pricing band (cheap / mid / premium) inferred from reviews + photos. 3. Output a business_brief column in the sheet — 80-120 words, structured: offer, audience, vibe, aesthetic, pricing band. 4. Also pull a moodboard: 3-5 of their best Instagram photos saved to a folder, ready to feed the design step. Example prompt to your agent: For each row in the scanner sheet, run business research. Pull: Google Business Profile (description, last 20 reviews verbatim, top 10 photos), Instagram (if linked, last 12 posts), Facebook page. Extract: exact offer (specific, not generic), customer segment, 3-adjective brand vibe, aesthetic signals (color palette, photography style, copywriting tone), pricing band (cheap/mid/premium). Output to business_brief column, 80-120 words. Also save their 5 best Instagram photos to /mockups/
Avoid the "I'm a Western agency rebuilding your Thai salon" energy. The brief should let the design skill respect their existing aesthetic, not impose a default minimalist look. Pricing band matters for what kind of site you'd promise. A $5 nail salon doesn't need a $5k site. Match the offer to the segment. Skill file: Builds on agent-browser + _auto-competitor-intel. Pattern only — no standalone skill in this version. Tell your agent to wire one from these.
Tip 5.3 — Find-a-great-competitor-site skill
What it does: For the prospect's exact niche + tier, the agent finds 3-5 great-looking websites of competitors who are doing the same thing, well. These become the reference set for the design skill — "make something as good as these, but not the same as any of them." Why it wins: Same reasoning as the Marketing section's image-remix trick: generating from a blank slate produces mediocre output. Generating from an exemplar shifts the floor up. The exemplar isn't copied — it's the quality bar. Tools: SerpAPI or Google Search via agent-browser for niche searches, screenshot capture ( agent-browser snapshot ), optionally Awwwards or SiteInspire scrapers for the aspirational tier. How to wire it: 1. Search query template: "best [niche] websites [year]" , "
conversion clarity. Keep top 3-5. Screenshot hero + one mid-page per reference, save to /mockups/agent-browser. Pattern only — no standalone skill in this version. Tell your agent to write one from this recipe.
Tip 5.4 — Design the mockup (homepage as image — NOT a real site)
What it does: Generate an image of a homepage tailored to the prospect. Use the business_brief (5.2) for the content, copy, and aesthetic. Use the competitor_refs (5.3) as the quality bar. Output: a single 1920×1080 (or mobile-friendly 1080×1920) image that looks like the homepage their site could have. Why it wins: This is the deliverable. Generating an image — not a real site — keeps the cost at $0.04 per attempt instead of $50+ of engineering tokens. You can iterate 5 times for under a dollar. You can also send 100 of these a week without bankrupting yourself. Tools: OpenAI gpt-image-1 (handles image-input remixing, accepts text prompts up to 4000 tokens), or fal.ai's image-to-image endpoint (cheaper). The competitor screenshots as input references. How to wire it: 1. The prompt template (the agent fills the blanks per business): > "Generate a homepage hero design for [business name], a [exact offer]. Audience: [demographic]. Vibe: [3 adjectives]. Aesthetic: [palette + style]. Reference the composition energy from these competitor sites: [refs]. Don't clone them — match the quality, change the subject. Required elements: business name as the logo, a hero photo that suggests [vibe], a primary CTA ('[appropriate CTA — Book Now / See Menu / Reserve]'), 3 service blurbs, a location map placeholder, social proof. Output: a single homepage hero + first scroll, 1920×1080."
1. Feed the strongest competitor screenshot as image input alongside the prompt (the
"remix this" approach). 2. Generate. Score the output on: does this match the brief's vibe? Is the copy plausible (not lorem ipsum)? Is the CTA right for the offer? Does it look real? 3. If the output is weak (about 20% of attempts), regenerate with a different competitor reference. Don't ship a mid mockup — the whole play depends on it landing. 4. Save the final at /mockups/image-gen. Pattern only — no standalone skill in this version. Tell your agent to write one from this recipe.
Tip 5.5 — DM with the screenshot — "I already made you a site"
What it does: Send the prospect the mockup image with a short message framed as "I already built you a site, here's a sneak peek, would you want to jump on a call so I can show
you the rest." The deliverable carries the pitch. Most cold DMs are talked about; this one shows up with an artifact. Why it wins: A cold message asks the prospect to imagine a future. A cold message with their already-built homepage doesn't ask them to imagine anything — it just shows them. The conversion delta is significant: cold DMs with no deliverable run 1-3% reply; cold DMs with a tailored visual artifact run 8-15%. Tools: Whatever DM channel the prospect actually uses — usually Instagram DMs (for local businesses) or Facebook Messenger, sometimes WhatsApp Business if their Google listing has it, occasionally email if that's all they have. agent-browser for the platforms without an API. Three actually-good DM copy versions: Version 1 — Direct, gift-framed (best for premium niches): Hey [first name] — built [Business] a homepage mockup over coffee this morning. Image attached, no strings. If the direction lands, happy to show you a clickable v1 on a 15-min call this week. If not, keep the image, no follow-up. Version 2 — Short, intrigue-led (best for restaurants, salons, busy operators): Hey — sneak peek of what your homepage could look like 👇 (built it specifically for [Business] based on your IG). 15 min this week if you want me to walk you through the rest? Version 3 — Specific, social-proof anchored (best for higher-tier businesses, dentists, law offices, med spas): Hey [first name] — noticed [Business] doesn't have a site live yet and you've got [Xstar, Y review] reviews. Mocked up what a homepage could look like — attached. Built 4 of these for [niche] in [city] in the last 60 days, [one happy-client one-liner]. 15 min this week to show you the rest? (All three: never use the word "wondering," never apologize for the cold reach-out, never call it a "template" — call it a mockup or sneak peek. Keep the CTA to a 15-min call, not "let me know what you think" — calls book; replies vanish.) How to wire it: 1. Pick the channel per business: Instagram DM if they have an active IG, Facebook Messenger if FB-only, WhatsApp if listed, email last resort. 2. For each business with mockup_status = ready : the agent drafts the right version of the message based on tier (premium → v1, mid → v2, high-trust niche → v3), attaches the mockup image, queues for approval.
- Send via agent-browser against the logged-in platform (no API for IG DMs at smallbusiness volume). 4. Pacing: 10-20 sends per day max per outbound account. IG flags spam fast. 5. Reply detection: any reply pauses the automation for that lead. You take it from there. The conversion path: image → call booked → site quote → close. 6. Track everything in CRM: image sent, reply Y/N, call booked Y/N, closed Y/N. The conversion math at each step matters for tuning. Example prompt to your agent: For each business with mockup_status = ready and outreach_status = pending : pick the right DM channel (IG if active, else FB Messenger, else WhatsApp via Google listing, else email). Pick the right message version (premium → v1, mid → v2, high-trust niche → v3). Personalize the [Business] and [first name] tokens. Attach the mockup image. Queue on Telegram for my approval. On approval, send via agent-browser for IG/FB/WhatsApp, or Gmail API for email. Cap 15 sends/day per outbound account. Log to CRM and creative-outreach-sent.json . On any inbound reply: pause automation, ping me with the reply, tag the lead status = engaged . Watch out for: Don't send the same template to 50 businesses in a row. The agent should rotate phrasing within each version (5-6 micro-variations of v1, v2, v3) so the spam filters don't pattern-match. Instagram aggressively shadow-bans accounts that DM at scale from new profiles. Warm the IG account up: post some real content for 2 weeks first, follow some accounts, engage normally, then start DMing. Don't promise things in the DM that the call can't deliver. "Here's your finished site" is a lie — this is a mockup, not a build. The "show you the rest on a call" framing is honest. Some local businesses are off social entirely. For those, email or even a physical postcard with a printed mockup + QR code is a thing — old school works in this segment. Cultural fit: the directness of v1 plays great in some markets, terribly in others. For Asian markets especially, soften the CTA ("if you'd like, happy to show you"). Skill file: Composite — wires
whatsapp-web+agent-browser+email-followups. Pattern only — no standalone skill in this version. Tell your agent to wire one from these. Cross-link: For the story version of this whole loop (scanner → research → mockup → DM), see Wild Examples #2 — The Site-Mockup Cold DM.
6. Booking Accelerator
This is the section the operator called "the extreme example of how far you can go." Every call that gets booked is an opportunity to walk in with the prospect already impressed. The booking accelerator does that — automatically, every time.
Tip 6.1 — Booking accelerator as a single skill
What it does: The moment any new prospect books a call (Cal.com / Calendly webhook), the agent kicks off an end-to-end pipeline: deep research → build a high-value personalized asset (lead list, audit, mini-report, mockup — whatever fits your offer) → email it to the prospect framed as a welcome gift → CC the team → log to CRM. By the time the prospect walks into the call, they're already impressed. Why it wins: Most sales teams treat the "booked" → "call" gap as dead time. It's the opposite — it's the moment of highest possible impression-per-dollar. A free, personalized, high-effort-looking deliverable lands before the call. The prospect arrives 50% pre-sold and tells everyone at their company "this person built me a [thing] before our call even happened." Tools: Cal.com / Calendly webhook, your research pipeline (Tip 2.3 base), your asset-build skills (mockup designer, lead-list builder, audit builder, whatever you offer), Gmail API, CRM. How to wire it: 1. Webhook on BOOKING_CREATED . Hard rule: first-booking only. Returning prospects don't trigger this — they trigger post-call autopilot (6.3). Query Cal.com API by email; abort if more than one booking exists. 2. Spawn the research subagents (same fan-out as 2.3 — site, LinkedIn, news, tech stack). 3. After research: the agent decides what to build. Default options: - Targeted lead list: 20-50 named leads in their ICP, with notes per lead. Best for salesteam prospects. - Site audit / mini-report: 1-page audit of their site or marketing with 3-5 specific suggestions. Best for marketing prospects. - Homepage mockup: like Section 5. Best for prospects without a real site. - Workflow audit: for ops prospects. - Voice/style analysis: for content prospects. 1. Build it. Save to /demos/
- Email queues on Telegram for your approval. On approval: send via Gmail with the asset attached, CC team, log to CRM, mark booking_accelerator_status = sent . Example email template: Hey [Name], See attached. The moment you booked, my AI agent dug into [Company] and built you [exact asset description]. Then it drafted this email in my voice and dropped it in my drafts for review. Yes — this is my AI agent. Which is a tiny preview of the kind of work we'd do for you. Looking forward to [day, time]. the operator Example prompt to your agent: On every new Cal.com booking webhook: check Cal.com API for prior bookings by that email — if > 1, abort (this is a returning prospect, run post-call-autopilot instead). Otherwise: spawn parallel research (site, LinkedIn, news, tech stack). After research, decide what to build based on what they're likely buying — default to targeted lead list, but mockup for no-site prospects, audit for marketing prospects, workflow doc for ops prospects. Build the asset, save to /demos/
/ . Draft the welcome-gift email using email-voice skill — short, honest that the agent built it, with the asset attached. Queue on Telegram for approval. On approval: send via Gmail, CC [team], log to CRM, mark booking_accelerator_status = sent . Use the _skillsanonymized/booking-accelerator/ skill as the base. Watch out for: First-booking-only rule is critical. If a returning lead triggers this, you'll send them a second "the agent built you something" email and the magic dies. Hard-block. The asset has to be actually good. A mediocre lead list with random companies makes you look worse than no list. If the agent can't confidently build something impressive, fall back to a short, well-researched "here's what I noticed about your business and what I'd want to explore on the call" doc. The honest framing — "yes this is my AI agent" — is the key. People are more impressed when you tell them than when they figure it out. Don't try to hide it. Time-box the build: 5-10 minutes max from booking to email queued. Beyond that, the moment passes (prospects book day-of often). Don't CC the team on the prospect-facing email unless your team norm supports it. Some prospects find a CC awkward. Skill file: booking-accelerator(production-grade skill — directly liftable). Cross-link: For the story version of this play, see Wild Examples #1 — The Booking Accelerator.
Tip 6.2 — Pre-call email auto-sent the night before
What it does: The night before any scheduled call, the agent sends a short, warm "looking forward, here's one thought" email to the prospect. References something specific (from the research pass or the booking form). Reduces no-shows. Sets the conversational tone. Why it wins: No-show rates on cold-booked calls run 30-50% in some niches. A short, personable pre-call email cuts that by half. Plus it pre-frames the conversation so the call doesn't start cold. Tools: Cal.com / Calendly (for the scheduled-calls list), your research from 6.1, Gmail API. How to wire it: 1. Cron at 8pm local each day. List all calls scheduled for tomorrow. 2. For each, check: has a pre-call email already been sent? If yes, skip. If no, generate one. 3. Format — 2-4 sentences, no preamble: > Hey [Name], looking forward to our call at [time] [tz] tomorrow. Had a look at [their company] — sounds like you're dealing with [thing from booking form or research]. Got some ideas on the [your offer] side that should fit. Talk soon. — the operator 1. Queue for approval. On approval, send via Gmail. 2. Track in precall-sent.json . Example prompt to your agent: Every night at 8pm local, list tomorrow's scheduled calls via Cal.com API. For each: if precall-sent.json doesn't have it yet, generate a 2-4 sentence email referencing one specific thing from the prospect's booking-form answers OR their research file. Format: "Hey [Name], looking forward to our call at [time, tz] tomorrow. Had a look at [Company] — sounds like you're dealing with [thing]. Got some ideas on the [my offer] side that should fit. Talk soon. — the operator". Queue all on Telegram in one message. On approval send via Gmail. Log to precall-sent.json . Watch out for: Don't send pre-call emails to prospects who got a booking-accelerator email (6.1) — they already heard from you. One pre-call email is plenty. Time-zone math is brutal — confirm the time in the prospect's TZ when you state it. Some prospects book multiple times back-to-back (sequence of discovery + technical + close). Pre-call email should only fire on the first call of the sequence. Skill file: _skills-anonymized/call-confirmation-emails/ , _skillsanonymized/email-followups/ .
Tip 6.3 — Post-call follow-up cron (Fathom hook → agent drafts thank-you +
next steps)
What it does: The moment a call wraps and the transcript lands in Fathom (usually 5-15 minutes after the call ends), the agent extracts the next steps, drafts a thank-you + recap + clear-next-step email, and queues it for your approval. The follow-up goes out within 30 minutes of the call ending — when the conversation is still fresh in the prospect's head. Why it wins: "I'll send you the recap tomorrow" → tomorrow becomes Friday → Friday becomes Monday → the deal cools. Sending within 30 minutes ties the recap emotionally to the energy of the call. It's also the single highest-conversion follow-up window — reply rates run 60-80%. Tools: Fathom API (poll every 15 min or use a webhook), your email skill, CRM, your postcall-autopilot skill. How to wire it: 1. Poll Fathom every 15 min (or wire up their webhook on transcript-ready). 2. For each new transcript, match to a CRM lead via attendee email. Skip if no match. 3. Extract: top 3 talking points, prospect's primary pain, objections raised, what you committed to, what they committed to, suggested next call timing, suggested follow-up artifact (if you promised to send something). 4. Draft a follow-up email: - Subject: "[Your name] x [Their name] — recap + next steps" - 3 bullet recap of what was discussed (your read, not a transcript dump) - Clear next step: either "I'll send X by [date]" or "want to grab a 30-min next week to dig into Y?" (with booking link) - 2-4 paragraphs total, no fluff. 1. Queue on Telegram. On approval, send via Gmail. CC the team if applicable. 2. If you committed to sending something specific (proposal, lead list, whatever), the agent queues that as a separate follow-up task with a deadline. Example prompt to your agent: Every 15 minutes, poll Fathom for new transcripts since the last run. For each: match to CRM lead via attendee email — skip if no match. Extract top 3 talking points, primary pain, objections, my commitments, their commitments, suggested next-call timing, any artifact I promised. Draft the post-call email — subject "the operator x [Name] — recap + next steps", 3-bullet recap, one clear next step (artifact send-by date OR booking link for next call), 2-4 paragraphs total, use email-voice skill. Queue on Telegram. For any
artifact I committed to, queue a separate task with the agreed deadline. Log everything to CRM. Use _skills-anonymized/post-call-autopilot/ as the base. Watch out for: Wait 5-10 minutes after the Fathom webhook fires before sending — give yourself a window to override anything that got mistranscribed. Mistranscription of names, numbers, and product names is the #1 source of bad recaps. Don't send the recap if the call was clearly a no-go for either side (the prospect ended it abruptly, you decided they're not ICP). The agent should detect those signals from transcript tone and pause — flag to you instead of auto-drafting. Keep the recap short. Bullet point > paragraph. Prospects re-read recaps later; longform is friction. The "I'll send you X by Y" promise creates an auditable trail — if you don't ship X by Y, the agent will flag it in the follow-up sweep (3.1's PROMISE BROKEN bucket). Don't promise what you won't deliver. Skill file: _skills-anonymized/post-call-autopilot/ (production skill), _skillsanonymized/fathom-transcripts/ .
How it all stacks
Sales automation is more channel-dependent than marketing. The marketing stack works whether you have 1 channel or 5 — content distributes wherever you point it. Sales requires actual coverage of every surface a deal moves through. The order to install:
Channel connections first (Tip 1.1). Without read access to every channel a prospect uses, nothing else works. This is the boring foundation. Do it on day one even if it takes a week.
CRM consolidation (1.3). Get to one CRM. Don't proceed until you're there.
Voice skills per channel (1.2). Need at least your top 2 (probably email + WhatsApp). The rest can come over the first month.
Lead-status skill (2.1). The first "wow this is real" demo of having the channels wired. You'll use it daily.
Pre-call research on booking (2.3) and booking accelerator (6.1). These two ship together — the moment you have prospects booking real calls, you want both.
Note-taker connection + post-call follow-up (2.2, 6.3). Now the loop closes: book → research → call → recap → CRM.
Follow-up sweep on cron (3.1, 3.2, 3.3). This is when you stop losing deals to ghosting.
Apollo pipeline (4.1-4.5). Once the inbound infrastructure is rock-solid, turn on outbound. Not before — outbound generates volume, which exposes every gap in your inbound handling. 9. Creative outreach (5.1-5.5). Last because it's a different ICP entirely. Add it as a parallel channel once the rest of the stack hums. A common mistake: starting with outbound (Apollo, creative outreach) because it feels like "real sales." Resist it. Outbound without follow-up infrastructure ends with leads ghosted three weeks in and a $4k Apollo subscription gathering dust. Inbound discipline first. Outbound volume second. Don't try to ship all 24 tips in a month. Pick the three highest-leverage ones for your current funnel: No CRM, leads everywhere → Tip 1.1 + 1.3 + 2.1. Three weeks of work. Transforms how every other deal feels. CRM exists, deals dying in follow-up → Tip 3.1 + 3.2 + 3.3. One week of work. Highest single ROI in this whole document. Inbound humming, want to scale outbound → Tip 4.1 + 4.3 + 4.5. Two weeks of setup, then a month of tuning, then it prints. You sell into local SMBs without sites → Tip 5.1 → 5.5. The most fun build in the whole cookbook. The agent is here to ensure no deal dies because you got busy. Build the stack accordingly.
Ops
Newsletter
Get the next one in your inbox.
One short email a week. Operator takes on AI agents, no hype.