Documentation Index
Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
Use this file to discover all available pages before exploring further.
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
| Requirement | Where to find it |
|---|
| Base URL | https://your-instance.kaireonai.com or https://playground.kaireonai.com for testing |
| Tenant ID | Settings > General in the KaireonAI UI |
| API Key | Settings > 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
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