Skip to content

SOP-LC-01: Lifecycle Communications

Version: 1.1
Status: Production Ready
Created: January 2026
Updated: February 2026
Owner: Protocol Raw Operations
Related: Email Design System v1.1, SOP-CS-00, SOP-REF-01, SOP-SUB-00, SOP-02, SOP-EMAIL-01


What's New in v1.1

  • ✅ All transactional confirmation emails implemented in Customer.io
  • ✅ Database trigger architecture for automatic email sending
  • ✅ Updated copy with brand voice warmth pass
  • ✅ Added Box Size, Frequency, and Address change confirmations
  • ✅ Customer.io Transactional Message IDs documented
  • ✅ Edge Function send-lifecycle-email documented

1. Overview

Purpose

This SOP defines all automated customer email communications for Protocol Raw. It consolidates copy, triggers, timing, and technical implementation details into a single reference document.

Philosophy

Emails are not marketing brochures. They're direct communication with someone who already trusts us. Every email should feel like a note from a competent, thoughtful company, not a sales pitch.

Core principles:

  • Calm, expert, reassuring
  • Short, declarative, plain English
  • Factual without being cold
  • Respectful of time

We are: Confident, warm, systematic
We are NOT: Salesy, cute, desperate for attention

Email Categories

Category Purpose Headline Sign-off Tone
Transactional Receipts, confirmations, system updates Optional Protocol Raw Factual, simple
Operational Delivery reminders, billing notices Optional Protocol Raw Factual, simple
Lifecycle Onboarding, check-ins, education Yes Protocol Raw or Persona Warm but not pushy
Lifecycle (Relational) Check-ins, win-back, reply-inviting No Persona Conversational, human
Support Replies to customer inquiries No Persona Conversational, human

Personas

For relational emails that invite replies, we use named personas:

Persona Usage
Sophie Support, check-ins, win-back
Tom Support, check-ins, win-back
Lucy Support, check-ins, win-back

Assignment: Deterministic per customer (hash of customer ID). Same customer always gets same persona across all touchpoints.


2. Email Inventory

Master List

# Email Category Timing Customer.io ID Status
1a Order Confirmation (First) Transactional Immediate 6 ✅ Live
1b Order Confirmation (Repeat) Transactional Immediate 7 ✅ Live
2 Transition Guide Lifecycle +24 hours ⏳ Campaign
3 Week 1 Check-in Lifecycle (Relational) +7 days ⏳ Campaign
4 Week 2 Check-in Lifecycle (Relational) +14 days ⏳ Campaign
5 7-Day Delivery Reminder Operational -7 days ⏳ Existing
6 48-Hour Lock Operational -48 hours ⏳ Existing
7 Dispatch Confirmation Transactional On dispatch ⏳ Existing
8 Delivery Confirmation Transactional On delivery ⏳ Existing
9 Skip Confirmation Transactional Immediate 9 ✅ Live
10 Reschedule Confirmation Transactional Immediate 10 ✅ Live
11 Pause Confirmation Transactional Immediate 11 ✅ Live
12 Resume Confirmation Transactional Immediate 12 ✅ Live
13 Cancellation Confirmation Transactional Immediate 13 ✅ Live
14 Box Size Change Transactional Immediate 14 ✅ Live
15 Frequency Change Transactional Immediate 15 ✅ Live
16 Address Change Transactional Immediate 16 ✅ Live
17 Win-back 1 Lifecycle (Relational) +30 days ⏳ Campaign
18 Win-back 2 Lifecycle (Relational) +60 days ⏳ Campaign
A1 Calculator Abandonment 1h Lifecycle +1 hour ✅ Existing
A2 Calculator Abandonment 48h Lifecycle +48 hours ✅ Existing

Emails Documented Elsewhere

Email Source SOP
Referral signup SOP-REF-01
Credit earned SOP-REF-01
Credit applied SOP-REF-01
Credit expiring SOP-REF-01
Card expiring (30 day) SOP-SUB-00
Card expiring (7 day) SOP-SUB-00
Payment failed (Day 0/3/7/10) SOP-SUB-00
Courier exceptions SOP-02

3. Onboarding Sequence (First Order)

3.1 Order Confirmation (First)

Customer.io ID: 6
Template ID: order_confirmation_first
Trigger: Database trigger on raw_ops.orders INSERT (first order)
Timing: Immediate
Category: Transactional

Subject: Your order is confirmed
Preview text: Order #{{order.order_number}}. We'll have it with you soon.


Hi {{customer.first_name}},

We've received your order and it's being prepared.

Order #{{order.order_number}}
{{order.box_size}} box, £{{order.total_price}}
{{customer.address1}}, {{customer.city}}, {{customer.zip}}

Your box will be matched to a tested batch. It will arrive frozen within 3-5 working days.

You'll receive tracking as soon as it leaves our freezer. Once it arrives, scan the QR code on any pouch to view your batch report.

Tomorrow we'll send {% if dog_name %}{{dog_name}}'s{% else %}your{% endif %} personalised transition guide with a day-by-day feeding schedule.

Any questions, just reply.

Protocol Raw


3.2 Order Confirmation (Repeat)

Customer.io ID: 7
Template ID: order_confirmation_repeat
Trigger: Database trigger on raw_ops.orders INSERT (orders 2+)
Timing: Immediate
Category: Transactional

Subject: Your order is confirmed
Preview text: Order #{{order.order_number}}. We'll have it with you soon.


Hi {{customer.first_name}},

We've received your order and it's being prepared.

Order #{{order.order_number}}
{{order.box_size}} box, £{{order.total_price}}
{{customer.address1}}, {{customer.city}}, {{customer.zip}}

Your box will be matched to a tested batch. It will arrive frozen within 3-5 working days.

You'll receive tracking as soon as it leaves our freezer.

Any questions, just reply.

Protocol Raw


3.3 Transition Guide

Template ID: transition_guide
Trigger: First order created
Timing: +24 hours after order
Category: Lifecycle
Status: ⏳ To be implemented as Customer.io Campaign

Subject: {{if dog_name}}{{dog_name}}'s{{else}}Your{{end}} transition guide is ready
Preview text: A 10-day schedule for switching to raw.


Your 10-day transition plan

Hi {{customer.first_name}},

Your box will arrive in the next few days. This guide shows how to introduce it.

The 10-day transition

A gradual switch gives {{if dog_name}}{{dog_name}}'s{{else}}your dog's{{end}} digestive system time to adapt. We've built a day-by-day schedule based on the feeding plan you calculated.

View {{if dog_name}}{{dog_name}}'s{{else}}your{{end}} schedule

The schedule shows exact gram amounts for each day, so there's no guesswork.

What's normal during transition

Softer stools in the first few days. This usually settles within a week.

You may also notice {{if dog_name}}{{dog_name}}{{else}}your dog{{end}} drinking less water. That's expected. Raw food is naturally high in moisture, so they get hydration from the food itself.

Your portal

The link above is your customer portal. You can adjust deliveries, pause or skip orders, update your address, and track shipments.

Questions during the transition? Reply here and we'll help.

Protocol Raw


CTA: View schedule → {{portal_url}}?view=transition


4. Ongoing Subscription

4.1 7-Day Delivery Reminder

Template ID: delivery_reminder_7day
Trigger: 7 days before next billing
Timing: -7 days
Category: Operational
Status: ⏳ Existing via Make.com

Subject: Your next box ships in a week
Preview text: Make any changes by {{cutoff_date}}.


Hi {{customer.first_name}},

Your next box ships in about a week.

Next delivery
{{order.box_size}} box, £{{order.total_price}}
Ships: {{ship_date}}
Charged: {{billing_date}}

Need to skip, reschedule, or change your box size? Make changes by {{cutoff_date}}.

Manage your subscription

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


4.2 48-Hour Lock

Template ID: delivery_lock_48h
Trigger: 48 hours before billing
Timing: -48 hours
Category: Operational
Status: ⏳ Existing via Make.com

Subject: Your box ships tomorrow
Preview text: Changes are now locked.


Hi {{customer.first_name}},

Your next box ships tomorrow. Changes are now locked for this delivery.

This delivery
{{order.box_size}} box, £{{order.total_price}}
Ships: {{ship_date}}

If you need to make urgent changes, reply to this email.

Protocol Raw


5. Subscription State Changes

5.1 Skip Confirmation

Customer.io ID: 9
Template ID: delivery_skipped
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'skip')
Timing: Immediate
Category: Transactional

Subject: Delivery skipped
Preview text: Your plan is saved and ready whenever you are.


Hi {{customer.first_name}},

You've skipped your next delivery. No problem. Your plan remains active.

Next delivery
{{subscription.box_size}} box, £{{subscription.price}}
Ships: {{subscription.new_ship_date}}
Charged: {{subscription.new_billing_date}}

You can adjust this anytime from your portal.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.2 Reschedule Confirmation

Customer.io ID: 10
Template ID: delivery_rescheduled
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'reschedule')
Timing: Immediate
Category: Transactional

Subject: Delivery rescheduled
Preview text: Your new delivery date is confirmed.


Hi {{customer.first_name}},

Your new delivery date is confirmed.

New delivery date
{{subscription.box_size}} box, £{{subscription.price}}
Ships: {{subscription.new_ship_date}}
Charged: {{subscription.new_billing_date}}

Everything else on your plan remains the same. You can adjust your delivery anytime from your portal.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.3 Pause Confirmation

Customer.io ID: 11
Template ID: subscription_paused
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'pause')
Timing: Immediate
Category: Transactional

Subject: Subscription paused
Preview text: Your plan is saved and ready whenever you are.


Hi {{customer.first_name}},

Your subscription is now paused. You won't be charged until you resume.

Subscription status
{{subscription.box_size}} box, £{{subscription.price}}
Status: Paused

Your plan remains saved and ready whenever you are.

When you're ready, you can resume from your portal and we'll schedule your next delivery.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.4 Resume Confirmation

Customer.io ID: 12
Template ID: subscription_resumed
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'resume')
Timing: Immediate
Category: Transactional

Subject: Welcome back
Preview text: Your subscription is active. Next delivery scheduled.


Hi {{customer.first_name}},

Welcome back. Your subscription is now active.

Next delivery
{{subscription.box_size}} box, £{{subscription.price}}
Ships: {{subscription.new_ship_date}}
Charged: {{subscription.new_billing_date}}

You can adjust your delivery anytime from your portal.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.5 Cancellation Confirmation

Customer.io ID: 13
Template ID: subscription_cancelled
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'cancel')
Timing: Immediate
Category: Transactional

Subject: Subscription cancelled
Preview text: You won't be charged again.


Hi {{customer.first_name}},

Your subscription has been cancelled. You won't be charged again.

If you decide to return in the future, we can help you pick up where you left off at protocolraw.co.uk.

Any questions, just reply.

Protocol Raw


Notes: No CTA button. Door left open with continuity language ("pick up where you left off").


5.6 Box Size Change

Customer.io ID: 14
Template ID: box_size_changed
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'box_change')
Timing: Immediate
Category: Transactional

Subject: Box size updated
Preview text: Now {{subscription.box_size}} box, £{{subscription.price}}.


Hi {{customer.first_name}},

Your box size has been updated.

Your plan
{{subscription.box_size}} box, £{{subscription.price}}
Next delivery: {{subscription.new_ship_date}}

This applies from your next delivery. You can adjust anytime from your portal.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.7 Frequency Change

Customer.io ID: 15
Template ID: frequency_changed
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'frequency_change')
Timing: Immediate
Category: Transactional

Subject: Delivery schedule updated
Preview text: Now every {{subscription.frequency_weeks}} weeks.


Hi {{customer.first_name}},

Your delivery schedule has been updated.

Your plan
{{subscription.box_size}} box
Every {{subscription.frequency_weeks}} weeks
Next delivery: {{subscription.new_ship_date}}

This applies from your next delivery. You can adjust anytime from your portal.

Manage your subscription

Any questions, just reply.

Protocol Raw


CTA: Manage your subscription → {{portal_url}}


5.8 Address Change

Customer.io ID: 16
Template ID: address_updated
Trigger: Database trigger on raw_ops.subscription_actions INSERT (action_type = 'address_change')
Timing: Immediate
Category: Transactional

Subject: Delivery address updated
Preview text: All future deliveries will go to your new address.


Hi {{customer.first_name}},

Your delivery address has been updated.

New delivery address
{{customer.address1}}
{{customer.city}}
{{customer.zip}}

All future deliveries will go to this address.

If this wasn't you, please reply straight away.

Manage your subscription

Protocol Raw


CTA: Manage your subscription → {{portal_url}}

Notes: Security line replaces "Any questions, just reply." Address formatted UK-style (postcode on own line, no comma).


6. Win-Back Sequence

6.1 Win-back 1 (30 Days)

Template ID: winback_30day
Trigger: 30 days after cancellation
Timing: +30 days
Category: Lifecycle (Relational)
Status: ⏳ To be implemented as Customer.io Campaign

Subject: Still there?
Preview text: £10 off if you'd like to come back.


Hi {{customer.first_name}},

It's been a few weeks since you cancelled. No pitch, just checking if anything's changed.

If you'd like to restart, use code COMEBACK10 for £10 off your next box.

If something wasn't right, I'm happy to hear about it. Just reply.

{{persona}}
Protocol Raw


6.2 Win-back 2 (60 Days)

Template ID: winback_60day
Trigger: 60 days after cancellation
Timing: +60 days
Category: Lifecycle (Relational)
Status: ⏳ To be implemented as Customer.io Campaign

Subject: Last note from us
Preview text: Your COMEBACK10 code is still valid.


Hi {{customer.first_name}},

This is the last time we'll reach out about your subscription.

The code COMEBACK10 is still valid if you'd like to restart. No expiry, no pressure.

If raw feeding isn't right for {{if dog_name}}{{dog_name}}{{else}}your dog{{end}} right now, that's okay. We'll be here if things change.

{{persona}}
Protocol Raw


Notes: After this email, silence. No more win-back emails. Same offer, no escalation.


7. Calculator Abandonment Sequence

7.1 Abandonment 1h

Template ID: abandonment_1h
Trigger: Calculator completion, no order
Timing: +1-2 hours
Category: Lifecycle
Status: ✅ Existing via Edge Function

Subject: {{if dog_name}}{{dog_name}}'s{{else}}Your{{end}} feeding plan
Preview text: {{daily_grams}}g per day. Ready when you are.


Hi,

You calculated a feeding plan but didn't place an order. The details are saved.

Your plan
{{box_size}} box, £{{discounted_price}} (£20 off)
{{daily_grams}}g per day for {{if dog_name}}{{dog_name}}{{else}}your dog{{end}}
Delivered every {{delivery_weeks}} weeks

Use code {{discount_code}} at checkout.

Continue your order

Protocol Raw


CTA: Continue your order → {{product_url}}?token={{token}}


7.2 Abandonment 48h

Template ID: abandonment_48h
Trigger: Calculator completion, no order, 1h email sent
Timing: +48-50 hours
Category: Lifecycle
Status: ✅ Existing via Edge Function

Subject: Still thinking it over?
Preview text: Your plan is still saved.


Hi,

Your feeding plan for {{if dog_name}}{{dog_name}}{{else}}your dog{{end}} is still saved. A few things that might help:

Safety
Every batch is tested by an independent UKAS-accredited lab before release. When your box arrives, scan the QR code on any pouch to see the results for your specific batch.

Transition
We include a 10-day schedule with exact gram amounts. Most dogs adjust within the first week or two.

Your code {{discount_code}} is still valid for £20 off.

Continue your order

Protocol Raw


CTA: Continue your order → {{product_url}}?token={{token}}


8. Technical Implementation

8.1 Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                      TRANSACTIONAL EMAILS                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Order Confirmations:                                               │
│  ┌────────────┐    ┌──────────────┐    ┌───────────────────────┐  │
│  │   Orders   │───▶│   Trigger    │───▶│  send-lifecycle-email │  │
│  │   INSERT   │    │  Function    │    │    Edge Function      │  │
│  └────────────┘    └──────────────┘    └───────────────────────┘  │
│                                                   │                 │
│  Subscription Actions:                            ▼                 │
│  ┌────────────┐    ┌──────────────┐    ┌───────────────────────┐  │
│  │subscription│───▶│   Trigger    │───▶│   Customer.io         │  │
│  │  _actions  │    │  Function    │    │   Transactional API   │  │
│  │   INSERT   │    └──────────────┘    └───────────────────────┘  │
│  └────────────┘                                                    │
│       ▲                                                            │
│       │                                                            │
│  ┌────────────┐                                                    │
│  │ Ops Portal │  (calls log_subscription_action RPC)               │
│  │ Cust Portal│                                                    │
│  └────────────┘                                                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

8.2 Customer.io Configuration

Site ID: 8633d5bc763716f848d1
API Key: b08777c3150e4cf96485 (Track API)
Transactional API: Used for all confirmation emails

8.3 Customer.io Transactional Message IDs

Email Customer.io ID Template ID
Order Confirmation (First) 6 order_confirmation_first
Order Confirmation (Repeat) 7 order_confirmation_repeat
Skip Confirmation 9 delivery_skipped
Reschedule Confirmation 10 delivery_rescheduled
Pause Confirmation 11 subscription_paused
Resume Confirmation 12 subscription_resumed
Cancellation Confirmation 13 subscription_cancelled
Box Size Change 14 box_size_changed
Frequency Change 15 frequency_changed
Address Change 16 address_updated

8.4 Edge Function: send-lifecycle-email

Location: Supabase Edge Functions
Purpose: Send transactional emails via Customer.io Transactional API

Environment Variables: - CUSTOMERIO_API_KEY - SUPABASE_URL - SUPABASE_SERVICE_ROLE_KEY

Payload:

{
  "email_type": "subscription_paused",
  "customer_id": "uuid",
  "order_id": "uuid",           // For order emails
  "subscription_data": {}        // Optional override for testing
}

Email Type Mapping:

const EMAIL_TYPE_TO_CIO_ID: Record<string, number> = {
  'order_confirmation_first': 6,
  'order_confirmation_repeat': 7,
  'delivery_skipped': 9,
  'delivery_rescheduled': 10,
  'subscription_paused': 11,
  'subscription_resumed': 12,
  'subscription_cancelled': 13,
  'box_size_changed': 14,
  'frequency_changed': 15,
  'address_updated': 16,
}

8.5 Database Triggers

Order Confirmations:

-- Trigger function
CREATE FUNCTION raw_ops.trigger_order_confirmation()
RETURNS TRIGGER AS $$
-- Detects first vs repeat order
-- Calls send-lifecycle-email via pg_net
$$;

-- Trigger
CREATE TRIGGER trg_order_confirmation
AFTER INSERT ON raw_ops.orders
FOR EACH ROW
EXECUTE FUNCTION raw_ops.trigger_order_confirmation();

Subscription Actions:

-- Trigger function
CREATE FUNCTION raw_ops.trigger_subscription_action_email()
RETURNS TRIGGER AS $$
-- Maps action_type to email_type
-- Calls send-lifecycle-email via pg_net
-- Sets email_sent = TRUE
$$;

-- Trigger
CREATE TRIGGER trg_subscription_action_email
BEFORE INSERT ON raw_ops.subscription_actions
FOR EACH ROW
EXECUTE FUNCTION raw_ops.trigger_subscription_action_email();

8.6 Logging Subscription Actions

RPC Function: raw_ops.log_subscription_action

log_subscription_action(
  p_seal_subscription_id TEXT,
  p_action_type TEXT,
  p_action_data JSONB DEFAULT '{}',
  p_source TEXT DEFAULT 'portal'
) RETURNS JSONB

Usage: - Ops Portal: Calls this function before Make.com webhook - Customer Portal: Should call this function before Make.com webhook (pending frontend update)

Action Types: - skip - reschedule - pause - resume - cancel - box_change - frequency_change - address_change

8.7 Portal Integration Status

Portal Status Notes
Ops Portal ✅ Wired Calls log_subscription_action → email triggers automatically
Customer Portal ⏳ Pending Needs frontend update to call log_subscription_action before Make.com

8.8 Personalization Variables

Variable Source Notes
customer.first_name customers table Always available post-order
dog_name calculator_discounts or dogs table May be NULL for multipet or direct purchase
order.order_number orders table Shopify order number
order.box_size order_items or subscription 8kg, 12kg, or 16kg
order.total_price orders or subscription In GBP
subscription.box_size subscriptions table 8kg, 12kg, or 16kg
subscription.price subscriptions table In GBP
subscription.new_ship_date action_data Formatted: "Monday, 3 February"
subscription.new_billing_date action_data Formatted: "3 February"
subscription.frequency_weeks subscriptions table 2, 3, or 4
portal_url Generated https://my.protocolraw.co.uk?token={{token}}
persona Deterministic from customer_id Sophie, Tom, or Lucy

9. Design Standards

All emails follow the Protocol Raw Email Design System v1.1.

9.1 Quick Reference

Element Standard
Background Cream #F9F7F4
Body text Espresso #2B2523, 16px Inter
Headlines Espresso #2B2523, 28px Montserrat Bold
Links Burnt Sienna #B85C3A
Primary CTA Burnt Sienna #B85C3A background, white text
Info cards Stone #EBE8E3 background
Max width 600px
Header Espresso bar with "Protocol Raw" in Cream

9.2 Sign-off Rules

Email Type Sign-off
Transactional Protocol Raw
Operational Protocol Raw
Lifecycle (standard) Protocol Raw
Lifecycle (relational) {{persona}}\nProtocol Raw
Support {{persona}}\nProtocol Raw

9.3 Warmth Pattern

All transactional emails end with "Any questions, just reply." except: - Cancellation (door-open language instead) - Address Change (security line instead)


10. What NOT to Email

Silence is sometimes the stronger move. We do NOT send:

  • Week 3 or Week 4 check-ins (Week 2 is the last onboarding touch)
  • Win-back 3+ (two touches maximum, then silence)
  • "We miss you" or guilt-based messaging
  • Promotional emails or sales
  • Newsletter/content marketing (not a newsletter brand)
  • Survey requests (unless specific research need)
  • NPS scores (doesn't fit brand)
  • Birthday emails (don't collect DOB)
  • Anniversary emails (feels performative)

11. Performance Metrics

11.1 Targets

Email Type Open Rate Click Rate
Transactional 70%+ N/A
Operational 60%+ 20%+
Lifecycle 50%+ 15%+
Win-back 30%+ 10%+
Abandonment 40%+ 15%+

11.2 Key Indicators

Metric Target Alert Threshold
Box-2 retention ≥70% <65%
Unsubscribe rate <0.5% >1%
Spam complaint rate <0.1% >0.2%
Reply rate (check-ins) >5% <2%

12. Version History

Version Date Changes
1.0 January 2026 Initial release. Consolidated all lifecycle email copy.
1.1 February 2026 Implemented transactional emails in Customer.io. Added database trigger architecture. Updated copy with warmth pass. Added Box Size, Frequency, Address change emails. Documented Customer.io IDs and Edge Function.

  • Email Design System v1.1: Visual and copy standards
  • SOP-EMAIL-01: Email architecture and Edge Functions
  • SOP-CS-00: Customer Operations System (email matrix, triggers)
  • SOP-REF-01: Referral System (referral/credit emails)
  • SOP-SUB-00: Subscription State Management (dunning/card expiry emails)
  • SOP-02: Courier Watchdog (delivery exception emails)
  • Abandonment Recovery System: Technical implementation for calculator abandonment

End of SOP-LC-01 v1.1