Skip to main content

Overview

This guide shows you how to call the KaireonAI APIs from JavaScript (Node.js / browser) and Python. Both examples cover the two core endpoints:
  • Recommend — get personalized next-best-action offers for a customer
  • Respond — record outcomes (impressions, clicks, conversions) to close the feedback loop

Prerequisites

RequirementWhere to find it
Base URLhttps://your-instance.kaireonai.com or https://playground.kaireonai.com for testing
Tenant IDSettings > General in the KaireonAI UI
API KeySettings > API Keys — create one and copy the raw key
Every request requires three headers:
X-Tenant-Id: <your-tenant-id>
X-API-Key: <your-api-key>
X-Requested-With: XMLHttpRequest

JavaScript

Install dependencies

No SDK package is needed — the built-in fetch API works in Node 18+ and all modern browsers. If you prefer a library:
npm install node-fetch   # only needed for Node < 18

Recommend API

const BASE_URL = "https://playground.kaireonai.com";

const headers = {
  "Content-Type": "application/json",
  "X-Tenant-Id": "YOUR_TENANT_ID",
  "X-API-Key": "YOUR_API_KEY",
  "X-Requested-With": "XMLHttpRequest",
};

async function getRecommendations(customerId, limit = 3) {
  const response = await fetch(`${BASE_URL}/api/v1/recommend`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      customerId,
      limit,
    }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Recommend failed (${response.status}): ${error.error}`);
  }

  return response.json();
}

// Usage
const result = await getRecommendations("SBX-000100");
console.log("Decisions:", result.decisions);
console.log("Recommendation ID:", result.recommendationId);
Response shape:
{
  "recommendationId": "rec-uuid",
  "customerId": "SBX-000100",
  "count": 3,
  "decisions": [
    {
      "offerId": "offer-abc",
      "offerName": "Starbucks: Discount — 10 Day Low",
      "categoryName": "Starbucks: Retention",
      "channelName": "Starbucks: Email",
      "creativeId": "creative-xyz",
      "score": 0.85,
      "rank": 1,
      "content": { "subject": "Special offer", "body": "<p>Save today</p>" },
      "personalization": {},
      "scoreExplanation": { "method": "priority_weighted", "priority": 85, "finalScore": 1 }
    }
  ],
  "meta": { "totalCandidates": 60, "afterQualification": 60, "degradedScoring": false }
}

Respond API

After the customer sees or interacts with an offer, record the outcome:
async function recordOutcome(customerId, creativeId, channelId, outcome) {
  const response = await fetch(`${BASE_URL}/api/v1/respond`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      customerId,
      creativeId,  // from the recommend response decisions[].creativeId
      channelId,   // from the recommend response decisions[].channelId
      outcome,     // "impression", "click", "accept", "dismiss", "convert"
      idempotencyKey: `${outcome}-${Date.now()}`,
    }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Respond failed (${response.status}): ${error.error}`);
  }

  return response.json();
}

// Usage — record a click on the first decision
const decision = result.decisions[0];
await recordOutcome("SBX-000100", decision.creativeId, decision.channelId, "click");
Response shape (201 Created):
{
  "interactionId": "interaction-uuid",
  "customerId": "SBX-000100",
  "outcome": "click",
  "classification": "positive",
  "offerName": "Starbucks: Discount — 10 Day Low",
  "status": "recorded"
}

Error handling

Wrap calls in a try/catch and handle common status codes:
try {
  const recs = await getRecommendations("cust-001", "web");
} catch (err) {
  // 401 -- invalid API key or tenant ID
  // 404 -- customer not found or no active decision flow
  // 422 -- validation error (bad request body)
  // 429 -- rate limited
  // 500 -- server error
  console.error("API error:", err.message);
}

Python

Install dependencies

pip install requests

Recommend API

import requests

BASE_URL = "https://playground.kaireonai.com"

HEADERS = {
    "Content-Type": "application/json",
    "X-Tenant-Id": "YOUR_TENANT_ID",
    "X-API-Key": "YOUR_API_KEY",
    "X-Requested-With": "XMLHttpRequest",
}


def get_recommendations(customer_id: str, limit: int = 3) -> dict:
    response = requests.post(
        f"{BASE_URL}/api/v1/recommend",
        headers=HEADERS,
        json={
            "customerId": customer_id,
            "limit": limit,
        },
    )
    response.raise_for_status()
    return response.json()


# Usage
result = get_recommendations("SBX-000100")
print("Decisions:", result["decisions"])
print("Recommendation ID:", result["recommendationId"])

Respond API

import time

def record_outcome(
    customer_id: str,
    creative_id: str,
    channel_id: str,
    outcome: str,
) -> dict:
    response = requests.post(
        f"{BASE_URL}/api/v1/respond",
        headers=HEADERS,
        json={
            "customerId": customer_id,
            "creativeId": creative_id,   # from decisions[].creativeId
            "channelId": channel_id,     # from decisions[].channelId
            "outcome": outcome,          # impression, click, accept, dismiss, convert
            "idempotencyKey": f"{outcome}-{int(time.time())}",
        },
    )
    response.raise_for_status()
    return response.json()


# Usage — record a click on the first decision
decision = result["decisions"][0]
record_outcome("SBX-000100", decision["creativeId"], decision["channelId"], "click")

Error handling

from requests.exceptions import HTTPError

try:
    recs = get_recommendations("cust-001", "web")
except HTTPError as err:
    status = err.response.status_code
    body = err.response.json()
    # 401 -- invalid API key or tenant ID
    # 404 -- customer not found or no active decision flow
    # 422 -- validation error (bad request body)
    # 429 -- rate limited
    # 500 -- server error
    print(f"API error ({status}): {body.get('error', 'Unknown')}")

Next steps

  • API Tutorial — deep dive into request/response formats, decision traces, and experiments
  • Computed Values — personalize offers with dynamic formulas
  • Sample Data — load sample offers and customers into your instance