> ## Documentation Index
> Fetch the complete documentation index at: https://docs.proofrail.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK API

> Complete reference for every public function, class, and method in the Arclasp SDK

# SDK API

This is the canonical reference for the Python SDK. For tutorial-style introductions see [Quickstart](/quickstart); for framework-specific patterns see the [Framework adapters](/frameworks/langgraph).

## `arclasp.init()`

Configure the SDK. Call once at application startup before opening any chains.

```python theme={null}
arclasp.init(
    api_key: str,
    *,
    environment: str = "production",
    backend_url: str = "http://localhost:8000",
    backend_timeout_seconds: float = 5.0,
    fail_modes: dict[str, str] | None = None,
    fail_mode: str | None = None,
    financial_approval_threshold_usd: float = 5000.0,
    cumulative_financial_threshold_usd: float = 10000.0,
    external_domains_allowlist: list[str] | None = None,
    high_risk_agents: list[str] | None = None,
    default_approval_timeout_hours: float = 24,
    fallback_approvers: list[str] | None = None,
    sensitive_field_patterns: list[str] | None = None,
    sensitive_value_patterns: list[str] | None = None,
    max_payload_string_length: int = 1000,
    enable_local_fast_path: bool = True,
    offline_buffer_max_events: int = 100,
)
```

**Required**

| Parameter | Type  | Description                                                   |
| --------- | ----- | ------------------------------------------------------------- |
| `api_key` | `str` | Your Arclasp API key, prefixed `prail_`. Treated as a secret. |

**Common**

| Parameter                 | Type    | Default                   | Description                                                                                           |
| ------------------------- | ------- | ------------------------- | ----------------------------------------------------------------------------------------------------- |
| `environment`             | `str`   | `"production"`            | Tag attached to every chain. Common values: `"production"`, `"staging"`, `"development"`.             |
| `backend_url`             | `str`   | `"http://localhost:8000"` | Defaults to local development. Pass `"https://api.proofrail.dev"` explicitly to reach hosted Arclasp. |
| `backend_timeout_seconds` | `float` | `5.0`                     | Per-request timeout when calling the backend. Should be raised for high-latency networks.             |

**Failure handling**

| Parameter                   | Type             | Default                                       | Description                                                                                                                                                                                                                                                                  |
| --------------------------- | ---------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fail_modes`                | `dict[str, str]` | See [Configuration](/reference/configuration) | Per-action-class behavior when the backend is unreachable. Keys are action categories (`financial`, `external_communication`, etc.); values are `"deny"` or `"allow"`. A `default` key sets the fallback for unmatched categories.                                           |
| `fail_mode`                 | `str`            | None                                          | Legacy single-string parameter. Treated as `{"default": fail_mode}`. Don't pass both `fail_modes` and `fail_mode`.                                                                                                                                                           |
| `offline_buffer_max_events` | `int`            | `100`                                         | Legacy/deprecated compatibility setting. It does not enable offline governed execution in the current backend-authoritative path — a backend-unavailable action raises `BackendUnavailableError` rather than being buffered. Retained only for call-signature compatibility. |

**Policy thresholds**

| Parameter                            | Type        | Default   | Description                                                                                          |
| ------------------------------------ | ----------- | --------- | ---------------------------------------------------------------------------------------------------- |
| `financial_approval_threshold_usd`   | `float`     | `5000.0`  | Single transactions above this require approval.                                                     |
| `cumulative_financial_threshold_usd` | `float`     | `10000.0` | Chain cumulative financial exposure above this requires approval on the next financial action.       |
| `external_domains_allowlist`         | `list[str]` | None      | Domains agents may communicate with without triggering exfiltration alerts.                          |
| `high_risk_agents`                   | `list[str]` | None      | Agent names treated as high-risk; every action by these agents requires approval.                    |
| `default_approval_timeout_hours`     | `float`     | `24`      | How long approval requests stay valid before timing out.                                             |
| `fallback_approvers`                 | `list[str]` | None      | Email addresses that receive escalations if primary approvers don't respond within half the timeout. |

**Privacy**

| Parameter                   | Type        | Default                                             | Description                                                                                                                |
| --------------------------- | ----------- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `sensitive_field_patterns`  | `list[str]` | See [Sanitization defaults](#sanitization-defaults) | Field-name substrings that get redacted in payloads sent to the backend. Match is case-insensitive substring against keys. |
| `sensitive_value_patterns`  | `list[str]` | See [Sanitization defaults](#sanitization-defaults) | Value prefixes that get redacted. Match uses `str.startswith()` against string values.                                     |
| `max_payload_string_length` | `int`       | `1000`                                              | Strings longer than this are truncated before being sent.                                                                  |

**Performance**

| Parameter                | Type   | Default | Description                                                                                                                                                                                                                                        |
| ------------------------ | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enable_local_fast_path` | `bool` | `True`  | Deprecated. Setting this to `True` emits a `DeprecationWarning` and has no effect — governed `record_agent_action()` execution always requires backend authority; there is no local decision path. Retained only for call-signature compatibility. |

### Returns

A `ChainConfig` instance. Configuration is also stored globally for the process so subsequent `arclasp.Chain(...)` calls use it.

### Sanitization defaults

The SDK uses two separate default lists for redacting sensitive data:

`sensitive_field_patterns` (default — matches against dict keys by case-insensitive substring):

```
["api_key", "password", "secret", "_token", "credit_card", "ssn", "private_key"]
```

`sensitive_value_patterns` (default — matches against string values using `str.startswith()`):

```
["sk_", "pk_", "ghp_", "hf_", "eyJ", "AKIA", "prail_"]
```

Custom patterns you pass via the corresponding kwarg are appended to the defaults.

***

## `arclasp.Chain`

Context manager that opens a chain and records every action within it. Use as an async or sync context manager depending on your code.

```python theme={null}
class Chain:
    def __init__(
        self,
        name: str,
        metadata: dict | None = None,
        policy_config: dict | None = None,
    ): ...

    async def __aenter__(self) -> "Chain": ...
    async def __aexit__(self, exc_type, exc_val, exc_tb) -> bool: ...

    def __enter__(self) -> "Chain": ...
    def __exit__(self, exc_type, exc_val, exc_tb) -> bool: ...

    def add_financial_threshold(
        self, usd: float, notify: list[str] | None = None, deny: bool = False,
    ) -> None: ...

    async def record_agent_action(...) -> PolicyDecision: ...
```

### Constructor parameters

| Parameter       | Type   | Description                                                                                                                                                                                                                   |
| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`          | `str`  | Human-readable identifier shown in the dashboard. Conventional: hyphen-separated lowercase (`"vendor-purchase"`, `"customer-onboarding"`).                                                                                    |
| `metadata`      | `dict` | Arbitrary JSON-serializable key/value pairs. Attached to the chain and visible in receipts. Stored as opaque data — the SDK does not interpret keys within it.                                                                |
| `policy_config` | `dict` | Per-chain policy override, merged key-by-key over the org-wide config (chain value wins where set). Build it with `add_financial_threshold()`, or pass the recognized keys directly. Must be set before the chain is started. |

### Lifecycle

On `__aenter__` / `__enter__`: a chain record is created on the backend; the chain ID is available as `chain.chain_id` after entry.

On `__aexit__` / `__exit__`: the SDK calls `POST /v1/chains/{chain_id}/complete`, which seals the chain and triggers receipt generation on the backend. If exit was triggered by an exception, the chain is marked accordingly and the receipt reflects the failure mode.

### Methods

#### `record_agent_action()` (async)

```python theme={null}
async def record_agent_action(
    self,
    agent_name: str,
    action_type: str,
    action_name: str,
    payload: dict | None = None,
    parent_agent_name: str | None = None,
) -> PolicyDecision
```

Record an action and receive a policy decision. There is no `metadata` parameter on this method — action-level metadata is not currently supported; chain-level `metadata` is set once on `Chain(...)`.

| Parameter           | Type   | Description                                                                                       |
| ------------------- | ------ | ------------------------------------------------------------------------------------------------- |
| `agent_name`        | `str`  | Identifier for the agent taking the action.                                                       |
| `action_type`       | `str`  | Category of action. Common values: `tool_call`, `llm_call`, `state_update`.                       |
| `action_name`       | `str`  | Specific name within the type. For `tool_call`, the tool name (e.g., `search_web`, `send_email`). |
| `payload`           | `dict` | The action's inputs. Sanitized before sending.                                                    |
| `parent_agent_name` | `str`  | Agent that delegated to this one, if any. Used for tracking hierarchical workflows.               |

Returns a `PolicyDecision` object with `policy_decision="allow"`. Blocks until resolution on `require_approval` (returns `allow` with `decision_source="human_approval"` once approved). Raises `ActionDeniedError` on `deny` or human denial, `ChainTimeoutError` if the local polling window expires, and `ChainAutoPausedError` if the backend halts the chain for a runaway-limit trigger.

### `chain.chain_id`

The backend-assigned chain UUID. Available after `__aenter__` / `__enter__`. Useful for logging or cross-system references:

```python theme={null}
async with arclasp.Chain("workflow") as chain:
    logger.info("Started chain", extra={"chain_id": chain.chain_id})
```

***

## `arclasp.PolicyDecision`

Returned by `record_agent_action` when the action is allowed (including after a human approval resolves).

```python theme={null}
@dataclass
class PolicyDecision:
    policy_decision: str                          # "allow" | "allow_with_flag" | "require_approval" | "deny"
    decision_reason: str = ""
    decision_source: str = "backend_evaluation"
    policy_name: str | None = None
    kill_switch_active: bool = False
    pause_reason: str | None = None
    remediation: str | None = None
    docs_url: str | None = None
    evaluation_mode: str | None = None
    shadow_decision: str | None = None
    estimated_cost_usd: float | None = None
    auto_paused: bool = False
```

| Attribute            | Type    | Description                                                                                                                                                                                                                                                                                     |
| -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `policy_decision`    | `str`   | The field can hold `"allow"`, `"allow_with_flag"`, `"require_approval"`, or `"deny"` — but `record_agent_action` only ever returns the object with `"allow"` or `"allow_with_flag"` here: it raises on `deny`, and blocks until resolution (then returns with `"allow"`) on `require_approval`. |
| `decision_reason`    | `str`   | Human-readable explanation if a policy matched. Empty string when no reason applies.                                                                                                                                                                                                            |
| `decision_source`    | `str`   | Where the decision came from: `"backend_evaluation"` for a direct policy decision, or `"human_approval"` once a `require_approval` gate has been resolved by a reviewer.                                                                                                                        |
| `policy_name`        | `str`   | Name of the matched policy, if any.                                                                                                                                                                                                                                                             |
| `kill_switch_active` | `bool`  | True if the org's kill switch was found active during evaluation (in which case denials raise `ArclaspKillSwitchError`).                                                                                                                                                                        |
| `pause_reason`       | `str`   | If the org was paused, the reason supplied at activation.                                                                                                                                                                                                                                       |
| `remediation`        | `str`   | Suggested fix when a policy matched.                                                                                                                                                                                                                                                            |
| `docs_url`           | `str`   | Link to docs for this kind of decision.                                                                                                                                                                                                                                                         |
| `evaluation_mode`    | `str`   | `"enforce"` or `"shadow"` for the matching policy.                                                                                                                                                                                                                                              |
| `shadow_decision`    | `str`   | When `evaluation_mode` is `"shadow"`, the decision the policy would have made in enforce mode.                                                                                                                                                                                                  |
| `estimated_cost_usd` | `float` | For LLM call events, the computed cost.                                                                                                                                                                                                                                                         |
| `auto_paused`        | `bool`  | True if the chain auto-paused at this action (event-count, duration, or token-budget limit).                                                                                                                                                                                                    |

***

## Framework adapters

Each adapter exposes a `govern()` function that wraps an existing framework object. See the framework-specific pages for usage details.

### `arclasp.langgraph.govern()`

```python theme={null}
def govern(
    compiled_graph,
    chain_name: str = "langgraph_workflow",
    metadata: dict | None = None,
) -> GovernedGraph
```

See [LangGraph adapter](/frameworks/langgraph).

### `arclasp.langchain.govern()`

```python theme={null}
def govern(
    agent_executor_or_chain,
    chain_name: str = "langchain_workflow",
    metadata: dict | None = None,
) -> GovernedChain
```

The `agent_name` for recorded events is derived from `type(executor).__name__` at wrap time — it isn't a `govern()` parameter.

See [LangChain adapter](/frameworks/langchain).

### `arclasp.crewai.govern()`

```python theme={null}
def govern(
    crew,
    chain_name: str = "crewai_workflow",
    metadata: dict | None = None,
) -> GovernedCrew
```

See [CrewAI adapter](/frameworks/crewai).

### `arclasp.mcp.ArclaspMcpAdapter`

```python theme={null}
class ArclaspMcpAdapter:
    def __init__(
        self,
        chain: arclasp.Chain,       # an already-entered chain
        agent_name: str = "mcp-agent",
        parent_agent_name: str | None = None,
    ): ...

    async def handle_tool_call(self, tool_name: str, arguments: dict, handler) -> Any: ...
    def tool(self, tool_name: str): ...  # decorator
    def install(self, server) -> None: ...  # unsupported — always raises RuntimeError
```

`install()` is not supported with `mcp >= 1.0` and always raises `RuntimeError`; it is kept only for signature compatibility. Wire governance through `handle_tool_call()` inside your own `@server.call_tool()` handler instead. See [MCP adapter](/frameworks/mcp).

***

## `arclasp.client.verify_receipt_v2()`

Verify receipt integrity through the authenticated v2 API.

```python theme={null}
async def verify_receipt_v2(receipt_id: str) -> AuthenticatedReceiptVerificationResponse
```

Receipt verification is server-attested integrity verification. It is not an independent offline proof export.

## `arclasp.client.verify_approval_v2()`

Verify an approval through the authenticated role-aware v2 API.

```python theme={null}
async def verify_approval_v2(approval_id: str) -> AuthenticatedApprovalVerificationResponse
```

The response separates integrity, signature, key-trust, timestamp-anchor, and overall status. Member and admin responses differ based on role.

## Public verification token helpers

```python theme={null}
async def list_public_verification_tokens(...) -> PublicVerificationTokenListResponse
async def issue_public_verification_token(...) -> PublicVerificationTokenIssueResponse
async def revoke_public_verification_token(...) -> PublicVerificationTokenRevokeResponse
async def verify_public_token(token: str) -> PublicVerificationTokenVerifyResponse
```

`issue_public_verification_token()` returns the plaintext public token once. List and revoke helpers do not return plaintext tokens or token hashes. `verify_public_token()` calls `GET /public/v2/verify/{opaque_token}` and raises a sanitized verification error if the token is unavailable.

## `arclasp.client.verify_receipt()`

Legacy receipt verification helper.

```python theme={null}
async def verify_receipt(receipt_id: str) -> ReceiptVerifyResponse
```

This helper remains temporarily available for compatibility with the legacy `GET /v1/receipts/{receipt_id}/verify` route and emits a deprecation warning. New callers should use `verify_receipt_v2()`.

## See [Verification](/concepts/verification) for current verification routes and migration guidance.

## Exceptions

All exceptions live in `arclasp.exceptions`. The base for policy-driven errors is `ArclaspPolicyError`.

```
ArclaspPolicyError                # base for policy denials
├── ActionDeniedError               # Policy or human reviewer denied
├── PolicyViolationError            # Policy condition violated outside main eval path
└── ArclaspKillSwitchError        # Org kill switch is active

Exception
├── BackendUnavailableError         # Backend unreachable, fail_mode=deny
├── ChainTimeoutError               # Chain exceeded configured timeout
└── ChainAutoPausedError            # Auto-pause rule fired (events, duration, tokens)
```

See [Exceptions reference](/reference/exceptions) for attributes and handling patterns.

***

## Version compatibility

The SDK requires Python 3.10 or later (enforced at install time by pip). Supported framework version ranges are pinned in `sdk/pyproject.toml`; install Arclasp with a compatible version of your framework already installed. See [Limitations](/limitations) for the current compatibility matrix.

## Where to go next

<CardGroup cols={2}>
  <Card title="Configuration" icon="gear" href="/reference/configuration">
    Detailed walkthrough of every init() option.
  </Card>

  <Card title="Exceptions" icon="triangle-exclamation" href="/reference/exceptions">
    All exception types and how to handle them.
  </Card>

  <Card title="Framework adapters" icon="puzzle-piece" href="/frameworks/langgraph">
    Per-framework usage and edge cases.
  </Card>

  <Card title="Limitations" icon="circle-info" href="/limitations">
    What Arclasp does and doesn't do at current version.
  </Card>
</CardGroup>
