Skip to content
← All templates

SaaS Customer Onboarding

A 14-day onboarding sequence that sends a welcome email, waits for activation, branches by user engagement, A/B tests subject lines, alerts your team on churn risk, and updates your CRM.

routerdelayab_splitactivepiecestry_catch

What this workflow does

01

Welcome email — sends immediately after signup via SendGrid or Gmail (Activepieces connector).

02

Wait 2 days — business-hours-only delay. Skips weekends.

03

Check activation — HTTP request to your API to check if the user completed setup.

04

Branch — activated users get a tips-and-tricks email. Non-activated get a nudge with A/B tested subject lines (60/40 split).

05

Wait 5 more days — then check engagement score via your analytics API.

06

Churn risk alert — if engagement is low, Slack notification to #customer-success with user details.

07

CRM update — updates HubSpot contact lifecycle stage via Activepieces connector.

Workflow definition

Copy this JSON and POST it to /sequences.

{
  "id": "saas_onboarding_v1",
  "context_schema": {
    "user_id": "string",
    "email": "string",
    "name": "string",
    "plan": "string"
  },
  "blocks": [
    {
      "id": "welcome_email",
      "type": "step",
      "handler": "ap://sendgrid.send_email",
      "params": {
        "auth": { "api_key": "credentials://sendgrid" },
        "props": {
          "to": "{{context.data.email}}",
          "subject": "Welcome to {{context.data.plan}}, {{context.data.name}}!",
          "html": "<h1>You're in!</h1><p>Here's how to get started...</p>"
        }
      }
    },
    {
      "id": "wait_activation",
      "type": "step",
      "handler": "sleep",
      "params": { "duration_ms": 172800000 },
      "delay": { "duration": 172800000, "business_days_only": true }
    },
    {
      "id": "check_activation",
      "type": "step",
      "handler": "http_request",
      "params": {
        "method": "GET",
        "url": "https://api.yourapp.com/users/{{context.data.user_id}}/activation",
        "headers": { "Authorization": "Bearer credentials://internal-api" }
      }
    },
    {
      "id": "activation_branch",
      "type": "router",
      "routes": [
        {
          "condition": "steps.check_activation.output.activated",
          "blocks": [
            {
              "id": "tips_email",
              "type": "step",
              "handler": "ap://sendgrid.send_email",
              "params": {
                "auth": { "api_key": "credentials://sendgrid" },
                "props": {
                  "to": "{{context.data.email}}",
                  "subject": "3 tips to get more from {{context.data.plan}}",
                  "html": "<h1>Power user tips</h1><p>...</p>"
                }
              }
            }
          ]
        }
      ],
      "default": [
        {
          "id": "nudge_ab",
          "type": "ab_split",
          "variants": [
            {
              "name": "nudge_a", "weight": 60,
              "blocks": [
                {
                  "id": "nudge_a_email",
                  "type": "step",
                  "handler": "ap://sendgrid.send_email",
                  "params": {
                    "auth": { "api_key": "credentials://sendgrid" },
                    "props": {
                      "to": "{{context.data.email}}",
                      "subject": "You're 1 step away from setup",
                      "html": "<p>Complete your setup in 2 minutes...</p>"
                    }
                  }
                }
              ]
            },
            {
              "name": "nudge_b", "weight": 40,
              "blocks": [
                {
                  "id": "nudge_b_email",
                  "type": "step",
                  "handler": "ap://sendgrid.send_email",
                  "params": {
                    "auth": { "api_key": "credentials://sendgrid" },
                    "props": {
                      "to": "{{context.data.email}}",
                      "subject": "Need help getting started?",
                      "html": "<p>Reply to this email — we'll set it up for you.</p>"
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "id": "wait_engagement",
      "type": "step",
      "handler": "sleep",
      "params": { "duration_ms": 432000000 },
      "delay": { "duration": 432000000 }
    },
    {
      "id": "check_engagement",
      "type": "step",
      "handler": "http_request",
      "params": {
        "method": "GET",
        "url": "https://api.yourapp.com/users/{{context.data.user_id}}/engagement",
        "headers": { "Authorization": "Bearer credentials://internal-api" }
      }
    },
    {
      "id": "churn_branch",
      "type": "router",
      "routes": [
        {
          "condition": "steps.check_engagement.output.score < 30",
          "blocks": [
            {
              "id": "churn_alert",
              "type": "step",
              "handler": "ap://slack.send_channel_message",
              "params": {
                "auth": { "access_token": "credentials://slack-bot" },
                "props": {
                  "channel": "#customer-success",
                  "text": "Churn risk: {{context.data.name}} ({{context.data.email}}) — engagement score {{steps.check_engagement.output.score}}/100. Plan: {{context.data.plan}}"
                }
              }
            }
          ]
        }
      ]
    },
    {
      "id": "crm_update",
      "type": "step",
      "handler": "ap://hubspot.update_contact",
      "params": {
        "auth": { "access_token": "credentials://hubspot-oauth" },
        "props": {
          "email": "{{context.data.email}}",
          "properties": {
            "lifecyclestage": "customer",
            "onboarding_completed": true
          }
        }
      }
    }
  ]
}

Credentials to configure

Register these via POST /credentials before deploying.

sendgridapi_keySendGrid API key for transactional emails
slack-botoauth2Slack bot token with chat:write scope
hubspot-oauthoauth2HubSpot OAuth2 token with crm.objects.contacts.write
internal-apiapi_keyYour app's internal API key for activation/engagement checks

How to trigger

Fire this workflow when a new user signs up.

// POST /instances
{
  "sequence_id": "saas_onboarding_v1",
  "context": {
    "user_id": "usr_abc123",
    "email": "alice@example.com",
    "name": "Alice",
    "plan": "Pro"
  },
  "idempotency_key": "onboarding:usr_abc123"
}

Or attach a webhook trigger to fire on your signup event:

// POST /triggers
{
  "type": "webhook",
  "sequence_id": "saas_onboarding_v1",
  "config": {
    "path": "/hooks/new-signup",
    "hmac_secret": "credentials://webhook-secret"
  },
  "context_mapping": {
    "user_id": "body.user.id",
    "email": "body.user.email",
    "name": "body.user.name",
    "plan": "body.user.plan"
  }
}

Customize it

Swap email provider — replace ap://sendgrid.send_email with ap://gmail.send_email or ap://mailchimp.send_email.

Add more branches — check plan tier in the router to send different content to Free vs Pro vs Enterprise users.

Extend the timeline — add more delay + email steps to create a 30-day or 60-day onboarding drip.

Add retry — wrap email steps in a TryCatch block with exponential backoff if your provider has rate limits.