Quickstart
From an API key to a model explained and analysed, in five steps and about ten minutes.
The steps use a built-in reference model, so there is nothing to deploy. Swap in your own model with one upload call or a scoring endpoint when you are ready.
Create an API key
Sign up on the free plan, then open API keys in the dashboard and create a key. Keys look like km_live_… and are shown once. A key authenticates every /v1 endpoint except account management, which needs a dashboard session (see Authentication).
Install the client
Python 3.9 or newer. The models extra adds NumPy, which uploading a fitted estimator needs; images adds Pillow for photo helpers.
pip install kaimei
pip install "kaimei[models]" # upload fitted estimators (NumPy)
pip install "kaimei[images]" # load and render photos (Pillow)
pip install matplotlib # optional: charts in the dashboard's colours
export KAIMEI_API_KEY=km_live_... # read automatically by Kaimei()Register a model
A model is a feature schema plus a way to run it. The quickest start is a reference model that ships with Kaimei: register it under a slug of your own and it behaves like a model you deployed, complete with reference data for the explanations to compare against.
from kaimei import Kaimei
client = Kaimei() # KAIMEI_API_KEY from the environment
model = client.models.create(
name="Credit risk v3",
slug="credit-risk-v3",
inference={"type": "builtin", "name": "credit-risk"},
)
print(model.id, model.task, [f["name"] for f in model.features])
# mdl_390bd6d9568f626851ef binary_classification ['income', 'credit_score', ...]curl https://api.kaimei.ai/v1/models \
-H "Authorization: Bearer $KAIMEI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Credit risk v3", "slug": "credit-risk-v3",
"inference": {"type": "builtin", "name": "credit-risk"}}'Explain a prediction
Pass any input row. Kaimei runs the model, computes attributions for the explained class, ranks them in top_features and, if you ask, searches for the smallest change that would flip the decision. Features you leave out take their baseline from the schema.
explanation = client.explanations.create(
model="credit-risk-v3",
input={"income": 72000, "credit_score": 681, "utilization": 0.41,
"debt_to_income": 0.38, "loan_amount": 18000, "employment_years": 4,
"num_delinquencies": 1, "age": 34, "home_ownership": "rent"},
method="shap",
options={"counterfactual": True, "frozen_features": ["age"]},
)
print(explanation.output["label"], round(explanation.output["value"], 3))
# decline 0.595
print(explanation.counterfactual["changes"])
# [{'feature': 'credit_score', 'from': 681, 'to': 850, 'output_after': 0.083, 'label_after': 'approve'}]
explanation # in a notebook: the Kaimei card, bars and all
explanation.to_frame() # or the same numbers as a pandas DataFramecurl https://api.kaimei.ai/v1/explanations \
-H "Authorization: Bearer $KAIMEI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "credit-risk-v3",
"input": {"income": 72000, "credit_score": 681, "utilization": 0.41,
"debt_to_income": 0.38, "loan_amount": 18000, "employment_years": 4,
"num_delinquencies": 1, "age": 34, "home_ownership": "rent"},
"method": "shap",
"options": {"counterfactual": true, "frozen_features": ["age"]}
}'{
"object": "explanation",
"id": "exp_7d7add16c796eafac087",
"model_id": "mdl_390bd6d9568f626851ef",
"prediction_id": "pred_2b3edef200ac9fba4e3c",
"method": "shap",
"output": {
"label": "decline",
"class_index": 1,
"probability": 0.5947,
"probabilities": {"approve": 0.4053, "decline": 0.5947},
"target_label": "decline",
"target_index": 1,
"value": 0.5947,
"name": "decision"
},
"attributions": {
"income": -0.052572,
"credit_score": 0.02092,
"utilization": -0.062237,
"debt_to_income": 0.079706,
"loan_amount": -0.022242,
"employment_years": 0.007327,
"num_delinquencies": 0.07484,
"age": 0.012778,
"home_ownership": 0.045748
},
"base_value": 0.4904,
"top_features": [
{
"feature": "debt_to_income",
"attribution": 0.079706,
"value": 0.38,
"share": 0.2107,
"direction": "positive",
"rank": 1
},
{
"feature": "num_delinquencies",
"attribution": 0.07484,
"value": 1,
"share": 0.1978,
"direction": "positive",
"rank": 2
},
{
"feature": "utilization",
"attribution": -0.062237,
"value": 0.41,
"share": 0.1645,
"direction": "negative",
"rank": 3
},
…
],
"counterfactual": {
"found": true,
"changes": [
{
"feature": "credit_score",
"from": 681,
"to": 850,
"output_after": 0.0834,
"label_after": "approve"
}
],
"output_before": 0.5947,
"output_after": 0.0834,
"n_evals": 95,
"target": {"kind": "flip_decision", "threshold": 0.5}
},
"n_evals": 32865,
"latency_ms": 417.8,
"options": {
"counterfactual": true,
"max_changes": 3,
"frozen_features": ["age"],
"log_prediction": true,
"top_k": 8,
"estimator": "kernel",
"exact": true,
"n_coalitions": 510,
"background_rows": 64,
"background_source": "reference_data"
},
"metadata": {"api_key": "km_live_fPaB"},
"created_at": "2026-10-31T22:40:23.705348Z"
}Study the whole model
An analysis runs in the background and writes one insight per step. full runs all seven steps. Poll the analysis, or let the client wait, then read the insights.
analysis = client.analyses.create(model="credit-risk-v3", type="full")
analysis = client.analyses.wait(analysis.id) # polls until completed or failed
print(analysis.status, analysis.n_evals) # completed 101558
for insight in client.insights.list(model="credit-risk-v3").data:
print(f"{insight.type:20} {insight.severity:7} {insight.summary}")
# global_importance info `credit_score` is the most influential input, followed by ...
# drift medium Recent traffic has moderate drift (PSI 0.15). Shifted inputs: ...curl https://api.kaimei.ai/v1/analyses \
-H "Authorization: Bearer $KAIMEI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "credit-risk-v3", "type": "full"}'
# {"object": "analysis", "id": "anl_b8d6...", "status": "queued", ...}
curl https://api.kaimei.ai/v1/analyses/anl_b8d673126dcf3cdbe79a \
-H "Authorization: Bearer $KAIMEI_API_KEY"
# ... "status": "completed", "insight_ids": ["ins_57a8...", ...]
curl "https://api.kaimei.ai/v1/insights?model=credit-risk-v3" \
-H "Authorization: Bearer $KAIMEI_API_KEY"Next Everything you just created is in the dashboard: the model, its explanations with attribution bars and counterfactuals, the insight cards, and the architecture view for uploaded models. The Python client's notebook cards link straight to each record.