{
  "slug": "stalled-trial-slack-alert",
  "title": "Stalled trial Slack alert: template and code",
  "url": "https://www.courier.com/recipes/stalled-trial-slack-alert",
  "markdown": "https://www.courier.com/recipes/stalled-trial-slack-alert.md",
  "stage": "Activation",
  "purpose": "Hand stuck, high-value trials to a person instead of sending another email.",
  "summary": "A stalled trial Slack alert tells your sales team about big free trials that haven't activated. Five days into a trial, if the account has 10 or more seats, it posts in your sales channel with the account and its owner. Smaller trials get a friendly email instead, and activating cancels the check.",
  "channels": [
    "slack",
    "email"
  ],
  "shape": "journey",
  "shows": [
    "Asking your app for data before deciding who hears about it",
    "A branch that picks Slack or email by seat count",
    "Posting to Slack with a token stored once on a tenant"
  ],
  "data": [
    {
      "name": "account_id",
      "type": "string",
      "example": "acct_8F2k",
      "note": "Sent to your endpoint, builds the cancellation token, and ends the account link"
    },
    {
      "name": "account_name",
      "type": "string",
      "example": "Globex",
      "note": "Returned by your endpoint"
    },
    {
      "name": "profile.first_name",
      "type": "string",
      "example": "Dana",
      "note": "From the owner's profile. Write it when the user signs up. The emails say \"there\" when it's missing"
    },
    {
      "name": "profile.last_name",
      "type": "string",
      "example": "Lee",
      "note": "From the owner's profile"
    },
    {
      "name": "profile.email",
      "type": "email",
      "example": "dana@globex.com",
      "note": "From the owner's profile"
    },
    {
      "name": "seats",
      "type": "number",
      "example": "12",
      "note": "Returned by your endpoint"
    },
    {
      "name": "activity_summary",
      "type": "string",
      "example": "2 projects created, 0 teammates invited",
      "note": "Returned by your endpoint"
    }
  ],
  "steps": [
    {
      "step": "1",
      "when": "5 days after the trial starts",
      "channels": "Slack or Email",
      "templates": [
        "templates/stalled-trial-slack.json",
        "templates/trial-nudge-email.json"
      ]
    }
  ],
  "files": {
    "journey": "journey.json",
    "templates": [
      "templates/stalled-trial-slack.json",
      "templates/trial-nudge-email.json"
    ],
    "setup": [
      "setup.ts",
      "setup-slack.ts"
    ],
    "start": [
      "start.ts",
      "start.py"
    ],
    "stop": [
      "stop.ts",
      "stop.py"
    ]
  },
  "docs": [
    "https://www.courier.com/docs/journeys/nodes/fetch-data",
    "https://www.courier.com/docs/journeys/nodes/branch",
    "https://www.courier.com/docs/journeys/nodes/send",
    "https://www.courier.com/docs/integrations/direct-message/slack",
    "https://www.courier.com/docs/journeys/nodes/cancel",
    "https://www.courier.com/docs/journeys/invoke"
  ],
  "related_recipes": [
    "https://www.courier.com/recipes/trial-ending-email-sequence",
    "https://www.courier.com/recipes/customer-health-score-slack-alert",
    "https://www.courier.com/recipes/onboarding-incomplete-reminder-email"
  ],
  "agent_prompt": "Add a stalled trial alert to this app, sent through Courier: 5 days into a trial, post in our sales Slack channel when an account with 10 or more seats is still stalled, and email smaller stalled trials instead. Follow the steps at https://www.courier.com/recipes/stalled-trial-slack-alert.md and use the Courier skill for SDK details.\n\n1. Create the journey and its templates in my Courier workspace by replacing Acme, the setup and admin links, and the activation endpoint URL (in journey.json) with our own, then running setup.ts from that page with COURIER_API_KEY from our environment. Save the journey ID it prints as COURIER_STALLED_TRIAL_JOURNEY_ID.\n2. Run setup-slack.ts from the same page with COURIER_API_KEY, SLACK_BOT_TOKEN, and SLACK_ALERT_CHANNEL (our sales channel's ID) from our environment. It creates the \"sales-alerts\" tenant that the Slack node already names.\n3. Add an HTTPS endpoint that takes a POST with {\"account_id\": \"...\"} and returns the fields marked \"Returned by your endpoint\" in the Data fields table, from our real account data, like activationStatus in start.ts.\n4. Find where this codebase starts a trial and start the journey there, as the account owner. Pass the fields in the Data fields table, point the fetch node at the endpoint from step 3, and make sure the owner's first_name, last_name, and email are written to their Courier profile at signup.\n5. Find where an account activates or upgrades and cancel the journey with the token trial-check-<account_id>.\n6. Match this codebase's language, file layout, and error handling. Never hardcode the API key or the Slack token.\n7. When you're done, start one run for a test user and show me the run's steps.",
  "status": {
    "state": "passing",
    "last_tested": "2026-10-19"
  }
}
