Skip to main content
An Offer is the fundamental building block of KaireonAI. It represents something you can recommend to a customer — a product, a promotion, a message, or a next-best-action. Every time the Recommend API runs, it evaluates your active offers against a specific customer, filters out ineligible ones, scores the rest, and returns the best matches. If Decision Flows are the engine, Offers are the fuel. Offers belong to a Category (and optionally a sub-category), carry configuration for priority, business value, budget, and scheduling, and connect to Creatives that define the actual content delivered through each Channel.
Only offers with status: "active" are considered by Decision Flows. Draft and paused offers are excluded from all candidate selection.

How Offers Work at Runtime

When a Decision Flow executes via the Recommend API, every offer passes through these stages:
StageRegular OffersMandatory Offers
InventoryLoaded by scope (all, category, or manual)Same — split into separate list
ScheduleExcluded if outside date/time windowSame — expired promotions are not forced
QualificationEvaluated against propensity, segments, recencyBypassed
ScoringPRIE formula with model + weightsFixed score of 1.0
Contact PolicyFiltered by all active policiesBypassed (except mandatory-specific policies)
Daily CapN/ACapped at 5/customer/day (configurable)
RankingSorted by score descendingPrepended above regular results

Common Use Cases

Use CaseExampleKey Config
Product recommendation”Upgrade to Premium Card”priority: 70, businessValue: 85, qualification rules for credit score
Time-sensitive promotion”Flash Sale: 24 Hours Only”schedule.startDate / endDate, high priority
Regulatory notice”CFPB Rate Disclosure”mandatory: true with reason, approver, and expiry
Retention offer”Stay with us — get 20% off for 6 months”High businessValue, churn model for propensity scoring
Exploratory content”Did you know about our new savings account?”Low priority: 25, broad eligibility

Priority and Business Value

Two fields control how aggressively an offer competes during scoring. They look similar but serve different purposes in the PRIE formula:
FieldPRIE FactorRangePurposeWho Sets It
priorityEmphasis (E)0—100Subjective campaign lever — how much to boost or suppress this offerMarketer
businessValueImpact (I)0—100Objective business worth — revenue, margin, strategic importanceBusiness analyst
Both are normalized to 0—1 at scoring time. Setting either to 0 eliminates the offer from PRIE scoring entirely (because PRIE is multiplicative).

Priority Bands

LevelValueWhen to Use
Critical90Regulatory, compliance
High70Strategic campaigns, time-sensitive
Medium50Standard recommendations (default)
Low25Exploratory, filler content

Business Value Example (Starbucks)

OfferbusinessValueNormalized (I)Rationale
BOGO Frappuccino800.80High margin on Frappuccinos, drives store visits
25% Off Merchandise500.50Lower margin but drives basket size
Informational: New Store200.20No direct revenue, brand awareness only
When in doubt, start with priority: 50 and businessValue: 50 (the defaults). Adjust after you see initial performance data in the Business Dashboard.

Status Lifecycle

Offers progress through a defined lifecycle:
draft -> active -> paused -> archived
StatusDescription
draftBeing configured. Not available for decisioning.
activeLive and eligible for recommendation.
pausedTemporarily removed from decisioning. Can be reactivated.
archivedPermanently retired. Preserved for reporting history.

Qualification Config

Control which customers are eligible to receive this offer via the eligibility object:
FieldTypeDescriptionExample
propensityThresholdnumber (0—1)Minimum model score required0.65 — only show to customers with 65%+ propensity
recencynumber (days)Minimum days since customer last received this offer30 — no repeat within a month
requiredSegmentsstring[]Customer must belong to all listed segments["high_value", "credit_eligible"]
modelReferencestringScoring model to use for propensity evaluation"model_propensity_cc_v3"

Budget Config

Set spend and impression limits via the budget object:
FieldTypeDescriptionExample
maxImpressionsnumberTotal lifetime impression cap50000
maxDailyBudgetnumberMaximum spend per day2500.00
costPerActionnumberCost per impression or conversion1.50
Budget checking uses atomic Redis INCR (with Prisma fallback) to prevent race conditions under concurrent load. When an offer’s budget is exhausted, it is automatically excluded from decisioning.
The budget_exhausted Contact Policy rule type can also enforce budget limits at the policy level.

Schedule Config

Restrict when an offer is eligible via the schedule object:
FieldTypeDescriptionExample
startDateISO 8601Earliest date the offer can be recommended"2026-03-15T00:00:00Z"
endDateISO 8601Latest date the offer can be recommended"2026-06-15T23:59:59Z"
daysOfWeeknumber[]Allowed days (0=Sunday through 6=Saturday)[1,2,3,4,5] — weekdays only
timeWindowobject{ start: "HH:mm", end: "HH:mm" } within allowed days{ "start": "08:00", "end": "20:00" }
Schedule filtering happens early in the pipeline (inventory stage) and applies to both regular and mandatory offers. An offer outside its schedule window is excluded regardless of priority or mandatory status.

Mandatory Governance

Marking an offer as mandatory: true activates a special runtime path for compliance-critical communications. Mandatory offers bypass qualification rules and receive a fixed score of 1.0, guaranteeing they rank above all regular candidates.

Required Fields

When mandatory is true, the API enforces three governance fields:
FieldPurposeExample
mandatoryReasonWhy this offer must be shown (audit trail)"CFPB regulation 2026-04 requires rate disclosure"
mandatoryApprovedByWho approved the override"jane.smith@acme.com"
mandatoryExpiresAtISO 8601 expiry after which the offer reverts to normal"2026-04-15T23:59:59Z"
If any are missing, the API returns 400 Bad Request. Only users with the admin role can create or update mandatory offers.
Mandatory offers bypass qualification rules and normal ranking. Use this only for regulatory or compliance-critical communications. The mandatoryExpiresAt field ensures overrides do not persist indefinitely.

Example: Regulatory Disclosure

{
  "name": "CFPB Rate Disclosure Q2-2026",
  "status": "active",
  "categoryId": "cat_compliance",
  "priority": 90,
  "mandatory": true,
  "mandatoryReason": "CFPB regulation 2026-04 requires rate disclosure within 30 days",
  "mandatoryApprovedBy": "jane.smith@acme.com",
  "mandatoryExpiresAt": "2026-04-15T23:59:59Z",
  "schedule": {
    "startDate": "2026-03-15T00:00:00Z",
    "endDate": "2026-04-15T23:59:59Z"
  }
}
During the 30-day window, this offer scores 1.0 and appears above all regular recommendations, bypasses propensity thresholds and segment requirements, still respects the daily mandatory cap (default 5 per customer), and automatically stops after April 15.

Emergency Exclusions

The emergencyExcluded flag lets you instantly remove an offer from all recommendations without changing its status or modifying a Decision Flow. Designed for pricing errors, compliance issues, or product recalls.
AspectBehavior
ScopeExcluded from all flows, all channels, all segments
SpeedTakes effect on the next Recommend API call — no cache flush needed
StatusRemains active (toggling back is a single API call)
AuditEvery toggle is recorded with timestamp, user, and previous value
Set via API:
PUT /api/v1/offers
{ "id": "offer_abc123", "emergencyExcluded": true }
Set via UI: Open the offer detail page and click the Emergency Exclude button.
Emergency exclusion is a blunt instrument — it removes the offer from all channels, all placements, and all segments simultaneously. For targeted suppression (e.g., one channel only), use Contact Policies instead.

Creating an Offer

1

Navigate to Offers

Go to Studio > Offers in the sidebar.
2

Click + New Offer

Click the + New Offer button in the top-right corner.
3

Fill in basic info

Enter the offer name, description, and select a Category and sub-category.
4

Set priority and business value

Choose the priority level (Emphasis) and business value (Impact). Both default to 50.
5

Configure qualification (optional)

Set propensity thresholds, required segments, and recency rules.
6

Configure budget and schedule (optional)

Set impression caps, daily budget limits, start/end dates, and time windows.
7

Fill custom fields

Populate any custom fields defined by the parent category, including computed field formulas.
8

Save and activate

Save as draft, review, then set to active when ready.

Field Reference

Every field accepted by POST /api/v1/offers (create) and PUT /api/v1/offers (update):
FieldRequiredTypeDefaultDescription
nameYesstringDisplay name. Must be unique within the tenant.
statusNoenum"draft"draft, active, paused, archived
categoryIdNostringnullParent Category ID
subCategoryIdNostringnullSub-category ID within the category
productTypeNostring""Product nature: bogo, discount, auto_insurance, credit_card, etc. Used for PRIE strategy overrides and offer_attribute qualification rules.
priorityNointeger (0—100)50PRIE Emphasis (E) factor. Higher = more aggressive ranking.
businessValueNointeger (0—100)50PRIE Impact (I) factor. Overall business importance.
marginNofloat0Profit margin per conversion. Sub-weight of Impact (I) in PRIE scoring.
revenueValueNofloat0Expected revenue per conversion. Sub-weight of Impact (I) in PRIE scoring.
mandatoryNobooleanfalseBypass qualification and rank above all regular offers
mandatoryReasonConditionalstringnullRequired when mandatory=true
mandatoryApprovedByConditionalstringnullRequired when mandatory=true
mandatoryExpiresAtConditionalstringnullRequired when mandatory=true. ISO 8601.
descriptionNostring""Internal documentation
shortDescNostring""Brief description surfaced in responses
eligibilityNoobject{}Qualification config (see above)
budgetNoobject{}Budget config (see above)
scheduleNoobject{}Schedule config (see above)
tagsNostring[][]Freeform tags for filtering
metadataNoobject{}Arbitrary key-value pairs for integrations
emergencyExcludedNobooleanfalseInstant exclusion from all recommendations

API Quick Reference

Create

POST /api/v1/offers
{
  "name": "BOGO Frappuccino",
  "shortDesc": "Buy one Frappuccino, get one free this weekend",
  "categoryId": "cat_beverages",
  "priority": 70,
  "businessValue": 80,
  "status": "draft",
  "tags": ["bogo", "frappuccino", "weekend"],
  "eligibility": {
    "propensityThreshold": 0.5,
    "recency": 7,
    "requiredSegments": ["rewards_member"]
  },
  "schedule": {
    "startDate": "2026-04-05T00:00:00Z",
    "endDate": "2026-04-07T23:59:59Z",
    "daysOfWeek": [5, 6, 0]
  }
}
Response: 201 Created with the full offer object including generated id.

List

GET /api/v1/offers
Supports optional query parameters: status, categoryId, tags.

Update

PUT /api/v1/offers
Send id in the request body along with the fields to update. Only provided fields are changed.

Delete

DELETE /api/v1/offers?id={offerId}
Returns 409 Conflict if the offer has creatives or interaction history. Add ?force=true to confirm permanent deletion.
Deleting an offer removes it permanently along with its creatives and interaction history. Consider archiving instead to preserve reporting integrity.

Next Steps

Channels

Define how your offers are delivered to customers.

Creatives

Create the content variants for each offer and channel.

Decision Flows

Build the pipeline that scores, filters, and ranks your offers.

Glossary

Look up key terms used across the platform.