> ## 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.

# Quickstart

> From install to your first governed chain in under 10 minutes

# Quickstart

This walks through governing a simple agent workflow from scratch. By the end, you'll have a chain running with policy evaluation, a denied action raising an exception, and a receipt you can verify through our public endpoint.

The whole thing takes about 10 minutes if you have Python 3.10+ ready.

## 1. Install and configure

```bash theme={null}
pip install git+https://github.com/TOAAiV/proofrail
```

Get your API key from the [ProofRail dashboard](https://app.proofrail.dev) and save it to a `.env` file:

```bash theme={null}
# .env
PROOFRAIL_API_KEY=prail_your_key_here
```

## 2. Write a minimal governed workflow

Create a file called `first_chain.py`:

```python theme={null}
import asyncio
import os
from dotenv import load_dotenv

import proofrail

load_dotenv()
proofrail.init(api_key=os.environ["PROOFRAIL_API_KEY"])


async def main():
    async with proofrail.Chain("first-workflow") as chain:
        # A safe action — should resolve via the local fast-path
        decision = await chain.record_agent_action(
            agent_name="research-agent",
            action_type="tool_call",
            action_name="search_web",
            payload={"query": "vendor pricing for office chairs"},
        )
        print(f"Search action: {decision.policy_decision} (via {decision.decision_source})")

        # A small purchase — should be allowed
        decision = await chain.record_agent_action(
            agent_name="purchase-agent",
            action_type="tool_call",
            action_name="place_order",
            payload={"amount_usd": 150.00, "vendor": "office-supplies.com"},
        )
        print(f"Small purchase: {decision.policy_decision} (via {decision.decision_source})")


asyncio.run(main())
```

Run it:

```bash theme={null}
python first_chain.py
```

You should see two `allow` decisions, the first via `local_fast_path` and the second via `backend_evaluation` (because it contains financial data, which bypasses the fast-path).

## 3. Trigger an approval gate

Now bump that purchase amount up past the default approval threshold:

```python theme={null}
decision = await chain.record_agent_action(
    agent_name="purchase-agent",
    action_type="tool_call",
    action_name="place_order",
    payload={"amount_usd": 7500.00, "vendor": "office-supplies.com"},
)
```

Run the script again. This time, the call will block — the policy engine has decided this transaction needs human approval. You'll see logs like:

```
Waiting for approval on chain abc-123... (timeout=24h)
```

Check your email — the approver address you configured (or your account email by default) just received a message with the chain context and an approve/deny link.

Click "Approve" in the email. Your terminal output should resume:

```
Large purchase: allow (via human_approval)
```

If you click "Deny" instead, the script raises `ActionDeniedError` with the approver's notes attached.

## 4. View the chain in your dashboard

Open [app.proofrail.dev](https://app.proofrail.dev) and navigate to **Chains**. Your `first-workflow` chain should be at the top of the list with three events recorded:

* search\_web (allow, local fast-path)
* place\_order \$150 (allow, backend)
* place\_order \$7,500 (require\_approval → human\_approval allow)

Click into the chain to see the full event timeline, the cumulative metrics, and the receipt that was generated when the chain completed.

## 5. Verify a receipt

Receipts are HMAC-signed and hash-chained across your organization. You can verify any receipt through our public verification endpoint — no account required.

From the dashboard, find your chain's receipt and copy its receipt ID. Then:

```python theme={null}
import proofrail

proofrail.init(api_key=os.environ["PROOFRAIL_API_KEY"])

# Verify a specific receipt
result = await proofrail.client.verify_receipt("rcp_abc123...")
print(f"Valid: {result.valid}")
print(f"Receipt number: {result.receipt_number}")
```

`valid=True` means the receipt's data matches its signature. Tampering with the receipt content would flip this to `False`.

## You just shipped governance

In under 10 minutes you went from zero to:

* A real agent workflow under chain-level policy
* One action resolved locally for speed (fast-path)
* One action sent to the backend for authoritative evaluation
* One action gated for human approval, resumed cleanly after the approver clicked through
* A tamper-evident audit receipt verifiable through our public endpoint

That's the whole core surface. Everything beyond this — framework adapters, custom policies, kill switch, cost tracking — is configuration on top of this same pattern.

## Where to go next

<CardGroup cols={2}>
  <Card title="Chain-level governance" icon="link" href="/concepts/chain-level-governance">
    The concept that makes ProofRail different from per-call governance tools.
  </Card>

  <Card title="LangGraph adapter" icon="diagram-project" href="/frameworks/langgraph">
    Wrap a compiled LangGraph graph with one line.
  </Card>

  <Card title="MCP adapter" icon="plug" href="/frameworks/mcp">
    Govern MCP server tool calls.
  </Card>

  <Card title="Configuration" icon="gear" href="/reference/configuration">
    Tune thresholds, fail modes, approvers, and more.
  </Card>
</CardGroup>

<Note>
  **Trouble running this?** The most common issues are forgetting `dotenv` (env var not loaded), running Python 3.9 or earlier (3.10+ required), or hitting Supabase free-tier latency on the first chain start (give it a few seconds). If your approval email never arrives, check your spam folder and verify your approver address in the dashboard.
</Note>
