Skip to main content
Offers are the core decisioning entity in KaireonAI. Each offer represents a recommendation that can be scored, ranked, and delivered to a customer through one or more channels.
See the Offers feature page for UI guidance and conceptual overview.

Base path

/api/v1/offers

List offers

GET /api/v1/offers
Returns a paginated list of offers for the current tenant, ordered by creation date (newest first). Each offer includes its creatives, category, and sub-category relations.

Query parameters

ParameterRequiredTypeDescription
limitNointegerMaximum number of results to return. Default 25.
cursorNostringCursor for keyset pagination. Pass the last id from the previous page.

Response 200

{
  "data": [
    {
      "id": "off_abc123",
      "tenantId": "t_001",
      "name": "Platinum Card Upgrade",
      "status": "active",
      "categoryId": "cat_01",
      "subCategoryId": "sub_01",
      "category": "acquisition",
      "group": "",
      "priority": 75,
      "mandatory": false,
      "description": "Premium card upgrade offer for high-value customers.",
      "shortDesc": "Upgrade to Platinum",
      "eligibility": {},
      "budget": { "maxPerDay": 500 },
      "schedule": {},
      "tags": ["credit-card", "premium"],
      "metadata": {},
      "creatives": [],
      "categoryRef": { "id": "cat_01", "name": "Acquisition" },
      "subCategoryRef": null,
      "createdAt": "2026-03-10T12:00:00.000Z",
      "updatedAt": "2026-03-12T09:30:00.000Z"
    }
  ],
  "pagination": {
    "total": 42,
    "limit": 25,
    "hasMore": true,
    "nextCursor": "off_xyz789"
  }
}

Error codes

CodeReason
401Missing or invalid API key.
429Rate limit exceeded (2 000 requests / 60 s).

Create an offer

POST /api/v1/offers
Creates a new Offer. Triggers auto-assembly on any active Decision Flows.

Request body

FieldRequiredTypeDescription
nameYesstring (1-255)Unique offer name.
statusNoenumdraft (default), active, paused, archived.
categoryIdNostring | nullID of the parent category.
subCategoryIdNostring | nullID of the parent sub-category.
categoryNostringLegacy category label. Default "engagement".
groupNostringLegacy group label. Default "".
priorityNointeger (0-100)Offer priority. Default 50.
mandatoryNobooleanMark as mandatory (admin-only). Default false.
mandatoryReasonNostring | nullRequired when mandatory is true.
mandatoryExpiresAtNostring | nullISO 8601 expiry. Required when mandatory is true.
mandatoryApprovedByNostring | nullApprover ID. Required when mandatory is true.
descriptionNostringFull description.
shortDescNostringShort description for cards/lists.
eligibilityNoobjectEligibility rule config.
budgetNoobjectBudget constraints.
scheduleNoobjectScheduling config.
tagsNostring[]Free-form tags.
metadataNoobjectArbitrary key-value metadata.
Setting mandatory to true requires the admin role and all three governance fields: mandatoryReason, mandatoryExpiresAt, and mandatoryApprovedBy.

Example request

{
  "name": "Platinum Card Upgrade",
  "status": "draft",
  "categoryId": "cat_01",
  "priority": 75,
  "description": "Premium card upgrade for high-value customers.",
  "tags": ["credit-card", "premium"],
  "budget": { "maxPerDay": 500 }
}

Response 201

Returns the created offer object with all relations.

Error codes

CodeReason
400Validation error (missing name, invalid fields).
403Non-admin trying to create mandatory offer.
409An offer with that name already exists.
415Content-Type is not application/json.

Update an offer

PUT /api/v1/offers
Updates an existing offer. Only provided fields are changed. Triggers auto-assembly on status transitions.

Request body

All fields from the create schema are accepted as optional, plus:
FieldRequiredTypeDescription
idYesstringThe offer ID to update.

Example request

{
  "id": "off_abc123",
  "status": "active",
  "priority": 90
}

Response 200

Returns the updated offer object.

Error codes

CodeReason
400Validation error.
403Non-admin trying to set mandatory.
409Name conflict.

Delete an offer

DELETE /api/v1/offers?id={offerId}
Deletes an offer by ID. If the offer has associated creatives and interaction history, the API returns a 409 cascade warning. Append &force=true to confirm deletion.

Query parameters

ParameterRequiredTypeDescription
idYesstringOffer ID to delete.
forceNostringSet to "true" to force-delete an offer with interaction history.

Response 204

Empty body on success.

Response 409 (cascade warning)

{
  "title": "Cascade warning",
  "detail": "This offer has 3 creative(s) and 150 interaction records that will be permanently deleted. Add ?force=true to confirm.",
  "dependentCreatives": 3,
  "interactionRecords": 150
}

Error codes

CodeReason
400Missing id query parameter.
409Cascade warning (add ?force=true to proceed).

Role requirements

MethodMinimum role
GETviewer
POSTeditor
PUTeditor
DELETEeditor

Offers

Learn more about creating and managing offers in the platform UI.