KiteDocs
Guides

Activation, churn, and expansion

Turn product behavior into explicit Customer Success outcomes.

Kite has generic lifecycle, journey, rule, segment, and health primitives rather than built-in activation, churn, or revenue models. Your definitions therefore encode the product's own outcomes and remain reviewable with the product code.

Activation

Define activation as a durable customer outcome, not account creation or a login. A journey is useful when first value requires ordered milestones; the completed journey can enter an activated lifecycle state and emit a webhook event.

journeys/activation.ts
export default defineJourney({
  id: 'activation',
  name: 'Activation',
  startsWhen: { event: 'account.created' },
  expiresAfter: '30d',
  steps: [
    { id: 'connected', name: 'Connected data', completedWhen: { event: 'integration.connected' } },
    { id: 'value', name: 'Reached first value', completedWhen: { event: 'report.exported' } },
  ],
  onComplete: { emit: 'customer.activated' },
  onExpire: { emit: 'customer.activation_expired' },
});

Reference completion from the lifecycle:

activated: {
  description: 'Reached the product first-value outcome',
  enteredWhen: { journey: 'activation', status: 'complete' },
}

Journey steps are ordered. Optional steps may complete out of order, but only the next required step completes for an event. expectedWithin is currently descriptive and does not itself expire or alert on a step; use journey expiresAfter or a scheduled rule for enforcement. Completed or expired journeys do not restart.

Churn risk

Use a segment for a non-exclusive working queue and lifecycle only when risk must replace the customer's current state. Combine independent evidence rather than using one arbitrary threshold:

segments/at-risk.ts
export default defineSegments([{
  id: 'at_risk',
  name: 'At risk',
  filter: {
    any: [
      { inactiveDays: { min: 14 } },
      { healthScore: { max: 40 } },
      { eventCount: { event: 'api.error', days: 7, min: 5 } },
    ],
  },
  onEnter: { emit: 'customer.churn_risk.detected' },
  onExit: { emit: 'customer.churn_risk.resolved' },
}]);

This models risk, not confirmed churn. Represent cancellation, non-renewal, and contraction as authoritative billing or CRM events. Kite does not predict churn or understand MRR and renewals unless those facts are ingested and modeled explicitly.

Expansion

Expansion is similarly product-specific. Model qualification with a segment or rule built from adoption, plan traits, usage growth, and unused eligible features. Emit a signal for downstream CS workflow:

{
  id: 'expansion_candidate',
  name: 'Expansion candidate',
  triggers: [{ schedule: '0 9 * * 1' }],
  conditions: {
    all: [
      { lifecycle: 'activated' },
      { healthScore: { min: 75 } },
      { featuresUnused: { plan: 'pro', minCount: 1 } },
    ],
  },
  action: {
    type: 'emit_signal',
    signal: 'customer.expansion_candidate',
    metadata: { playbook: 'feature-discovery' },
  },
}

emit_signal rule actions are operational. Declarative defineSignals(...detect...) definitions are validated but automatic first-occurrence and average-based detection are not executed yet.

Validation

Backtest every definition against known examples: customers who did and did not reach value, renewed and churned, or expanded and remained flat. Record false positives, choose windows from observed product cadence, and review definitions when the product or packaging changes. A config activation affects future evaluation; use a dry-run recompute to measure historical impact.

On this page