Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

Tutorial: Churn Prevention

This tutorial walks through building a churn-prevention flow from a blank tenant. By the end you’ll have a working flow that scores customers by churn risk, qualifies the right retention offer, suppresses outreach for already-contacted customers, and improves with every recorded outcome. Business scenario: a telecom or SaaS provider wants to reduce monthly churn. The marketing team has three retention offers — a free month, a service upgrade, and a personal call. Each offer has different eligibility, different cost, and different effectiveness depending on the customer’s risk profile and tenure. The system has 24 hours to decide who gets which offer, and the contact policy says no customer may be touched more than once a week. What you’ll build:
  • A Customer schema with the fields the flow needs to score
  • 3 retention offers with different qualification rules and business impact
  • A decision flow that combines propensity scoring, qualification gates, and a 7-day contact policy
  • An end-to-end test through /recommend and /respond
  • A view into how the model learns from recorded outcomes
Prerequisites: A running KaireonAI instance (Playground, self-hosted, or Cloud), an admin API key, and curl or any HTTP client. Time: 25–30 minutes.

1. Define the customer schema

The flow needs four fields to make a churn-aware decision: tenure (months), monthly spend, support tickets in the last 90 days, and current plan tier.
curl -X POST https://your-instance.kaireonai.com/api/v1/schemas \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "name": "Customer",
    "fields": [
      { "name": "tenureMonths", "type": "integer" },
      { "name": "monthlySpend", "type": "decimal" },
      { "name": "ticketsLast90d", "type": "integer" },
      { "name": "planTier", "type": "string" }
    ]
  }'
A schema creates a real PostgreSQL table (ds_customer) you can populate via the Data → Schemas UI, a /api/v1/customers bulk insert, or a pipeline from any of the 80 connectors.

2. Define the three retention offers

Each offer represents a different retention play. The priority field encodes business preference when scores tie, and budget lets the platform respect spend caps later.
curl -X POST https://your-instance.kaireonai.com/api/v1/offers \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "name": "Free month",
    "category": "Retention",
    "priority": 70,
    "businessValue": 30,
    "margin": 80,
    "qualificationRules": [
      { "field": "ticketsLast90d", "op": ">=", "value": 2 }
    ]
  }'

curl -X POST https://your-instance.kaireonai.com/api/v1/offers \
  -d '{
    "name": "Service upgrade (one tier up)",
    "category": "Retention",
    "priority": 85,
    "businessValue": 110,
    "margin": 60,
    "qualificationRules": [
      { "field": "tenureMonths", "op": ">=", "value": 6 },
      { "field": "monthlySpend", "op": ">=", "value": 40 }
    ]
  }'

curl -X POST https://your-instance.kaireonai.com/api/v1/offers \
  -d '{
    "name": "Personal retention call",
    "category": "Retention",
    "priority": 95,
    "businessValue": 200,
    "margin": 20,
    "qualificationRules": [
      { "field": "monthlySpend", "op": ">=", "value": 100 },
      { "field": "tenureMonths", "op": ">=", "value": 12 }
    ]
  }'
The qualification rules are the gate — a low-tenure low-spend customer cannot receive the personal call, no matter how high their churn risk.

3. Add the 7-day contact policy

The most common churn-prevention failure mode is over-messaging. A contact policy of “no retention contact within 7 days” prevents the platform from following a free-month offer with an upgrade nudge the next day.
curl -X POST https://your-instance.kaireonai.com/api/v1/contact-policies \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "name": "Retention 7-day cooldown",
    "scope": "category:Retention",
    "ruleType": "frequency_cap",
    "windowDays": 7,
    "maxImpressions": 1
  }'
The policy is scoped to the Retention category, so transactional messages and other categories are unaffected.

4. Wire the decision flow

The flow stitches everything together:
  1. Inventory — load active retention offers.
  2. Enrich — pull tenureMonths, monthlySpend, ticketsLast90d, planTier from the Customer schema.
  3. Qualify — apply each offer’s eligibility rules; filter out non-qualifying candidates.
  4. Contact Policy — suppress any candidate the customer has already received in the last 7 days.
  5. Score — propensity-based scoring on a feature vector of (tenure, spend, tickets, tier).
  6. Rank — PRIE composite blending propensity, channel relevance, impact, and emphasis.
  7. Response — return the top offer.
You can build this through the Decision Flows UI in the Studio, or via the API:
curl -X POST https://your-instance.kaireonai.com/api/v1/decision-flows \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "name": "Churn Prevention",
    "config": {
      "nodes": [
        { "id": "inv", "type": "inventory", "config": { "category": "Retention" } },
        { "id": "enr", "type": "enrich", "config": { "schema": "Customer" } },
        { "id": "qual", "type": "qualify" },
        { "id": "cp", "type": "contact_policy" },
        { "id": "score", "type": "score", "config": { "method": "propensity" } },
        { "id": "rank", "type": "rank", "config": { "profile": "default-prie" } },
        { "id": "out", "type": "response" }
      ]
    }
  }'
Then POST /api/v1/decision-flows/{id}/publish to make it live.

5. Run the recommendation

For a customer who has a long tenure, high spend, and recent support friction — the kind of customer worth saving:
curl -X POST https://your-instance.kaireonai.com/api/v1/recommend \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "customerId": "cust_7",
    "channel": "email",
    "flow": "Churn Prevention"
  }'
A representative response:
{
  "decisions": [
    {
      "offerId": "off_personal_call",
      "name": "Personal retention call",
      "score": 0.81,
      "rank": 1,
      "trace": {
        "qualified": true,
        "contactPolicy": "passed (last contact 14 days ago)",
        "propensitySource": "offer",
        "prie": { "P": 0.78, "R": 0.70, "I": 0.85, "E": 0.95 }
      }
    },
    {
      "offerId": "off_service_upgrade",
      "name": "Service upgrade (one tier up)",
      "score": 0.64,
      "rank": 2
    },
    {
      "offerId": "off_free_month",
      "name": "Free month",
      "score": 0.42,
      "rank": 3
    }
  ],
  "decisionId": "dec_xyz123",
  "latencyMs": 47
}
The trace shows why the personal call won: it qualified, the contact policy passed, propensity scoring fired from the offer-scope model, and the PRIE composite ranked it first because impact (0.85) and emphasis (0.95) compensated for relevance (0.70 — email isn’t the obvious channel for a personal call but the offer specifies follow-up).

6. Record the outcome

When the customer accepts (or doesn’t), record the result so the model improves:
curl -X POST https://your-instance.kaireonai.com/api/v1/respond \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "X-Requested-With: XMLHttpRequest" \
  -d '{
    "decisionId": "dec_xyz123",
    "outcome": "accepted",
    "context": { "channel": "email" }
  }'
The bandit/Bayesian models update on every /respond. Within minutes the platform updates the scoped posterior for (scope=offer, scopeId=off_personal_call) — and the next decision for a similar customer sees a slightly tighter, higher confidence-interval lower-bound on the personal-call propensity.

7. Watch the model learn

The Model Health dashboard shows the Wilson confidence interval for each scoped adaptation. Initially, the interval is wide and exposureProbability is below 1.0 (the maturity ramp gates immature offers). After 30–50 outcomes the interval tightens, the offer becomes mature, and exposure goes to 1.0. For a deep-dive on the math (Wilson 1927 closed form, the 0.20 width threshold, the cold-start floor decay), see Maturity Ramp (BCB-MR).

8. What’s next

  • Add an uplift signal. Configure the T-learner / X-learner endpoint to estimate causal CATE per customer. The U term in PRIE-U then suppresses “sure thing” offers that would have converted anyway and boosts “persuadable” customers where the offer actually moves the needle.
  • Multi-channel routing. Add a channel_selector upstream of the flow to pick email vs. SMS vs. push based on customer preference and recent engagement.
  • Frequency optimization at the customer level. Add a customer_total_cap contact policy (max 3 contacts per customer per week across all categories) so retention doesn’t crowd out billing or service messages.
  • Experiment with a holdout group. Set up an A/B with a 10% holdout that gets no retention contact. Use the platform’s z-test uplift calculation to prove the program’s incremental revenue.

See Industry Templates for ready-made starter kits, Starbucks NBA pipeline for a full retail walkthrough, or the API Reference for endpoint-by-endpoint details.