Customers & accounts
Email Marketing Automation & Segmentation
Indicative price, not an offer: $29-99/mo; anchor: Klaviyo $20/mo tier entry
Generated from docs/plan/paid/email-marketing-automation-segmentation/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.
Email Marketing Automation & Segmentation provides SMTP/email delivery infrastructure, campaign templates, and behavioral triggering to send triggered and scheduled emails (abandoned cart, order confirmation, win-back sequences) to segments of customers.
The problem
Merchants lose repeat sales without automated email campaigns for order confirmations, recommendations, and win-back sequences.
What it does
- Campaign builder: visual/HTML/Markdown template editor
- Campaign types: broadcast, drip (day 1/7/30), event-triggered (order, abandon cart)
- Segmentation targeting: send to selected segments
- Template library: pre-built (order confirmation, password reset, promo, abandoned cart)
- Event triggers: order.created, customer.abandoned_cart, customer.created
- Schedule campaigns: now, future, recurring daily/weekly
- A/B testing: split audience, test subject lines or body
- Analytics: open rate, click rate, conversion rate, unsubscribe rate
- Unsubscribe link injection: auto-add to footer
- Authentication: SPF/DKIM setup guide, domain verification
- SMTP provider: Sendgrid, AWS SES, self-hosted
- Queue and retry: exponential backoff
- Audit log: sent, bounced, opened, clicked, unsubscribed
What it deliberately does NOT do
Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.
- SMS campaigns — email only
- In-app push notifications — email only
- Chat/social campaigns — email only
- Advanced AI personalization (dynamic per customer) — basic template vars ({{name}}, {{total}})
- Lead scoring — analytics feature
- List import/export with external tools — send-only
- Multi-language campaigns — single language
Data model
Campaign: id, store_id, name, type, subject, body_html, body_plaintext, template_id, segment_id, created_by, created_at, updated_at, scheduled_at, sent_at, is_published. CampaignEvent: id, campaign_id, event_type, trigger_conditions (JSON). CampaignEmail: id, campaign_id, customer_id, email_address, sent_at, opened_at, clicked_at, bounced_at, status, unsubscribe_token. CampaignAnalytics: campaign_id, sent_count, open_count, click_count, bounce_count, unsubscribe_count, conversion_count. EmailTemplate, SmtpConfiguration. Migration: add 6+ tables.
API
- POST /admin/campaigns
- GET /admin/campaigns
- GET /admin/campaigns/{id}
- PATCH /admin/campaigns/{id}
- DELETE /admin/campaigns/{id}
- POST /admin/campaigns/{id}/send
- POST /admin/campaigns/{id}/preview
- GET /admin/campaigns/{id}/analytics
- GET /admin/templates
- POST /admin/templates
- POST /admin/smtp/configure
- GET /admin/smtp/status
Every route added here must also appear in src/pages/openapi.json.ts — a test
fails the build if it does not.
Admin
Campaign list: table of name, type, segment, created, sent, status, stats. Builder: form with subject, segment selector, body editor (WYSIWYG or HTML), A/B toggles, schedule. Preview: render email. Analytics dashboard: sends/opens/clicks over time. Template library. SMTP setup: API key, provider, domain verification.
The seam — why this is paid
Core owns: event hooks (order.created, customer.abandoned_cart), customer/order data, segment queries. Paid module owns: SMTP integration, campaign builder UI, email templating, queue, delivery, analytics, retry, unsubscribe token.
Paid module owns SMTP/email deliverability reputation, campaign template engine, and subscriber list infrastructure; core owns order event stream only
Dependencies
- behavioral-segmentation (optional)
- customer-preferences
Acceptance checks
Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.
- Campaign segment=Gold Members, subject, body, send_time=2024-09-02 10:00; at 10:00 emails sent to Gold Members with email_opted_in=true
- Email footer includes Unsubscribe link with unique token
- Opening email sets opened_at; clicking link sets clicked_at; analytics show 100% open rate
- Unsubscribe via link causes email_opted_in=false; next campaign skips
- A/B test: 50% get Subject A, 50% get B; analytics show open rate per variant
- Abandoned cart triggered: cart+2hr no purchase causes email sent
- Bounce: SMTP returns 550; retried 1h, 4h, 24h; after 3 failures marked bounced
- Campaign 10k recipients queues over 5min (rate-limited)
Risks
API key leaked causes spam, reputation ruined. Email template {{name}} not replaced. Campaign sent to wrong segment. Unsubscribe token guessed. Bounce handling wrong. Rate limit exceeded. A/B sends twice. Analytics wrong.
Commercial context
| Suggested price | $29-99/mo; anchor: Klaviyo $20/mo tier entry |
| Rival anchor | Klaviyo $20-300+/mo, Omnisend freemium ($0-350/mo), Mailchimp freemium; Shopify Messaging free core only |
The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.
Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full
catalogue and ../../AI-GUIDE.md for how to work on this repository.