> ## 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.

# Python integration

> kaireonai — a dependency-free Python client for the KaireonAI public API (recommend, respond, negotiate, provenance, skip reasons).

## Install

```bash theme={null}
pip install kaireonai
```

The client is intentionally minimal: it uses only the Python standard library
(`urllib`), so installing it pulls **no** third-party dependencies into your
project. Python 3.9+.

## Quickstart

```python theme={null}
from kaireonai import KaireonClient

client = KaireonClient(
    base_url="https://playground.kaireonai.com",  # or set KAIREON_BASE_URL
    api_key="...",                                 # or set KAIREON_API_KEY
    tenant_id="...",                               # or set KAIREON_TENANT_ID
)

# Ask for the next best actions for a customer
rec = client.recommend(customer_id="cust-1", channel="email")
```

All three constructor arguments fall back to environment variables
(`KAIREON_BASE_URL`, `KAIREON_API_KEY`, `KAIREON_TENANT_ID`). `base_url`
defaults to `https://playground.kaireonai.com`. The client raises
`ValueError` if the API key or tenant ID is missing. Auth is sent as the
standard `X-API-Key` + `X-Tenant-Id` headers.

## API methods

| Method                                                                        | HTTP call                                    | Notes                                                                                                                                       |
| ----------------------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `recommend(*, customer_id, **kwargs)`                                         | `POST /api/v1/recommend`                     | Extra keyword args (e.g. `channel`, `placement`, `limit`, `context`, `attributes`) are passed through as request fields.                    |
| `respond(*, recommendation_id, customer_id, rank, outcome_key, outcome=None)` | `POST /api/v1/respond`                       | Records an outcome against a prior recommendation for attribution/learning.                                                                 |
| `negotiate(decision_id, *, offer_id, mode="shadow")`                          | `POST /api/v1/decisions/{id}/negotiate`      | Shadow-mode by default.                                                                                                                     |
| `provenance(decision_id)`                                                     | `GET /api/v1/decisions/{id}/provenance`      | Returns `{ "body", "signature", "digest" }` — the signed decision bundle plus the `X-Provenance-Signature` / `X-Provenance-Digest` headers. |
| `skip_reasons(*, window_hours=None, top_n=None)`                              | `GET /api/v1/decisioning-gates/skip-reasons` | Aggregated reasons candidates were filtered out by decisioning gates.                                                                       |

Errors surface as `KaireonError`, which carries `.status` and `.body` from
the server response:

```python theme={null}
from kaireonai import KaireonClient, KaireonError

client = KaireonClient()  # reads env vars

try:
    rec = client.recommend(customer_id="cust-1", channel="email", limit=3)
    outcome = client.respond(
        recommendation_id=rec["interactionId"],
        customer_id="cust-1",
        rank=1,
        outcome_key="click",
    )
except KaireonError as err:
    print(err.status, err.body)
```

## openapi-generator-cli recipe

For languages other than Python — or for the CRUD endpoints not wrapped by
the `kaireonai` package — generate a client straight from the platform's
OpenAPI spec, served at `/api/openapi.json`:

```bash theme={null}
npm install -g @openapitools/openapi-generator-cli
openapi-generator-cli generate \
  -i https://playground.kaireonai.com/api/openapi.json \
  -g <python|typescript-axios|java|go|...> \
  -o ./generated-client
```

## Calling the hosted MCP endpoint from Python

KaireonAI exposes a hosted MCP endpoint at `POST /api/v1/mcp` — stateless
JSON-RPC 2.0 over HTTP (no SSE). You can drive it with nothing but the
standard library, reusing the same `X-API-Key` / `X-Tenant-Id` headers:

```python theme={null}
import json, urllib.request

def mcp_call(method, params=None, base="https://playground.kaireonai.com",
             api_key="...", tenant_id="..."):
    payload = {"jsonrpc": "2.0", "id": 1, "method": method, "params": params or {}}
    req = urllib.request.Request(
        f"{base}/api/v1/mcp",
        data=json.dumps(payload).encode(),
        method="POST",
        headers={
            "Content-Type": "application/json",
            "X-API-Key": api_key,
            "X-Tenant-Id": tenant_id,
        },
    )
    with urllib.request.urlopen(req) as resp:
        return json.load(resp)["result"]

tools = mcp_call("tools/list")["tools"]
print([t["name"] for t in tools])
```

The endpoint supports `initialize`, `ping`, `tools/list`, and `tools/call`.
The authenticated tenant is forced into every call, and mutating operations
are routed through the governed approval flow rather than writing directly.
See the [MCP Server Reference](/integrations/mcp) for the full tool surface.

## Distribution status

The client lives in the `kaireonai/sdks` repository at `sdks/python/`
(package name `kaireonai`, version 0.1.0). Publishing the
artifact to PyPI requires operator authorization (PyPI credentials); until
that lands, install from source:

```bash theme={null}
pip install "git+https://github.com/kaireonai/sdks.git#subdirectory=sdks/python"
```
