Skip to main content
Every decisioning engine needs to answer one question: why did this customer see (or not see) this offer? Action Analysis (also called “Why-Not”) gives you a complete diagnostic breakdown of every qualification rule, contact policy, and scoring factor that determined the outcome. This is essential for support teams investigating customer complaints, marketers debugging campaign reach, and compliance teams auditing decision fairness.
Action Analysis brings enterprise-grade decision transparency to every tenant. Access it from the Live Console or via the API at GET /api/v1/customers/:customerId/why-not/:offerId.

Business Value

ScenarioHow Why-Not Helps
Customer complaintsSupport agent looks up why a promotion was not shown, sees “frequency cap exceeded” instantly
Campaign debuggingMarketer discovers a qualification rule is blocking 40% of the target audience
Compliance auditsAuditor verifies that exclusion decisions follow documented policy
Model validationData scientist confirms propensity scores are flowing through the pipeline correctly

How It Works

When you request a Why-Not analysis, KaireonAI replays the full decision pipeline for that specific customer-offer pair:
1

Load offer metadata

Fetches the offer, its category, sub-category, and active creatives.
2

Enrich customer data

Queries all schema tables for the customer’s data (demographics, transactions, behavioral attributes).
3

Evaluate qualification rules

Runs every active qualification rule and reports whether it applies to this offer, whether it passed or blocked, and the exact reason.
4

Evaluate contact policies

Checks frequency caps, cooldown periods, and suppression rules against the customer’s interaction history.
5

Return verdict

Produces a verdict of eligible or blocked with a human-readable summary and full detail breakdowns.

Using Why-Not Analysis

From the API

curl https://playground.kaireonai.com/api/v1/customers/CUST-001/why-not/offer_summer_promo \
  -H "X-Tenant-Id: my-tenant" \
  -H "Authorization: Bearer <token>"

Response Structure

The response includes four sections:
SectionDescription
verdicteligible or blocked — the final outcome
summaryHuman-readable explanation of the verdict
qualificationPer-rule breakdown with pass/block/skip status and reasons
contactPolicyPer-policy breakdown with pass/block/skip status and reasons

Example Response

{
  "customerId": "CUST-001",
  "offerId": "offer_summer_promo",
  "offerName": "Summer Rewards Bonus",
  "offerStatus": "active",
  "category": "Retention",
  "verdict": "blocked",
  "summary": "Blocked by contact policy: Email Frequency Cap",
  "qualification": {
    "total": 3,
    "passed": 3,
    "blocked": 0,
    "skipped": 1,
    "details": [
      {
        "ruleId": "qr_001",
        "ruleName": "Gold Tier Only",
        "ruleType": "attribute_condition",
        "scope": "category",
        "applies": true,
        "result": "passed",
        "reason": "Passed"
      },
      {
        "ruleId": "qr_002",
        "ruleName": "Min Balance",
        "ruleType": "attribute_condition",
        "scope": "offer",
        "applies": false,
        "result": "skipped",
        "reason": "Rule scope offer:offer_winter_sale does not match this offer"
      }
    ]
  },
  "contactPolicy": {
    "total": 2,
    "passed": 1,
    "blocked": 1,
    "skipped": 0,
    "details": [
      {
        "policyId": "cp_001",
        "policyName": "Email Frequency Cap",
        "ruleType": "frequency_cap",
        "scope": "global",
        "applies": true,
        "result": "blocked",
        "reason": "Frequency cap exceeded: 5/3 (daily)"
      }
    ]
  },
  "customerData": {
    "age": 34,
    "income": 75000,
    "gender": "F",
    "membershipDays": 412
  },
  "interactionHistory": {
    "totalImpressions": 5,
    "lastContact": "2026-04-02T14:30:00.000Z",
    "summaryCount": 3
  }
}
Why-Not analysis runs enrichment queries in real time. For customers with data across many schema tables, response times may be higher than typical API calls. Use this for diagnostic purposes, not in production recommendation paths.

Understanding the Results

Qualification Rule Results

Each rule returns one of three statuses:
StatusMeaning
passedRule applies to this offer and the customer meets the criteria
blockedRule applies and the customer fails the criteria — offer is ineligible
skippedRule does not apply to this offer (scope mismatch)

Contact Policy Results

StatusMeaning
passedPolicy applies and the customer is within limits
blockedPolicy applies and the customer has exceeded the policy (e.g., frequency cap, cooldown)
skippedPolicy scope does not match this offer

Supported Rule Types

Rule TypeWhat It Checks
attribute_conditionCustomer attribute against a threshold (e.g., income >= 50000)
offer_attributeOffer-level field value (e.g., productType == "credit_card")
frequency_capNumber of impressions within a time period
cooldownHours since last contact

API Reference

See the full Why-Not API Reference for endpoint details, field descriptions, and error codes.

Next Steps

Qualification Rules

Configure the rules that determine offer eligibility.

Contact Policies

Set up frequency caps, cooldowns, and suppression rules.

Decision Traces

View full pipeline execution traces for any decision.

1:1 Operations Manager

Real-time monitoring console with built-in Why-Not access.