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

# Set up Pylva with an AI agent

> Hand this page to an AI coding agent to integrate Pylva end to end: account, API key, SDK install, first event, and verification.

Paste this prompt into your coding agent (Claude Code, Cursor, or similar) from inside your project:

```text theme={null}
Read https://docs.pylva.com/setup-with-ai.md and integrate Pylva into this
project. Follow it exactly. Only ask me for the steps marked HUMAN ACTION
(signing in and pasting an API key).
```

If you just created an API key in the dashboard, the key panel has a **Copy prompt for your AI agent** button that produces this prompt with your key pre-filled.

Everything below this line is written for the agent.

## Agent instructions

You are integrating Pylva, cost infrastructure for AI agent businesses. The SDK meters the host application's LLM and non-LLM usage per customer and per agent step, and reports cost-shaped telemetry. Rules to follow throughout:

* Never print, log, or commit the Pylva API key. Store it in the project's secret store or `.env`, and make sure `.env` is gitignored.
* Never send prompt text, completions, tool arguments, message bodies, emails, or phone numbers in telemetry. Use opaque `customer_id` values and stable `step` labels.
* Pylva instrumentation must fail open: do not let it break the host application.
* The full documentation index is at `https://docs.pylva.com/llms.txt`. You can also connect the docs MCP server: `claude mcp add --transport http pylva-docs https://docs.pylva.com/mcp`.

## Step 1 - Detect the stack

Inspect the project and choose one integration mode:

| Project uses                                                  | Mode                                                                                                                                                |
| ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| TypeScript with `openai`, `@anthropic-ai/sdk`, or Vercel `ai` | Auto-instrumentation via `init`                                                                                                                     |
| Python with `openai` or `anthropic`                           | Auto-instrumentation via `init`                                                                                                                     |
| LangChain or LangGraph (either language)                      | `PylvaCallbackHandler` - do NOT also auto-instrument the same calls, or they will be double counted. See [LangGraph Cost Tracking](sdks/langgraph). |
| Anything else (other providers, non-LLM costs)                | Manual reporting - see [Non-LLM Usage](sdks/non-llm-usage)                                                                                          |

## Step 2 - HUMAN ACTION: account and API key

Tell your human exactly this, then wait:

> I need a Pylva API key.
>
> 1. Sign in at **[https://pylva.com/login](https://pylva.com/login)** (GitHub, Google, or email magic link). Your first sign-in creates a free workspace automatically - no credit card needed. The Free plan includes 100k events/month.
> 2. Open **[https://pylva.com/settings/keys](https://pylva.com/settings/keys)** (after sign-in it lands on Settings -> API keys). You must be the workspace owner.
> 3. Click **Create key** and create it.
> 4. Copy the key immediately - it is shown only once. Put it in `.env` as `PYLVA_API_KEY=pv_live_...` (or paste it to me and I will store it there).
>
> Shortcut: on a brand-new account, the empty dashboard shows a "Get started" checklist with a one-click **Create API key** button.

## Step 3 - Validate the key

Before writing any code:

1. Check the format: `^pv_(live|cli)_[a-f0-9]{8}_[a-f0-9]{32}$`. New keys use `pv_live_*`; legacy `pv_cli_*` keys remain valid after the universal-key migration.
2. Check it live (this endpoint is a safe read):

```bash theme={null}
curl -s -o /dev/null -w "%{http_code}" \
  https://api.pylva.com/api/v1/rules \
  -H "X-Pylva-Key: $PYLVA_API_KEY"
```

`200` means the key is valid. `401` means it is not - re-ask the human (a typo or a revoked key; the body is `{"error":{"code":"INVALID_API_KEY",...}}`). `403 WRONG_SCOPE` only appears on older deployments that still enforce legacy key scopes.

For a richer check, `GET https://api.pylva.com/api/v1/whoami` with the same header returns the workspace, plan tier, and current usage in one call - see [Who am I](api/whoami).

## Step 4 - Install and wire the SDK

The SDK does not read environment variables automatically - always pass the key explicitly from the environment.

### TypeScript

```bash theme={null}
npm install @pylva/sdk   # or: pnpm add @pylva/sdk
```

```ts theme={null}
import { init, track } from "@pylva/sdk";

// Call init at process startup, before serving traffic. Provider calls
// made before init are not recorded.
init({ apiKey: process.env.PYLVA_API_KEY! });

// Wrap each customer-facing operation with customer + step context:
await track(customerId, { step: "draft" }, async () => {
  // existing provider call, unchanged
});
```

### Python

```bash theme={null}
pip install pylva-sdk        # import name is `pylva`
```

```python theme={null}
import os
import pylva
from pylva import track_context

pylva.init(api_key=os.environ["PYLVA_API_KEY"])

with track_context(customer_id=customer_id, step="draft"):
    ...  # existing provider call, unchanged
```

Wiring guidance:

* Find where the application already knows which customer a request belongs to, and wrap at that boundary. Use the application's stable internal user/account ID as `customer_id` (opaque, `[A-Za-z0-9_-]`, max 255 chars) - never an email.
* Use a small set of stable `step` labels named after workflow stages (`retrieve_context`, `draft`, `evaluate`), not per-request values.
* Self-hosted Pylva: pass `endpoint: "https://<your-host>"` / `endpoint="https://<your-host>"` to `init`.

## Step 5 - Verify end to end

1. Optionally prove ingest works before running the app - send one zero-cost test event:

```bash theme={null}
TS=$(date -u +%Y-%m-%dT%H:%M:%SZ)
U() { uuidgen | tr 'A-Z' 'a-z'; }
curl -s https://api.pylva.com/api/v1/events \
  -H "X-Pylva-Key: $PYLVA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"batch_id\":\"$(U)\",\"sdk_version\":\"setup-check\",\"events\":[{
    \"schema_version\":\"1.6\",\"run_id\":\"$(U)\",\"parent_run_id\":null,
    \"trace_id\":\"$(U)\",\"span_id\":\"$(U)\",\"parent_span_id\":null,
    \"customer_id\":\"setup-test\",\"step_name\":\"setup_verification\",
    \"model\":null,\"provider\":null,\"tokens_in\":0,\"tokens_out\":0,
    \"latency_ms\":0,\"tool_name\":null,\"status\":\"success\",
    \"framework\":\"none\",\"instrumentation_tier\":\"reported\",
    \"cost_source\":\"configured\",\"metric\":null,\"metric_value\":null,
    \"stream_aborted\":false,\"abort_savings_usd\":0,
    \"sdk_version\":\"setup-check\",\"timestamp\":\"$TS\"}]}"
```

Expected response: `{"accepted":1,"rejected":0}`. Every field above is required - the API rejects partial events. The full schema is at `https://api.pylva.com/openapi.json`.

2. Run the instrumented code path once for a real (test) customer. The SDK flushes about every 5 seconds; for a short script, flush before exit: `await flush()` (TypeScript) / `await pylva.flush()` (Python, or `asyncio.run(pylva.flush())` in sync scripts).

3. Tell the human:

> Open your Pylva dashboard - once the first event arrives, the "Get started" checklist is replaced by live cost data. You should see customer `setup-test` (and your real test customer) with the steps we instrumented.

If no event appears, work through [Troubleshooting](troubleshooting).

## Step 6 - Production checklist

* Confirm no prompts, completions, or PII are sent in any `metadata` you added ([Privacy and PII](concepts/privacy-and-pii)).
* If the project has non-LLM costs (search, speech, vector DBs), see [Non-LLM Usage](sdks/non-llm-usage) and tell the human which pricing rules to configure in the dashboard.
* Before enabling budget hard stops, read [Budget Enforcement](sdks/budget-enforcement) and [Controls Workflow](concepts/controls-workflow).

## Step 7 - HUMAN ACTION (optional): upgrade the plan

The Free plan (100k events/month) is enough to complete this setup. See [Plans and limits](plans-and-limits) for tier details and what happens at the cap. When usage approaches the cap, tell the human:

> Your Pylva workspace is on the Free plan (100k events/month). To upgrade: **[https://pylva.com/pricing](https://pylva.com/pricing)** - Pro ($49/mo, 1M events) at https://pylva.com/login?next=/subscribe/pro, Scale ($199/mo, 10M events) at [https://pylva.com/login?next=/subscribe/scale](https://pylva.com/login?next=/subscribe/scale).

Payment happens in the browser; do not ask the human for card details.
