Recipes
The three messaging modes Hogsend gives you — transactional, lifecycle, and marketing — plus the two data primitives that drive them. Real, copy-pasteable how-tos.
Hogsend sends mail in three modes — transactional, lifecycle, and marketing — and each one is a first-class primitive you reach for directly in code. The logic lives in your repo as TypeScript, not behind a builder UI. These recipes are real, copy-pasteable how-tos: the exact Hogsend call for each job, plus the data primitives that feed all three.
The three messaging modes
| Mode | What it is | Hogsend primitive |
|---|---|---|
| Transactional | One-off, system-triggered mail to a single person — verify your email, reset your password, a receipt | hs.emails.send() → POST /v1/emails |
| Lifecycle | Multi-step, behaviour-driven sequences — onboarding, trial nudges, win-back | defineJourney() — durable TypeScript |
| Marketing | A one-time broadcast of one template to an audience | hs.campaigns.send() → POST /v1/campaigns |
Underneath all three, two more primitives carry the data that drives everything:
hs.contacts.upsert()— the durable contact record: who someone is.hs.events.send()— the behaviour stream that triggers journeys: what they just did.
Which primitive do I reach for?
Sending one email to one person because the system did something?
→ hs.emails.send() (transactional) recipes/transactional-emails
Reacting to behaviour over time, with delays and branches?
→ defineJourney() (lifecycle) recipes/lifecycle-journeys
Blasting one template to a whole audience, once?
→ hs.campaigns.send() (marketing) recipes/marketing-campaigns
Recording who someone is, or what they just did?
→ hs.contacts.upsert() / hs.events.send() recipes/events-and-contactsHow the pieces fit
A single signup touches every primitive: you upsert a contact (who they are), events.send a user.signed_up event (what they did, which triggers the onboarding journey), and emails.send a transactional verify-email. From there the journey takes over, buckets re-segment as contact properties change, and you can broadcast a campaign to anyone subscribed to a list.
// 1. who they are
await hs.contacts.upsert({ email, userId, properties: { plan: "free" } });
// 2. what they did — triggers the onboarding journey
await hs.events.send({ name: "user.signed_up", userId, eventProperties: { source: "web" } });
// 3. a one-off transactional email
await hs.emails.send({ to: email, template: "transactional/verify-email", props: { verifyUrl } });What you get across all three modes
Three guarantees that hold for every send Hogsend makes, and that show up throughout these recipes:
- Typed templates.
templateandpropsare type-checked against your own React Email registry — a renamed or missing prop is a build failure, not a broken email in production. - Automatic tracking. Every send — including one-off transactional — flows through the same tracked mailer, so opens and clicks are recorded and loop back into the engine as events that can trigger journeys or move bucket membership.
- The property split.
contactProperties(who they are) andeventProperties(what happened) are separate bags — see Events & contacts.
The four modes
Start here — one recipe per messaging mode, plus the data primitives that feed them:
All four use the typed @hogsend/client SDK. The underlying HTTP endpoints are documented in the Data API reference; journeys are documented in the Journeys guide.
The catalog
Every recipe below is a complete flow — trigger events, the full journey (or task), the wiring, and the invariants that make it hold in production.
Onboarding & activation
Welcome series
Greet on signup, resume the instant they activate, nudge only if they don't.
Activation milestones
Track setup as milestones and nudge exactly the step where someone stalls.
Waitlist launch
Collect a waitlist, broadcast on launch day, chase non-activators.
Verification chase
Re-send the verify email up to twice, stopping the moment they verify.
Trial, billing & upgrades
Trial conversion sequence
The full trial arc — value email, usage branch, expiry reminders, exit on payment.
Failed payment dunning
Stripe webhook in, escalating retries, human escalation on final failure.
Usage-limit upgrade
Nudge at 80% of plan limits, again at 100%, once per period.
Cancellation save
A reason survey via semantic links, with a save offer per answer.
E-commerce
Abandoned cart recovery
Race the purchase: two reminders at most, zero sends after checkout completes.
Post-purchase series
Receipt, product onboarding, and a hand-off to the review request.
Review request
A rating via semantic links — public-review ask or support alert, by score.
Back in stock
Per-product waitlists and an idempotent restock broadcast.
Retention & engagement
Win-back and sunset
Win back dormant users, then ask permission to keep sending — and honour the answer.
NPS survey
Quarterly score via semantic links; detractors page a human, promoters get the referral ask.
Weekly digest
A cron Hatchet task that computes per-user digests — and why it isn't a journey.
Anniversary emails
Yearly re-entry, landed at a local morning with ctx.when.
Timing & scheduling
Timezone-aware scheduling
The ctx.when cookbook — local times, send windows, and the timezone resolution chain.
Event reminder sequence
T-24h and T-1h reminders computed from the registration event, plus an attended branch.
Human-in-the-loop
Lead alerts
A hand-raise flags a lead; a task resolves identity server-side and pages the operator.
Human approval gate
The journey parks on waitForEvent until an operator fires the approval event.
Concierge onboarding
High-value signups alert a CSM and the journey tracks the human follow-through.
Support follow-up
Did this fix it? One tap answers route to reopen-plus-alert or a quiet close.
Agents & AI
Agent-triggered journeys
Agents enroll users through the same idempotent events API your app uses.
AI-drafted sends
An LLM fills typed template props; the template stays code-owned and reviewed.
Agent feedback loop
Answers fan out to your agent via a destination; its verdict resumes the journey.
AI-personalised onboarding
generateObject drafts typed email slots from a user-context bundle; the template owns all markup.
AI next-best action
generateText with tools lets the model pull history mid-reasoning and commit a typed send decision.
Pipelines & orchestration
PostHog-triggered journeys
The production PostHog webhook source — echo guard, identity guard, property split.
Cross-journey funnels
Journeys route into journeys with eligibility events instead of growing into monoliths.
Lifecycle alerts in Slack
One filtered destination decides which lifecycle moments page a human.
MCP server
The @hogsend/mcp server exposes a running Hogsend instance to MCP clients — Claude Desktop, Cursor, and claude.ai connectors — with three tools (manage_blueprint, hogsend_report, send_test_email), the blueprint authoring-guide resource, and the find_and_fix_bottleneck prompt. It runs over stdio via npx or as a consumer-mounted Streamable HTTP route at POST /v1/mcp, and every call is admin-gated with the operator's own full-admin key.
Transactional emails
Send a transactional email with hs.emails.send({ to, template, props }). Verify-email, password-reset, magic-link, and receipt — with typed props, automatic tracking, and unsubscribe handling.