Recipe

Drip / onboarding sequence

A series of 4-7 emails sent on a schedule after a user signs up. Each email teaches one feature, drives one action, and primes the next. Average open rates: 35-50% on Day 1, 15-25% by Day 7.

The classic 5-email arc

#WhenSubject patternGoal
1Right after signupWelcome, {first_name}Confirm signup; one CTA: complete profile
2+24hDid you try {feature}?Drive the activation event
3+72hThe story of why we built thisBuild emotional connection
4+1 weekWhat other users do in their first weekSocial proof + use cases
5+2 weeksShould we keep emailing you?Confirm engagement; trim non-engaged

SendBolt wiring

SendBolt's sequences feature handles the scheduling. Define the sequence once at /dashboard/sequences:

curl -X POST "$API/api/v1/sequences" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Onboarding (5 emails)",
    "trigger": "signup",
    "steps": [
      {"day_offset": 0,  "template_id": "tpl_welcome",      "send_hour_utc": null},
      {"day_offset": 1,  "template_id": "tpl_activation",   "send_hour_utc": 13},
      {"day_offset": 3,  "template_id": "tpl_origin_story", "send_hour_utc": 13},
      {"day_offset": 7,  "template_id": "tpl_case_studies", "send_hour_utc": 13},
      {"day_offset": 14, "template_id": "tpl_engagement_check","send_hour_utc": 13}
    ]
  }'

Enroll a user

await fetch(`${API}/api/v1/sequences/${SEQ_ID}/enroll`, {
  method: "POST",
  headers: { "Authorization": `Bearer ${KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    contact_email: user.email,
    contact_first_name: user.firstName,
    start_at: new Date().toISOString(),
    extra_vars: { activated_feature: null },
  }),
});

Conditional skip rules

A drip sequence that doesn't respect the user's actual behavior is annoying. Skip rules:

  • Day-2 "Did you try X?" — skip if user already used feature X. Pass activated_feature in extra_vars to gate this server-side
  • Day-14 "Should we keep emailing you?" — skip if user has opened 3+ emails (they're engaged). Use the events API to check before enqueueing
  • Any step — skip if user unsubscribed since enrollment (SendBolt handles this automatically; no code needed)

Content tips

  • Length: short. 100-200 words per email. People skim onboarding emails; don't bury the CTA
  • One link per email. Multiple CTAs split attention. Drive to ONE action
  • Personal signature. Sign from a real person (you, the founder) for the first 3 emails. After that, brand voice is fine
  • Subject lines: question or first-person. "A question about your Acme setup" beats "Welcome to Acme"
  • Per-recipient send-time on day-14+. By then you have engagement data — use send_time_optimization_enabled: true in the sequence step config

Win/loss metrics

Tracked automatically by the sequence engine:

  • Open rate per step (target: 30%+ on step 1, 20%+ on step 5)
  • Click rate per step (target: 8%+)
  • Unsubscribe rate per step (target: < 2% per step)
  • Sequence completion rate (target: 60%+)
  • Activation rate (your custom event) lifted vs. control group

Check at /dashboard/sequences — the funnel chart shows where users drop off.

What NOT to do

  • Don't send all 5 in the first 3 days. Spacing is the entire point. Compressing the schedule = unsubscribes
  • Don't mix marketing into drip. If a user activated and you want to upsell, that's a separate sequence with its own opt-in
  • Don't pause + resume. If the user goes inactive, end the sequence cleanly. Resurrection-cron emails get marked as spam fast