Template · Support

At-risk customer alert

Your helpdesk posts new tickets and low satisfaction ratings to a webhook. Claude scores each one for churn risk from the language, the account’s plan and the history you send. Most score low and stop there. High-risk ones get a brief for the account owner (what’s wrong, what the customer is worth, a suggested save play and a draft reply) posted to Slack within a minute.

Download .json

WebhookSUP-3471“Third sync failure this month, we’re evaluating alternatives”CSAT: 1/5
Pipeline
  1. Score churn risk Claude API · Haiku 4.5
  2. High risk? Condition
  3. Brief the owner Claude API · Sonnet 5
  4. Alert in Slack Shell
Slack#at-riskHigh risk: Northwind ($48k ARR). Owner: Ana. Save play: exec call + sync fix ETA.Alerted
The pipeline

What each step does

  1. Score churn risk

    Claude API · Haiku 4.5

    Rates the risk as high, medium or low with the signals behind it.

  2. High risk?

    Condition

    Stops here unless the risk is high.

  3. Brief the owner

    Claude API · Sonnet 5

    Writes the alert: what’s wrong, what the account is worth, a save play and a draft reply.

  4. Alert in Slack

    Shell

    Posts the alert for the account owner.

Set it up

From copy to first run

  1. Copy the pipeline JSON with the button above.
  2. In Jimothy, open Pipelines → New pipeline, paste it under “Or import a pipeline JSON” and click Import.
  3. Fill in the variables below under Pipeline settings → Variables.
  4. Triggers → Add trigger → Webhook. Post new tickets and low CSAT ratings with title (subject), description (message), key, and the extra fields below.

Send the extra fields customer, plan, arr, accountOwner and history (recent tickets or notes). They reach the prompts as {{issue.raw.arr}} and so on.

Variables

What to fill in

The prompts and commands read these as {{vars.<name>}}. The examples are placeholders: replace them with your own.

VariableWhat to put in itExample
savePlaysWhat your team can offer to keep an unhappy customer. The brief suggests from these.Call from a VP within 24 hours. Engineering ETA on the underlying bug. One month credit…
slackWebhookUrlA Slack incoming webhook for the channel account owners watch.—
Show the pipeline JSON
{
  "jimothyPipeline": 1,
  "name": "At-risk customer alert",
  "description": "Scores tickets and CSAT ratings for churn risk and alerts the account owner when it’s high.",
  "icon": "workflow",
  "color": "#ca8a04",
  "repo": {
    "mode": "scratch"
  },
  "concurrency": 5,
  "variables": {
    "savePlays": "Call from a VP within 24 hours. Engineering ETA on the underlying bug. One month credit (up to $5,000 ARR accounts). Dedicated onboarding session. Extended trial of a higher plan.",
    "slackWebhookUrl": ""
  },
  "steps": [
    {
      "id": "score",
      "name": "Score churn risk",
      "type": "agent",
      "description": "Rates the risk as high, medium or low with the signals behind it.",
      "harnessId": "anthropic-api",
      "model": "claude-haiku-4-5",
      "timeoutMinutes": 3,
      "retries": 1,
      "passPattern": "^\\s*RISK:\\s*(high|medium|low)\\b",
      "prompt": "Customer: {{issue.raw.customer | default:\"(unknown)\"}}, plan {{issue.raw.plan | default:\"unknown\"}}, ARR {{issue.raw.arr | default:\"unknown\"}}\nRecent history: {{issue.raw.history | default:\"(none sent)\"}}\n\nNew message ({{issue.key}}): {{issue.title}}\n{{issue.description | default:\"(empty)\"}}\n\nRate the risk that this customer churns. High means explicit talk of leaving, cancelling, evaluating alternatives or escalating, or repeated failures with strong frustration. Answer in exactly this format:\nRISK: high, medium or low\nSIGNALS: the phrases or facts that drove the rating"
    },
    {
      "id": "high",
      "name": "High risk?",
      "type": "condition",
      "description": "Stops here unless the risk is high.",
      "dependsOn": [
        "score"
      ],
      "condition": {
        "match": "all",
        "rules": [
          {
            "value": "{{steps.score.output}}",
            "op": "matches",
            "compare": "RISK:\\s*high"
          }
        ]
      }
    },
    {
      "id": "brief",
      "name": "Brief the owner",
      "type": "agent",
      "description": "Writes the alert: what’s wrong, what the account is worth, a save play and a draft reply.",
      "harnessId": "anthropic-api",
      "model": "claude-sonnet-5",
      "dependsOn": [
        "high"
      ],
      "timeoutMinutes": 5,
      "prompt": "{{steps.score.output}}\n\nCustomer: {{issue.raw.customer | default:\"(unknown)\"}}, plan {{issue.raw.plan | default:\"unknown\"}}, ARR {{issue.raw.arr | default:\"unknown\"}}, owner {{issue.raw.accountOwner | default:\"unassigned\"}}\nHistory: {{issue.raw.history | default:\"(none sent)\"}}\nMessage ({{issue.key}}): {{issue.title}}\n{{issue.description}}\n\nSave plays we can offer: {{vars.savePlays}}\n\nWrite a Slack alert (*bold*, - bullets), under 200 words: *At risk: <customer> (<ARR>)*, owner, what's wrong in two lines, the save play you recommend from the list and why, and a short draft reply for the owner to send personally."
    },
    {
      "id": "post",
      "name": "Alert in Slack",
      "type": "shell",
      "description": "Posts the alert for the account owner.",
      "dependsOn": [
        "brief"
      ],
      "timeoutMinutes": 2,
      "command": "printf '{\"text\":%s}' {{steps.brief.output | json}} | curl -fsS -X POST -H 'Content-Type: application/json' --data @- {{vars.slackWebhookUrl}}"
    }
  ]
}