Documentation
01 Introduction
Checkpoint is the control layer for AI agents. It checks any action your agent is about to take, evaluates it against your policy, and returns a verdict before the action runs: allow, stop, or escalate. Every decision is written to a tamper-evident audit log.
You write a policy once. Checkpoint enforces it everywhere your agent acts, whether you call it directly, gate your tools, or run through an agent framework.
02 The problem
AI agents are starting to move money, ship code, touch production systems, and act on data. They run in loops, call tools, and take actions a human never directly approves. Most are deployed with no layer deciding what they are allowed to do.
Logging after the fact tells you what already happened. Checkpoint decides before the action runs. It is the gate between an agent choosing to act and the action actually firing.
03 How it works
Every action your agent attempts is checked against a policy, an ordered set of rules where the first match decides the verdict. If nothing matches, the action is allowed.
- Check. Your code calls
cp.check(action, payload)before the action runs. - Evaluate. The payload is tested against your rules, locally or on the hosted service.
- Decide. A verdict comes back: allow, stop, or escalate.
- Record. The decision is appended to a hash-chained audit log.
04 Verdicts
Every check returns one of three verdicts.
05 Install
Checkpoint ships for Python and TypeScript. Install the SDK:
# Python
pip install "git+https://github.com/CheckPointAl/CheckPoint.git#subdirectory=sdk/python"
# TypeScript
npm install checkpoint-sdk
Optional: hosted key
Local mode needs nothing. For the hosted service, set your project key:
export CHECKPOINT_API_KEY="cp_live_xxx"
export CHECKPOINT_BASE_URL="https://your-backend"
06 Quickstart
Wrap any action your agent takes with cp.check(). It returns a verdict before the action runs. A stop raises CheckpointStopped, so the protected code below it never executes.
import checkpoint as cp
from checkpoint import Policy, rule
cp.set_policy(Policy([
rule("transfer_funds", when="amount > 25000", verdict="escalate", to="cfo"),
rule("export_records", when="pii_rows > 10000", verdict="stop"),
]))
def process_payment(amount, recipient):
cp.check("transfer_funds", {"amount": amount})
transfer_funds(amount, recipient) # only reached if allowed
Reading the verdict instead of raising
Pass raise_on_stop=False to handle the outcome yourself.
verdict = cp.check("transfer_funds", {"amount": amount}, raise_on_stop=False)
if verdict.allowed:
transfer_funds(amount, recipient)
else:
log(verdict.reason) # stopped or escalated
07 TypeScript
The TypeScript SDK has the same API. check() is async and resolves to a verdict.
import { check, setPolicy, Policy, rule } from "checkpoint-sdk";
setPolicy(new Policy([
rule("transfer_funds", { when: "amount > 25000", verdict: "escalate", to: "cfo" }),
rule("export_records", { when: "pii_rows > 10000", verdict: "stop" }),
]));
await check("transfer_funds", { amount }); // throws CheckpointStopped if stopped
08 Policy rules
A rule names an action, a condition over the payload, and a verdict. Rules are checked top to bottom; the first match wins. Conditions are short expressions evaluated safely, no arbitrary code runs.
Policy([
rule("transfer_funds", when="amount > 25000", verdict="escalate", to="cfo"),
rule("export_records", when="pii_rows > 10000", verdict="stop"),
rule("send_email", when="recipient_count > 1000", verdict="stop"),
rule("deploy", when="env == 'production'", verdict="escalate", to="eng_lead"),
])
Rule anatomy
| Field | Meaning |
|---|---|
| action | The checked action this rule applies to. |
| when | A condition over the payload. Supports comparisons, and/or/not, and registered helpers. |
| verdict | stop or escalate. Allow is the default when no rule matches. |
| to | Who an escalation routes to. Ignored for stop rules. |
| channel | Where the escalation is sent: slack, teams, or email. |
09 Escalation
An escalate verdict means the action needs a human before it can run. In local mode you supply a handler that decides; in hosted mode escalations surface in the dashboard and route to the person named in the rule.
cp.configure(escalation_handler=lambda v: ask_human(v.reason))
If no handler is set, an escalate verdict is returned to your code unresolved, so you can route it however you like. Nothing runs until it is approved.
10 Audit log
Every verdict is written to a hash-chained, tamper-evident log. Each entry hashes the previous one, so altering any past record breaks the chain and tampering is detectable.
for entry in cp.audit_log.entries():
print(entry["log_id"], entry["verdict"], entry["action"])
cp.audit_log.verify() # True if the chain is intact
11 Agent frameworks
Gate your agent's tools so cp.check() fires automatically before each one runs. A stopped action raises before the tool executes; an escalation returns the verdict without running it.
Any tool, with the decorator
from checkpoint.integrations import guard
@guard("transfer_funds")
def transfer_funds(amount, to):
...
transfer_funds(amount=80000, to="acct_1") # checked before it runs
LangChain, CrewAI, AutoGen
from checkpoint.integrations import (
wrap_langchain_tool, wrap_crewai_tool, register_autogen,
)
guarded = wrap_langchain_tool(my_tool, action="transfer_funds")
guarded = wrap_crewai_tool(my_tool, action="transfer_funds")
register_autogen(transfer_funds, action="transfer_funds",
agent=assistant, executor=user_proxy)
Each framework is imported only when you call its wrapper. Installing the SDK pulls in nothing.
12 LLM tool calls
If you call a model directly instead of through a framework, the model proposes tool calls and your code runs them. Checkpoint checks each proposed call before you execute it. Works with OpenAI, Anthropic, and Gemini.
from checkpoint.llm import check_openai_tool_calls
resp = client.chat.completions.create(model="gpt-4", messages=msgs, tools=tools)
for c in check_openai_tool_calls(resp):
if c.allowed:
result = run_tool(c.name, c.args)
else:
result = c.verdict.reason # stopped or escalated, tool not run
Each result is a CheckedCall with .allowed, .stopped, .escalated, the parsed .args, the provider's call .id, and the full .verdict. Use check_anthropic_tool_calls and check_gemini_function_calls for the others. OpenAI-compatible APIs (Mistral, Groq, Azure OpenAI, OpenRouter) work with the OpenAI helper.
13 Hosted mode
By default the SDK runs a local in-memory engine, so you can use it with no account. Point it at the hosted backend to share policy and a durable audit log across your team.
cp.configure(
api_key="cp_live_...",
base_url="https://your-backend",
)
With base_url set, check() calls POST /v1/check on the server. If the service is unreachable it fails closed (stops the action) by default. The public API is identical in both modes. Hosted mode unlocks with the paid tiers, see pricing.
14 SDK reference
cp.check(action, payload, raise_on_stop=True)
| Argument | Description |
|---|---|
| action | Name of the action being checked. |
| payload | Dict of action arguments the rules read. |
| raise_on_stop | If True (default), a stop raises CheckpointStopped. |
Verdict object
| Field | Description |
|---|---|
| .verdict | One of allow, stop, escalate. |
| .allowed | True if the action may proceed. |
| .stopped / .escalated | Booleans for the other outcomes. |
| .reason | Human-readable explanation of the decision. |
| .rule | The rule that fired, or None. |
| .log_id | The audit log entry id for this verdict. |
15 Error handling
A stop raises CheckpointStopped; both it and other SDK errors derive from CheckpointError.
from checkpoint import CheckpointStopped
try:
cp.check("export_records", {"pii_rows": 45000})
except CheckpointStopped as e:
print(e.reason, e.rule)
16 FAQ
Does it slow my agent down?
In local mode a check is an in-process policy evaluation, effectively instant. In hosted mode it is a single network round trip.
Where do policy rules live?
In local mode, in your code. In hosted mode, stored per project on the service and shared across your team, so the same verdict applies for everyone.
What happens to an escalated action while it waits?
It does not run. Your code receives an escalate verdict, or your handler resolves it. Nothing fires until a human approves.
Is the audit log tamper-evident?
Yes. Each entry is hash-chained to the previous one. Altering any past entry breaks the chain, which verify() detects.
Can I try it without a backend?
Yes. Local mode needs no account, no key, and no network. Install, set a policy, and start checking.
What is $CHECKPOINT?
$CHECKPOINT is the token built on Base. It is how the paid tiers work: Silver and Gold are unlocked with the token. The SDK itself runs in local mode for free, with no token required.
Do I need the token to use Checkpoint?
Yes. All tiers, Bronze, Silver, and Gold, unlock with the $CHECKPOINT token on Base. You can install the SDK and run it in local mode to evaluate it, and connect your wallet to get ready. See pricing for what each tier includes.
What happens to tokens used for tiers?
Tokens used to pay for tiers go to a treasury and are burned, permanently removed from circulation with every purchase.
How are fees used?
Running a low-latency control layer that teams depend on has real ongoing costs: the hosted verdict service, the durable audit-log storage, the policy backend, and the compute behind each check, plus hosting, databases, and bandwidth. Tokens used for paid tiers are burned, permanently removed from circulation with every purchase.