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 decisioning gate and contact policy 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


How It Works

When you request a Why-Not analysis, KaireonAI re-evaluates the decisioning gates and contact policies 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 decisioning gates

Runs every active decisioning gate 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

Response Structure

The response includes four sections:

Example Response

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

Decisioning Gate Results

Each rule returns one of three statuses:

Contact Policy Results

Supported Rule Types

Empty or short result set — what the trace tells you

Call /recommend with debug: true and read debugTrace. Beyond the funnel counts (totalCandidates → afterQualification → afterSuppression → afterContactPolicy → afterConsent → afterGuardrails), two fields explain results that would otherwise look like a silent failure: A fully-absent-data decisioning gate (e.g. segment_required with no segment data, or propensity_threshold on a cold model) now skips with a Skipped: … reason in qualificationReasons rather than silently blocking every offer.

Per-request why-not: rejectedOffers on /recommend?explain=true

For a live request (rather than the re-evaluation this page’s endpoint performs), call /recommend with explain: true. The response’s rejectedOffers[] lists every offer that entered the pipeline but didn’t make the response, each with the stage that dropped it and a self-contained human-readable reason. Coverage is complete — every candidate-dropping stage records a reason: The same merged list is persisted on DecisionTrace.rejectedOffers for sampled traces, so the answer to “why didn’t customer X get offer Y on request Z” survives after the fact. See the Recommend API rejectedOffers field and Decision Traces for exact shapes.

API Reference

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

Next Steps

Decisioning Gates

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.

Live Console

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