Docs Start here
Connect your code to KIFF in 5 lines
Keep the agent, framework, and function you already run. Immediately before a consequential call, send the proposed action to KIFF and branch on the decision. KIFF returns the decision; your application remains the executor.
Before
Today the action runs as soon as the agent or application asks for it:
result = process_refund(order_id, amount, reason)
There is no independent state check between the proposal and the consequence.
Add the five-line proposal
decision = ask_kiff(
entity_id=order_id, entity_type="Order",
action="ISSUE_REFUND",
parameters={"amount": amount, "reason": reason},
)
Then let the explicit outcome decide whether your existing function runs:
if decision["outcome"] == "allowed":
result = process_refund(order_id, amount, reason)
elif decision["outcome"] == "approval_required":
raise NeedsApproval(decision["reasons"])
elif decision["outcome"] == "blocked":
raise Blocked(decision["reasons"])
else:
raise BadProposal(decision["reasons"])
That boundary is the integration. KIFF does not run process_refund; it
evaluates the proposal against the entity’s current state and domain contract.
Your code runs only after an allowed decision.
The helper
The helper is a normal HTTP call. It requires no model SDK and no change to your agent runtime:
import os
import requests
def ask_kiff(*, entity_id, entity_type, action, parameters, actor_id="agent"):
response = requests.post(
f"{os.environ['KIFF_CLOUD_URL']}/v1/proposals/decide",
headers={"Authorization": f"Bearer {os.environ['KIFF_CLOUD_API_KEY']}"},
json={
"entity_id": entity_id,
"entity_type": entity_type,
"action_name": action,
"actor_id": actor_id,
"parameters": parameters,
},
timeout=5,
)
return response.json()
Configure the hosted endpoint and a key minted in your workspace:
export KIFF_CLOUD_URL=https://api.kiff.dev
export KIFF_CLOUD_API_KEY='kiff_live_...'
Outcomes
| Outcome | Meaning | What your code does |
|---|---|---|
allowed |
The current state and contract permit the action. | Run the function. |
approval_required |
A human authority must decide first. | Hold the action. |
blocked |
State, permissions, or parameters forbid it. | Do not run it. |
invalid |
The proposal or domain configuration is incomplete. | Fix the request or domain. |
limit_exceeded |
The current Cloud allowance is exhausted. | Do not run; surface the billing state. |
Branch on outcome, not only the HTTP status. Allowed, blocked, and
approval-required decisions are all valid answers from the runtime.
What this does—and does not—guarantee
KIFF governs calls routed through this boundary. It does not intercept another code path that bypasses the helper, invent missing domain events, or prove that your downstream function completed successfully. It proves what was proposed, which state and contract were evaluated, and what KIFF authorized before the call.
When you are ready to integrate an existing agent through a framework-native hook instead, use kiff-guard and the framework guides.