Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,79 @@



# Templates

Starter cold-email templates live in [`/templates`](./templates). Each file is
a single ICP × purpose combination — pick the closest match, swap the variables,
adapt the body in your own voice. Bodies are 80–140 words, plain text, no
buzzword soup.

The current set:

| File | ICP | Purpose |
| --- | --- | --- |
| `devtools-cold-intro.json` | Engineering manager / staff engineer | Book a 15-min product demo |
| `b2b-saas-cold-intro.json` | Head of RevOps / Sales Ops | Land a 20-min discovery call |
| `agency-services-pitch.json` | Founder / marketing lead | Open a paid-engagement conversation |
| `recruiter-candidate-outreach.json` | Senior / staff engineer | Book an exploratory call |
| `fundraising-warm-intro.json` | Friend / advisor (forwardable to investor) | Get a warm intro to a specific VC |
| `partnership-pitch.json` | Partnerships lead at adjacent product | Explore co-marketing or integration |
| `customer-research-interview.json` | Anyone in your ICP | Book a 20-min discovery interview |
| `lapsed-lead-revive.json` | Prospect silent 30+ days | Re-open the conversation |

## Template JSON shape

```json
{
"id": "devtools-cold-intro",
"name": "Devtools cold intro",
"icp": "Engineering manager / staff engineer at series A–C startups",
"purpose": "Book a 15-min product demo",
"subjectLines": ["...", "..."],
"body": "Hi {{firstName}}, ...",
"variables": [
{"key": "firstName", "required": true},
{"key": "company", "required": true},
{"key": "specificObservation", "required": false, "note": "Something specific you noticed about their product or recent post."}
],
"notes": "Why this template works, when to use it, what to swap.",
"license": "MIT"
}
```

Fields:

- `id` — kebab-case identifier; matches the filename.
- `name` — human-readable label for pickers.
- `icp` — who this is aimed at.
- `purpose` — the single outcome the email is trying to produce.
- `subjectLines` — 2–3 variants. Test before scaling.
- `body` — plain text, `{{var}}` placeholders, no HTML.
- `variables` — every placeholder used in `subjectLines` or `body`. `required: true` means the email shouldn't go without it; `required: false` means it's worth using if you have it. Use the optional `note` field to coach senders on what makes a good value.
- `notes` — when to use, when not to, what tends to break.
- `license` — usage license. All starters ship as MIT.

## How to use a template

Today, templates are content-only. Pick one, copy the `body` and one of the
`subjectLines` into the compose UI, and substitute your variables by hand.

Wiring `templates/` directly into the compose UI as a picker is a follow-up —
see the parent plan in HIR-105, or open an issue if you want it sooner.

## Contributing a template

PRs welcome. Keep new templates aligned with the conventions:

- One ICP × purpose per file.
- 80–140 word body, plain text, no jargon.
- 2–3 subject line variants.
- Document every variable, including a `note` for non-obvious ones.
- `notes` should explain *why* the template works and what to watch out for.
- All starters in this repo are MIT-licensed.



# Move the needle TO-DO list:

- [x] Templates for popular email needs i.e "onboarding for SaaS" — see `/templates`
Expand Down
29 changes: 29 additions & 0 deletions templates/agency-services-pitch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"id": "agency-services-pitch",
"name": "Agency reaching out to founders",
"icp": "Founder or marketing lead at a seed–series B startup",
"purpose": "Open a conversation about a paid engagement",
"subjectLines": [
"{{specificObservation}} — one idea",
"{{company}}'s {{channelOrChannel}} — quick thought",
"Not a pitch, just one observation about {{company}}"
],
"body": "Hi {{firstName}},\n\n{{specificObservation}}. Spent ten minutes looking through {{company}}'s {{channelOrChannel}} this morning and one thing jumped out: {{specificFinding}}.\n\nWe run a small {{agencyType}} agency — five people, ex-{{founderBackground}}. Most of our clients are at the same stage as {{company}}. Recent example: helped {{customerExampleA}} take {{metric}} from {{beforeMetric}} to {{afterMetric}} over {{timeframe}}.\n\nNo deck, no discovery call upfront. If it's useful, I'll send a free 2-page write-up of what I'd actually change about {{specificFinding}}. If you want to talk after that, great. If not, no follow-up.\n\nFair?\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true},
{"key": "company", "required": true},
{"key": "specificObservation", "required": true, "note": "Open with something genuine — a recent launch, a hiring move, a product decision."},
{"key": "channelOrChannel", "required": true, "note": "The actual channel you reviewed. e.g. 'landing page', 'paid search ads', 'cold email sequence'."},
{"key": "specificFinding", "required": true, "note": "One concrete observation. Not 'your funnel could be tighter.' Try 'your pricing page hides the ICP-specific copy below the fold.'"},
{"key": "agencyType", "required": true, "note": "e.g. 'growth', 'content', 'paid acquisition'."},
{"key": "founderBackground", "required": false, "note": "Where the team came from. e.g. 'Stripe + HubSpot'. Skip if not credible."},
{"key": "customerExampleA", "required": false},
{"key": "metric", "required": false},
{"key": "beforeMetric", "required": false},
{"key": "afterMetric", "required": false},
{"key": "timeframe", "required": false},
{"key": "senderFirstName", "required": true}
],
"notes": "Founders get pitched constantly by agencies and the bar is high. The differentiator is offering free, specific work upfront — the 2-page write-up. Only use this if you'll actually deliver one. The 'no follow-up' line is a contract; honor it. If you can't fill in customerExampleA truthfully, delete that sentence and lean harder on the specific finding.",
"license": "MIT"
}
28 changes: 28 additions & 0 deletions templates/b2b-saas-cold-intro.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"id": "b2b-saas-cold-intro",
"name": "B2B SaaS cold intro to ops/RevOps",
"icp": "Head of RevOps, Sales Ops, or BizOps at a 50–500-person B2B SaaS",
"purpose": "Land a 20-min call to walk through the pain and see if the product fits",
"subjectLines": [
"{{company}} + {{painPoint}}",
"Quick one for the {{company}} ops team",
"Saw the {{specificObservation}} — curious how it's going"
],
"body": "Hi {{firstName}},\n\nNoticed {{specificObservation}}. Usually when a team gets to that stage, {{painPoint}} starts eating an unreasonable amount of the ops team's week.\n\nWe built {{productName}} to fix that one specific thing. {{customerExampleA}} cut their {{metric}} from {{beforeMetric}} to {{afterMetric}} in {{timeframe}}, with no extra headcount.\n\nNot trying to replace your stack. It plugs into {{integrationStack}} and runs alongside what you already have.\n\nIf the timing's right, I can show you the {{customerExampleA}} setup in 20 minutes — happy to send the recording instead if a live call is too much.\n\nWorth a conversation?\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true},
{"key": "company", "required": true},
{"key": "specificObservation", "required": true, "note": "A signal: hiring a RevOps role, recent funding, a podcast appearance, a tool migration. Avoid generic 'congrats on the growth.'"},
{"key": "painPoint", "required": true, "note": "The pain in their language. e.g. 'lead routing latency', 'pipeline hygiene', 'attribution gaps'."},
{"key": "productName", "required": true},
{"key": "customerExampleA", "required": false, "note": "Use only if you have permission. Otherwise drop the case-study sentence and rewrite around the product."},
{"key": "metric", "required": false, "note": "The metric that moved. e.g. 'lead-to-meeting conversion', 'time-to-first-touch'."},
{"key": "beforeMetric", "required": false},
{"key": "afterMetric", "required": false},
{"key": "timeframe", "required": false},
{"key": "integrationStack", "required": true, "note": "The 1–2 tools they almost certainly already use. e.g. 'Salesforce + Outreach'."},
{"key": "senderFirstName", "required": true}
],
"notes": "RevOps people are skeptical of cold email by trade — they read these for a living. The win here is being concrete: name the pain, name the metric, name the tools you integrate with, and offer a recording instead of a call. Drop the case-study paragraph entirely if you can't substantiate it; a vague claim is worse than no claim.",
"license": "MIT"
}
24 changes: 24 additions & 0 deletions templates/customer-research-interview.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": "customer-research-interview",
"name": "Customer research / discovery interview ask",
"icp": "Person in your target ICP — could be a current user, a churned user, or a non-user who fits the profile",
"purpose": "Book a 20-minute discovery call",
"subjectLines": [
"20 minutes on {{topicArea}}?",
"Quick research request — {{topicArea}}",
"Picking your brain on {{topicArea}}"
],
"body": "Hi {{firstName}},\n\nShort one. We're doing customer research at {{yourCompany}} on how {{icpDescription}} actually handle {{topicArea}} day-to-day. You came up because of {{specificReason}}.\n\nI'm not selling anything on this call. I'm trying to understand:\n- How you currently handle {{topicArea}}\n- Where the process breaks or feels heavy\n- What 'good' would look like for you\n\n20 minutes, video off if you'd rather. Happy to share what we learn from the full set of interviews — most people we talk to find the cross-cut more useful than their individual call.\n\nAs a thank-you, {{thankYouOffer}}.\n\nIf you're up for it, here's my calendar: {{calendarLink}}. Or just reply with two times that work and I'll send an invite.\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true},
{"key": "yourCompany", "required": true},
{"key": "icpDescription", "required": true, "note": "How you'd describe their role/situation. e.g. 'engineering managers at series A startups'."},
{"key": "topicArea", "required": true, "note": "The narrow topic. e.g. 'sprint planning', 'incident response', 'pipeline forecasting'."},
{"key": "specificReason", "required": true, "note": "Why this person specifically. e.g. 'a referral from {{referrerName}}' or 'your recent post on X.'"},
{"key": "thankYouOffer", "required": false, "note": "e.g. 'a $50 Amazon gift card', 'a copy of the full research summary', 'a free year of {{productName}}.' Drop the line if you don't have one."},
{"key": "calendarLink", "required": true},
{"key": "senderFirstName", "required": true}
],
"notes": "The single biggest mistake in research outreach is making it sound like a sales call. Be explicit that it isn't. The promise to share what you learn is the most underrated incentive — it works better than gift cards on senior people. The bullet list of what you'll ask is reassuring; vague 'pick your brain' asks get archived.",
"license": "MIT"
}
25 changes: 25 additions & 0 deletions templates/devtools-cold-intro.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"id": "devtools-cold-intro",
"name": "Devtools cold intro",
"icp": "Engineering manager / staff engineer at series A–C startups",
"purpose": "Book a 15-min product demo",
"subjectLines": [
"{{specificObservation}} — quick question",
"How {{company}} handles {{painPoint}}",
"15 min on {{painPoint}} at {{company}}?"
],
"body": "Hi {{firstName}},\n\nI saw {{specificObservation}} — that resonated because most teams I talk to are dealing with {{painPoint}} around the same growth stage.\n\nI'm building {{productName}}. It's a {{oneLineDescription}}. Engineering teams at {{customerExampleA}} and {{customerExampleB}} use it to cut {{painPoint}} cycles roughly in half.\n\nNot trying to pitch a platform. If it's relevant, I can share a 5-minute Loom of how a team your size set it up — no demo call needed. If you'd rather just try it, the docs are public and there's a free tier with no card.\n\nWorth a look?\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true},
{"key": "company", "required": true},
{"key": "specificObservation", "required": true, "note": "Something concrete: a recent post, a job listing, a talk, a repo. Avoid 'I saw your company is growing fast.'"},
{"key": "painPoint", "required": true, "note": "The narrow problem your product solves, in their words. e.g. 'flaky CI', 'slow PR reviews'."},
{"key": "productName", "required": true},
{"key": "oneLineDescription", "required": true, "note": "One sentence, no jargon. e.g. 'CI cache layer that cuts test times by skipping unchanged files.'"},
{"key": "customerExampleA", "required": false, "note": "A recognizable customer name if you have permission to share."},
{"key": "customerExampleB", "required": false},
{"key": "senderFirstName", "required": true}
],
"notes": "Works because it leads with a specific observation, names the pain in their language, and removes the friction of a demo call by offering a Loom. Skip the customer logos line if you don't have permission to use names. The free-tier mention only works if you actually have a free tier; otherwise drop that sentence.",
"license": "MIT"
}
31 changes: 31 additions & 0 deletions templates/fundraising-warm-intro.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"id": "fundraising-warm-intro",
"name": "Founder asking for an intro to an investor",
"icp": "Friend, advisor, or prior coworker who knows the target investor personally",
"purpose": "Get a forwardable intro to a specific investor",
"subjectLines": [
"Quick intro ask — {{investorName}}",
"Would you mind forwarding this to {{investorFirstName}}?",
"{{companyName}} fundraise — small ask"
],
"body": "Hey {{firstName}},\n\nQuick ask. We're raising a {{roundType}} for {{companyName}} and {{investorName}} at {{investorFirm}} is at the top of our list — they led {{relevantPortfolioCo}}, which is the closest analogue to what we're building.\n\nWould you be open to forwarding the note below? Totally fine to say no or to add caveats.\n\n---\n\nHi {{investorFirstName}},\n\n{{introducerFirstName}} suggested I reach out. I'm {{senderFirstName}}, founder of {{companyName}}. We're building {{oneLineDescription}}.\n\nQuick traction snapshot: {{tractionMetric1}} and {{tractionMetric2}}. We're raising a {{roundSize}} {{roundType}} to {{useOfFunds}}.\n\nGiven your work with {{relevantPortfolioCo}}, I think you'd see the angle quickly. Open to a 20-min call in the next two weeks?\n\n{{senderFirstName}}\n{{deckLinkOrNote}}\n\n---\n\nThanks for considering it, {{firstName}} — and totally no pressure either way.\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true, "note": "The introducer's first name."},
{"key": "companyName", "required": true},
{"key": "roundType", "required": true, "note": "e.g. 'pre-seed', 'seed', 'Series A bridge'."},
{"key": "roundSize", "required": true, "note": "e.g. '$2M', '$8M'."},
{"key": "investorName", "required": true, "note": "Full name."},
{"key": "investorFirstName", "required": true},
{"key": "investorFirm", "required": true},
{"key": "relevantPortfolioCo", "required": true, "note": "A specific portfolio company that maps to your space. Be honest about the analogue."},
{"key": "introducerFirstName", "required": true, "note": "Same as firstName, repeated for the forwarded note."},
{"key": "senderFirstName", "required": true},
{"key": "oneLineDescription", "required": true, "note": "Plain English. No 'AI-powered platform.' One sentence."},
{"key": "tractionMetric1", "required": true, "note": "Real numbers. e.g. '$22k MRR, 18% MoM growth'."},
{"key": "tractionMetric2", "required": true},
{"key": "useOfFunds", "required": true, "note": "What the money buys. e.g. 'extend runway 18 months and hire two engineers'."},
{"key": "deckLinkOrNote", "required": false, "note": "Either a link to a 5-slide deck, or 'happy to send the deck after the call.'"}
],
"notes": "The forwardable note is the whole point — it has to stand on its own without the original wrapper. Investors evaluate the forwarded note in 30 seconds. The traction numbers should be specific and recent (last 30 days). Always give the introducer an out — don't make them feel obligated. If the investor doesn't actually map to your space, this template is a waste of a warm contact.",
"license": "MIT"
}
23 changes: 23 additions & 0 deletions templates/lapsed-lead-revive.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"id": "lapsed-lead-revive",
"name": "Re-engaging a prospect who went silent 30+ days ago",
"icp": "A prospect who replied at least once and then went quiet 30+ days ago",
"purpose": "Re-open the conversation without sounding desperate",
"subjectLines": [
"Should I close the loop on this?",
"{{painPoint}} — still on your radar?",
"Quick check-in, {{firstName}}"
],
"body": "Hi {{firstName}},\n\nLast time we talked you mentioned {{quotedPainOrContext}}. I assumed it got deprioritized — totally understand, things shift.\n\nTwo reasons I'm following up now:\n\n1. {{newReason}} — felt relevant given what you said.\n2. I'd rather close the loop than leave it hanging. If this isn't a {{currentQuarter}} priority, just tell me and I'll stop following up.\n\nIf it is back on the radar, the change since we last talked: {{productOrCompanyUpdate}}.\n\nWhich is it — paused, dead, or still interesting?\n\n{{senderFirstName}}",
"variables": [
{"key": "firstName", "required": true},
{"key": "painPoint", "required": false, "note": "Used in one of the subject lines only. The pain in their language from the original conversation. e.g. 'lead routing latency'. Pick a different subject if you don't have one."},
{"key": "quotedPainOrContext", "required": true, "note": "Quote them as closely as you can. e.g. 'you wanted to revisit after the Q1 board meeting' or 'you mentioned your team was buried in a migration.' Specificity proves you remember the conversation."},
{"key": "newReason", "required": true, "note": "A genuine new reason. e.g. 'we just shipped the Salesforce integration you asked about', 'we cut pricing for teams under 50.' If there's no new reason, this template doesn't work — wait until there is one."},
{"key": "currentQuarter", "required": true, "note": "e.g. 'Q2', 'this quarter', 'before the half'."},
{"key": "productOrCompanyUpdate", "required": false, "note": "Optional second hook. e.g. 'we hired a CS lead from notableCompany.' Skip if redundant with newReason."},
{"key": "senderFirstName", "required": true}
],
"notes": "The 'paused, dead, or still interesting?' close is the workhorse of this template — it gives the prospect three legitimate options instead of guilting them into a yes. The quoted pain is what makes it land; if you can't remember what they said, go read the thread before sending. Don't send this template more than once per lapsed lead — if they don't respond, mark them dead and move on.",
"license": "MIT"
}
Loading