Paitho
← Product / Stage 08 · Email Drafted
Pipeline · Stage 08

A real email.
Not a merge field.

Claude Sonnet writes subject, body, and signoff from the pitch brief and the pack's tone profile. Refuses to draft if the required facts aren't there. No fallback to "Hi {{firstName}}".

What goes in, what comes out.

Inputs
Brief + Brand
  • lead.pitchBrief — opener, painAngle1/2, namedLeaders, specificObservation
  • lead.enrichment.contacts[0] — addressed person + verified email
  • pack.brand — voice profile (devtools-blunt, fintech-formal, etc.)
  • pack.creditLinks[] — top-3 audience-matched blog/case-study URLs
  • draft.languageen | de | es (extensible per pack)
  • workspace.signature — your block, your sender
Outputs
email_draft
  • email_draft.subject — <= 9 words, no clickbait, no emoji
  • email_draft.body — 110–170 words, 3 paragraphs
  • email_draft.cta — single-question close, never "are you the right person"
  • email_draft.creditLink — chosen blog URL with rationale
  • email_draft.signoff — workspace signature
  • email_draft.refusal — if required input missing, why
  • email_draft.email_prompt_id — back-link for funnel attribution
Hard contract: missing pitchBrief.specificObservation → refusal

Brand-aware.
Pack-tuned. Refuses-on-gap.

— pack.brand.tone marketing
voice: warm, specific
forbidden: "synergy", "leverage", "10x"
openerStyle: observation-first
ctaStyle: one-question close
maxWords: 170

The draft is composed once, by Claude Sonnet, from the structured pitch brief produced upstream and the pack's brand profile. It is not a template with merge fields. The model is given the named leader, the specific observation, the two pain angles, the chosen credit link, and the brand voice constraints. It writes a subject line, three short paragraphs, and a one-question CTA. The tone is the pack's. The facts are the lead's. The output is unique enough to read like a senior-rep email.

Required-input refusal is the contract. If pitchBrief.specificObservation is null, the draft never fires — the lead is parked in a awaiting_facts column instead, with a note saying which input was missing. The system would rather stall than ship a generic email. This is the difference between a tool that "always produces something" and a tool that produces something worth sending. Reviewers see refusals; they don't see filler.

Language selection is per-draft, not per-pack. Most packs default to English, but the marketing pack often runs in German or Spanish for European clients. The model is given the pack's brand profile and the chosen language; it writes in that language with the same tone constraints applied. Credit links are picked from a pre-curated set for that pack — no inventing a URL. Every draft is attributed back to a versioned prompt id so reply-rate compares cleanly across copy variants downstream.

Hard input contract. Brand-bound voice.

prompt · email_draft_v19 · marketing +
--- system ---
You write a single B2B outbound email. Use ONLY the facts provided.
NEVER invent a fact, a metric, or a person. If specificObservation
is null, refuse: return refusal: "missing_specific_observation".

Brand voice: {{pack.brand.voice}}
Forbidden words: {{pack.brand.forbidden | json}}
CTA style: {{pack.brand.ctaStyle}}
Language: {{draft.language}}    # en | de | es

--- inputs ---
contact:        {{lead.enrichment.contacts[0] | json}}
pitchBrief:     {{lead.pitchBrief | json}}
creditLinks:    {{pack.creditLinks | json}}    # pre-curated, top 3
signature:      {{workspace.signature}}

--- output schema ---
{
  "subject":     string,    # <=9 words, no emoji
  "body":        string,    # 110–170 words, 3 paragraphs
  "cta":         string,    # single question
  "creditLink":  { url: string, rationale: string },
  "signoff":     string,
  "refusal":     string|null
}

--- guards ---
- The first paragraph must reference specificObservation by quote.
- The CTA must NOT ask "are you the right person".
- creditLink MUST be from creditLinks[]. No fabrication.

# <!-- PLACEHOLDER — full prompt registry available in app -->

What can break.
And what catches it.

Risk
Hallucinated metric

Email cites a stat about the lead the model invented to sound specific.

Mitigation

Inputs are typed and field-named. Numeric claims must be present in pitchBrief; post-draft validator scrubs any number not in the input set.

Risk
Generic-template drift

Drafts converge on similar phrasing across leads.

Mitigation

Per-pack n-gram saturation alert. Repeated openers across leads in a window are flagged for prompt-team review and trigger a version bump.

Risk
Wrong-language drift

Draft is requested in German, returns in English with a German signoff.

Mitigation

Output is run through a language-detect post-check; mismatches trigger a regenerate pass at higher constraint or surface the lead to manual triage.

Draft a real email.
In a sandbox, in 2 minutes.

Pick a pack. See subject, body, and CTA generated from real facts.