How to Build an AI Content Generator for Marketing Emails
Generate marketing email copy at scale using AI with your brand voice.
What This Integration Does
This workflow turns a short campaign brief (product, audience, goal) into a complete marketing email - subject line, preheader, body HTML, and CTA - written in your brand voice. It pulls brand guidelines and prior-campaign context from a Knowledge node so the model isn't generating in a vacuum, then routes the draft through a human approval step before pushing the final copy to Klaviyo or Resend for sending.
It's typically invoked manually (a marketer fills in a form that hits a webhook) but can also run from a campaign-planning Monday board or be triggered on a schedule for recurring sends like weekly newsletters.
Prerequisites
- A workspace LLM provider configured (Claude or GPT do well on long-form copy).
- A Spojit Knowledge base seeded with your brand guidelines, voice samples, and a few high-performing past emails.
- A klaviyo or resend connection for sending.
- A slack connection for the approval handoff (optional but recommended).
Step 1: Trigger with the Campaign Brief
Drop a Trigger node set to Webhook (so a form or internal tool can post a brief) or Manual for one-offs. The payload should carry at least:
{
"product": "Pro plan",
"audience": "trial users 7+ days in",
"goal": "drive upgrade",
"tone": "friendly, slightly urgent",
"segmentId": "klaviyo_segment_abc123"
}
Step 2: Pull Brand and Performance Context
Add a Knowledge node that queries the brand guidelines knowledge base with a query like "brand voice, banned phrases, CTA style for {{ trigger.body.audience }}". In parallel, add a Connector node on klaviyo / list-campaigns filtered to the last 30 days; pass the open and click rates into the generation step so the model can "lean into what worked".
Step 3: Generate the Email with Structured Output
Add a Connector node configured as a tool-augmented LLM call. Provide the brief, the brand context, and the recent-campaign stats. Define the Structured Output schema:
{
"type": "object",
"properties": {
"subjectLine": { "type": "string", "maxLength": 60 },
"preheader": { "type": "string", "maxLength": 100 },
"bodyHtml": { "type": "string" },
"ctaText": { "type": "string", "maxLength": 30 },
"ctaUrl": { "type": "string" },
"altSubjects": { "type": "array", "items": { "type": "string" }, "minItems": 2, "maxItems": 4 }
},
"required": ["subjectLine", "preheader", "bodyHtml", "ctaText", "ctaUrl"]
}
The altSubjects array gives you ready-made A/B variants.
Step 4: Render and Lint the HTML
Add a Transform node to inject your standard header and footer around bodyHtml. Then run a quick check with regex / test to flag risky patterns (raw http:// links, missing alt attributes on images, empty <a> hrefs). Bad output bounces back to the model with a corrective re-prompt rather than reaching a human.
Step 5: Human Approval
Add a Human node that surfaces the full preview (subject line, preheader, rendered HTML, CTA URL) to a marketer. They can approve, reject, or edit. In parallel, post a Slack message via slack / send-message to the marketing channel with a link to the approval task - useful for handoff visibility.
Step 6: Send via Klaviyo or Resend
Add a Condition node on the human's decision. On approve, send through your email platform:
- Klaviyo path: call klaviyo /
create-eventor push the segment viaadd-profiles-to-list, then trigger the campaign send via your Klaviyo flow. - Resend path: call resend /
send-batch-emailswith the recipient list and rendered HTML.
On reject, write the brief and the rejected draft to a Mongo collection so you can refine the prompt later.
Tips
- Seed the Knowledge base properly. Three or four exemplar emails do more for voice consistency than any amount of prompt engineering.
- Give the model the brief, not the prompt. Marketers shouldn't have to write prompts. A short structured form is enough.
- Cap subject length in the schema. Long subject lines get truncated on mobile. The
maxLengthin the JSON schema makes the model self-enforce.
Common Pitfalls
- Generic copy. Without brand context the model produces fine-but-bland writing. The Knowledge node is the difference between "AI copy" and "your copy".
- Banned phrases leaking through. Add a final regex pass on
bodyHtmlagainst your banned-phrase list and require a human edit if any match. - Mobile rendering. Test on at least one mobile email client before broad send; the model can produce HTML that looks fine on desktop but breaks on Gmail mobile.
- Compliance. Promotional emails need a working unsubscribe link. Make the footer template a hard-coded part of the Transform step, not something the model can edit.
Testing
Run the workflow end-to-end with a 5-person internal test segment first. Check the rendering across three mail clients (Gmail web, Gmail mobile, Outlook), confirm the CTA URL resolves, and verify the Klaviyo or Resend send actually fired. Iterate on the prompt until two consecutive runs produce copy you'd happily send before opening it up to the main marketer.