# Origamy playbook spec v1. Reference: /playbooks/spec-format/
spec_version: 1
id: base.welcome-onboarding
title: Welcome and onboarding
sector: base
source:
  kind: engagement
  date: 2026-10-31
  ref: eng-2026-10-church-a
  notes: >-
    The welcome timing (email after 2 hours, SMS after 2 days) is copied from a real build. The
    "finish setting up" nudge that stops the moment someone completes onboarding follows a
    segment and SMS built in our own demo workspace, not a customer's.
derived_from: church.first-timer-to-member
vocabulary:
  person: person
  people: people
  group: team
summary: >-
  Welcomes every new sign-up, then nudges people who haven't finished getting started, and
  stops nudging the moment they do.
when_to_use:
  - People sign up (or pay) and then have to do something to get value, like finishing their profile, completing onboarding or a first lesson.
  - Your app sends an event when someone signs up and another when they finish getting started.

requires:
  data_in:
    - how: app_events
      what: "Your app sends the start and done events. Without an app, use a sign-up form as the start event and a staff form (\"onboarding done\") as the done event."
  channels:
    - channel: email
      for: The welcome email and the second nudge
      needs: A verified sending domain for {{ params.email_from }}, or Origamy's test sender while you try it.
    - channel: sms
      for: The first nudge
      needs: An SMS provider, or Origamy managed SMS after business verification (KYC).
  events:
    - "{{ params.start_event }}"
    - "{{ params.done_event }}"
  traits: []

parameters:
  - key: org_name
    ask: true
    question: What should messages call your organisation?
    label: Organisation name
    type: string
    example: Northwind
  - key: start_event
    ask: true
    question: Which event means someone just joined? (sign-up, first payment…)
    label: Start event
    type: event_name
    default: Signed Up
  - key: done_event
    ask: true
    question: Which event means they've finished getting started?
    label: Done event
    type: event_name
    default: Onboarding Completed
  - key: start_url
    ask: true
    question: Where do they go to finish? (a link into your app)
    label: Getting-started link
    type: url
    example: https://app.yourcompany.example/start
  - key: email_from
    ask: true
    question: Which address should emails come from?
    label: Sender address
    type: email
    example: hello@yourcompany.example
  - key: welcome_delay
    label: Welcome email after the start event
    type: duration
    default: 2h
  - key: first_nudge_delay
    label: First nudge (SMS) after joining
    type: duration
    default: 1d
  - key: second_nudge_delay
    label: Second nudge (email) after the first
    type: duration
    default: 2d
  - key: greeting_fallback
    label: Greeting when a first name is missing
    type: string
    default: there

timings:
  - Welcome email {{ params.welcome_delay }} after {{ params.start_event }}.
  - If they haven't finished, an SMS nudge {{ params.first_nudge_delay }} after joining, and an email {{ params.second_nudge_delay }} after that.
  - The nudges stop as soon as {{ params.done_event }} arrives.

customer_must:
  - Make sure your app sends {{ params.start_event }} and {{ params.done_event }} for each person, with their email and phone on the profile.
  - Verify the sending domain; for the SMS, connect a provider or finish business verification.
  - Switch both follow-ups on (a follow-up only runs once it's on), run a test person through with your own phone and email, then erase them.

objects:
  - ref: seg_not_finished
    kind: segment
    about: Joined in the last 30 days and hasn't finished getting started.
    body:
      name: Joined, not finished getting started
      description: "{{ params.start_event }} in the last 30 days, no {{ params.done_event }}."
      segment_type: dynamic
      status: active
      definition:
        operator: and
        conditions:
          - { type: event, event_name: "{{ params.start_event }}", cond_operator: has_done, time_window: 30d }
          - { type: event, event_name: "{{ params.done_event }}", cond_operator: has_not_done, time_window: 30d }
  - ref: tmpl_welcome
    kind: template
    about: The welcome email.
    body:
      name: Welcome (email)
      channel: email
      category: Onboarding
      style: html
      status: active
      subject: "Welcome to {{ params.org_name }}, {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}"
      metadata: { email: { from: "{{ params.email_from }}", preview_text: "Here's how to get started." } }
      variables: {}
      body: >-
        <p>Hi {{ traits.first_name | default: "{{ params.greeting_fallback }}" }},</p>
        <p>Welcome to {{ params.org_name }}! Getting started takes a few minutes.</p>
        <p><a href="{{ params.start_url }}">Get started</a></p>
        <p>Questions? Just reply to this email.</p>
        <p style="font-size:12px;color:#6b6b80"><a href="{{ unsubscribe_url }}">Unsubscribe</a></p>
  - ref: tmpl_nudge_sms
    kind: template
    about: Short "your place is saved, finish in two minutes" SMS.
    body:
      name: Finish getting started (SMS)
      channel: sms
      category: Onboarding
      style: text
      status: active
      subject: ""
      metadata: {}
      variables: {}
      body: "Hi {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}, your {{ params.org_name }} account is ready. Finish setting up in 2 minutes: {{ params.start_url }} Reply STOP to opt out."
  - ref: tmpl_nudge_email
    kind: template
    about: Second nudge by email.
    body:
      name: Finish getting started (email)
      channel: email
      category: Onboarding
      style: html
      status: active
      subject: "You're one step away, {{ traits.first_name | default: \"{{ params.greeting_fallback }}\" }}"
      metadata: { email: { from: "{{ params.email_from }}", preview_text: "Pick up where you left off." } }
      variables: {}
      body: >-
        <p>Hi {{ traits.first_name | default: "{{ params.greeting_fallback }}" }},</p>
        <p>You haven't finished setting up {{ params.org_name }} yet. Pick up where you left off:
        it only takes a couple of minutes.</p>
        <p><a href="{{ params.start_url }}">Finish setting up</a></p>
        <p>If something got in the way, reply and tell us.</p>
        <p style="font-size:12px;color:#6b6b80"><a href="{{ unsubscribe_url }}">Unsubscribe</a></p>
  - ref: wf_welcome
    kind: workflow
    about: The welcome email.
    body:
      name: "Welcome"
      description: The welcome email after someone joins.
      enabled: false
      trigger_type: event
      trigger_config: { event_name: "{{ params.start_event }}" }
      steps:
        - { id: s1, type: delay, config: { duration: "{{ params.welcome_delay }}" } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: email, template_id: "{{ ref.tmpl_welcome.id }}" } } } }
      re_entry_policy: once
      re_entry_cooldown_hours: 24
      goal: {}
      exit_conditions: []
  - ref: wf_nudge
    kind: workflow
    about: Two nudges to finish getting started; leaves the moment they finish.
    body:
      name: "Finish getting started"
      description: An SMS and then an email for people who haven't finished; exits on the done event.
      enabled: false
      trigger_type: event
      trigger_config: { event_name: "{{ params.start_event }}" }
      steps:
        - { id: s1, type: delay, config: { duration: "{{ params.first_nudge_delay }}" } }
        - { id: s2, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: sms, template_id: "{{ ref.tmpl_nudge_sms.id }}" } } } }
        - { id: s3, type: delay, config: { duration: "{{ params.second_nudge_delay }}" } }
        - { id: s4, type: action, config: { action_type: send_message, channel_config: { mode: single, single: { channel: email, template_id: "{{ ref.tmpl_nudge_email.id }}" } } } }
      re_entry_policy: once
      re_entry_cooldown_hours: 24
      goal: { event_name: "{{ params.done_event }}", attribution_window_hours: 168 }
      exit_conditions: [{ event_name: "{{ params.done_event }}" }]

eval:
  name: 63_base_welcome_onboarding
  mode: task
  vertical: ""
  prompt: >-
    When someone signs up, send a welcome email a couple of hours later. If they haven't
    completed onboarding after a day, text them a short reminder, then email them two days
    later. Stop as soon as they finish onboarding.
  expect_artifacts: [workflow, message_template]
  forbid_terms: []
