Integration guide
Documentation
API contracts, integration patterns, and policy examples for Mandate.
ExecutionRequest Contract
Every adapter builds an ExecutionRequest to send to the gateway. This is the contract that all adapters must implement.
{
"execution_id": "exec_abc123",
"agent_id": "agt_xyz789",
"tool_name": "send_email",
"tool_version": "1.0.0",
"risk_level": "HIGH",
"parameters_hash": "sha256:abc123def456",
"parameters": {
"to": "recipient@example.com",
"subject": "Hello",
"body": "Test email body"
},
"policy_context": {},
"requested_at": "2026-07-13T10:00:00Z",
"session_id": "sess_xyz",
"adapter_signature": "hmac:sig..."
}Field Definitions:
- execution_id: UUID, generated by adapter
- agent_id: Registered Mandate agent identity
- tool_name: Registered tool identifier
- risk_level: LOW | MEDIUM | HIGH | CRITICAL
- parameters_hash: SHA-256 of serialized parameters
- adapter_signature: HMAC of request payload using agent secret
ExecutionResponse Contract
The gateway returns an ExecutionResponse containing the governance decision.
{
"execution_id": "exec_abc123",
"decision": "REQUIRE_APPROVAL",
"policy_ref": "high_risk_requires_approval",
"decided_by": "policy_engine",
"decided_at": "2026-07-13T10:00:01Z",
"result": null,
"receipt_id": "receipt_123",
"walrus_cid": null
}Decision Values:
- APPROVED: Tool may execute immediately
- DENIED: Tool invocation blocked. Check denial_reason.
- REQUIRE_APPROVAL: Tool held pending human approval
- TERMINATED: Operator activated kill switch
Policy Engine (OPA + Rego)
Mandate uses Open Policy Agent (OPA) to evaluate governance rules written in Rego. Every tool invocation is evaluated by these policies.
Example Policies:
Risk Taxonomy:
LOW
search_web
MEDIUM
read_document
HIGH
send_email
CRITICAL
transfer_funds
Python SDK — LangChain Adapter (v1)
The Mandate SDK provides a drop-in adapter for LangChain. Your agent code doesn't change.
from mandate import MandateAdapter
# Initialize adapter
adapter = MandateAdapter(
agent_id="agt_abc123",
api_key="mandate_sk_...",
gateway_url="https://mandate.example.com"
)
# Wrap tools
tools = adapter.wrap([search_web, send_email, transfer_funds])
# Initialize agent as normal
agent = initialize_agent(tools, llm, ...)
# Agent code is unchanged — all tool calls
# now route through the gateway
result = agent.run("Research and email the summary")Under the hood, every tool call triggers an ExecutionRequest → Gateway → Policy Engine → Execution/Denial/Approval flow.
See the gate hold.
The console shows every decision live — approved, denied, held for a human, sealed to a receipt.