Skip to content

Quickstart

Govern an agent in about two minutes.

You can block a real action before you sign up for anything. After that it is three steps, and the middle one is a choice between three ways to connect. They all run the same enforcement engine, so you can start on one and move later without re-authoring anything.

Plain markdown version, for your coding agent

No account needed

Block an action first. No key, no sign-in.

pre_commit runs inside your process. The verdict is computed locally from your state and your rule, with no network call, no model call and no API key, so you can have a real block and the proof of why before you decide whether we are worth an account. Needs causalor 0.2.3 or later.

This is a self-contained demonstration, not your integration. refund_amt is a field we invented so the snippet runs anywhere, on its own, with nothing configured. Your real rules are named after your own tool arguments and Causalor proposes them from the agent's prompt and tool schemas in step 3, so you are not hand-writing constraints. Everything the snippet needs comes from the one import line.

install

pip install causalor

an agent tries to refund 900 against a 500 ceiling

from causalor import Causalor, AgentStateSchema, FormalConstraint

schema = AgentStateSchema(version="1.0.0")
schema.register_field("refund_amt", "number")

c = Causalor(agent_id="refund-agent")
c.set_state_schema(schema)
c.register_constraints([FormalConstraint(
    constraint_id="refund_ceiling", variable="refund_amt",
    operator="<=", threshold=500, scope="SAFETY_CONSTRAINT",
)], replace=True)

result = c.pre_commit("customer-42", "issue_refund", state={"refund_amt": 900})

print(result.allowed)
print(result.proofs[0].proof_string)
print(result.state_snapshot_hash)
print(result.proofs[0].proof_fingerprint)

what you get

False
refund_amt=900 <= 500 -> False
sha256:v1:766ccc520ddeb830efe963d4b45434ab38e58dfd2ce41ffb28e59ad86d1e8586
sha256:v1:eb2c6c2242180923744ba837d376e58601bb02efeeebf60b57dc7aed754ba608

Those two hashes are not illustrations. You will get the same values, on your machine, today or in a year, because the verdict is computed from the state and the rule rather than inferred by a model. If you get something else, that is a bug and we want to hear about it.

The steps below add the half that does need an account: correction while the agent is still reasoning, the audit record, and the hosted routes.

1

Get your key

Sign in to the console. On first sign-in you get a tenant and a cal_ key, shown once. Copy it.

Open the console
2

Connect, whichever way suits you

Pick by trust boundary, not by feature set. Every route gets identical enforcement and the same console.

RouteUse whenYour changeModel traffic
Hosted gatewayTrying it outChange one URLThrough us
In-process SDKNo proxy in the model pathAdd a check at irreversible actionsNever leaves you
Sidecar gatewayProduction, traffic stays in your VPCRun a containerStays in your VPC

Point your existing OpenAI or Anthropic client at the gateway. You bring your own model key in a header; it is forwarded and never stored.

.env

CAUSALOR_API_KEY=cal_...        # your Causalor key (shown once on sign-in)
CAUSALOR_UPSTREAM_KEY=sk-...    # your OpenAI key; never stored

your code

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://gw.causalorlabs.com/v1",
    api_key=os.environ["CAUSALOR_API_KEY"],
    default_headers={
        "X-Causalor-Upstream-Key": os.environ["CAUSALOR_UPSTREAM_KEY"],
        "X-Causalor-Agent": "my-agent",
    },
)

Anthropic works the same way: Anthropic(base_url="https://gw.causalorlabs.com", auth_token="cal_...").

3

Review and activate your guardrails

After the first call your agent appears in the console. Open Guardrails: Causalor reads the agent's own system prompt and tool schemas and proposes typed, checkable constraints bound to your real field names. Edit a limit, drop one, add your own, then Activate. From then on every violating tool call is stopped with a replayable proof, and drift is corrected in flight.

See it work

The same guarantee, provable in ten lines.

Whichever route you pick, a blocked action returns a replayable proof. Here it is at its smallest: an in-process check with no proxy and no model, so you can run it right now.

install

pip install causalor

run this

from causalor import Causalor, AgentStateSchema, FormalConstraint

schema = AgentStateSchema(version="1.0.0")
schema.register_field("refund_amt", "number")

c = Causalor(tenant_id="getting-started")
c.set_state_schema(schema)
c.register_constraints([FormalConstraint(
    constraint_id="refund_ceiling", variable="refund_amt",
    operator="<=", threshold=500, scope="SAFETY_CONSTRAINT",
)], replace=True)

# the agent tries to refund $900
result = c.pre_commit("customer-42", "issue_refund", state={"refund_amt": 900})
print(result.allowed)   # False

real output

allowed: False   status: VIOLATION
proof: refund_amt=900 <= 500 -> False
       constraint_id=refund_ceiling   actual=900   threshold=500
       state_snapshot_hash=sha256:v1:766ccc52...   (same inputs -> same hash)

Run it twice and the hash is identical. That reproducibility is what separates a proof from an opinion, and it is why the record holds up in an audit. On the hosted gateway and the sidecar this exact check runs inline on every tool call, and the proof rides on the response (X-Causalor-Blocked).

Works with any framework

LangChain, LlamaIndex, AutoGen, CrewAI, or your own loop. It governs at the model-call boundary.

Start free