Developer docs

Ship an agent with a budget
in three lines.

@kyvernlabs/sdk is the official client for KyvernLabs vaults. It talks to the same API that powers the dashboard — install, paste, ship.

Setup

Install

bash
1npm install @kyvernlabs/sdk
2# or
3pnpm add @kyvernlabs/sdk
4# or
5yarn add @kyvernlabs/sdk

Node 18+ or any runtime with a global fetch. The package has zero runtime dependencies.

0 → first payment

Quickstart

1

Create a vault

Head to /vault/new and walk through the 5-step onboarding. You'll receive a one-time kv_live_… agent key — copy it somewhere safe.
2

Set the env var

bash
1export KYVERNLABS_AGENT_KEY=kv_live_...
2export VAULT_ID=vlt_...
3

Pay a merchant

ts
1import { Vault } from "@kyvernlabs/sdk";
2
3const vault = new Vault({
4 agentKey: process.env.KYVERNLABS_AGENT_KEY!,
5});
6
7const res = await vault.pay({
8 merchant: "api.openai.com",
9 recipientPubkey: "5eyKt4yXtD9Wz8gPWs9fEUv9AQCoTFv9o6xAiBm1Kjv6",
10 amount: 0.12,
11 memo: "forecast lookup",
12});
13
14if (res.decision === "blocked") {
15 console.log("refused:", res.code, res.reason);
16} else {
17 console.log("settled:", res.tx.signature);
18}
Method

vault.pay()

Ask the vault to pay a merchant. Policy is enforced server-side — every call is budgeted, rate-limited, and matched against the allowlist before Squads co-signs.

ts
1await vault.pay({
2 merchant: string, // URL or host, normalized server-side
3 recipientPubkey: string, // Solana pubkey of the USDC recipient
4 amount: number, // USD (USDC mint, 6 decimals)
5 memo?: string, // required if vault.requireMemo === true
6}): Promise<PayResult>

Returns { decision: "allowed" | "blocked", … }. Pass throwOnBlocked: true to the constructor if you'd rather catch KyvernPaymentBlocked.

Method

vault.status()

Snapshot of the vault — budget utilization, velocity, and the most recent payments. This is what the owner dashboard uses on every poll.

ts
1const s = await vault.status({ vaultId: "vlt_abc", limit: 20 });
2
3console.log(`${s.budget.spentToday} / ${s.budget.dailyLimitUsd} USD today`);
4console.log(`${s.velocity.callsInWindow} calls in last ${s.velocity.velocityWindow}`);
5for (const p of s.payments) {
6 console.log(p.createdAt, p.merchant, p.amountUsd, p.status, p.reason ?? "");
7}
Emergency stop

Kill switch

Pause blocks every future payment instantly. Existing policies stay intact — resume any time. Pause/resume require the ownerWallet at construction time.

ts
1const owner = new Vault({
2 agentKey: process.env.KYVERNLABS_AGENT_KEY!,
3 ownerWallet: "5eyKt4yXtD9Wz8gPWs9fEUv9AQCoTFv9o6xAiBm1Kjv6",
4});
5
6await owner.pause({ vaultId: "vlt_abc" }); // agent is dead to the world
7await owner.resume({ vaultId: "vlt_abc" }); // back online
Reference

Errors & decisions

Every pay() resolves with a decision. Blocks are not exceptions by default — they're data. The code is stable across versions so you can branch on it.

CodeWhen
vault_pausedOwner hit the kill switch.
amount_exceeds_per_txA single payment exceeds the per-transaction ceiling.
amount_exceeds_dailyToday's spend plus this payment exceeds the 24h budget.
amount_exceeds_weeklyThis week's spend plus this payment exceeds the 7d ceiling.
merchant_not_allowedMerchant isn't in the vault's allowlist.
velocity_capToo many calls inside the velocity window.
missing_memoVault requires a memo and the payment didn't include one.
invalid_amountNon-positive or non-finite amount.
invalid_merchantMerchant string couldn't be parsed as a host or URL.

Auth failures throw KyvernAuthError (401). Network or 5xx errors throw KyvernError with the HTTP status attached.

Prefer curl?

REST API

The SDK is a thin client. Here's the raw API for polyglot teams.

bash
1curl -X POST https://kyvernlabs.com/api/vault/pay \
2 -H "Authorization: Bearer kv_live_..." \
3 -H "Content-Type: application/json" \
4 -d '{
5 "merchant": "api.openai.com",
6 "recipientPubkey": "5eyKt4yXtD9Wz8gPWs9fEUv9AQCoTFv9o6xAiBm1Kjv6",
7 "amountUsd": 0.12,
8 "memo": "forecast lookup"
9 }'

200 = settled · 402 = policy block · 401 = bad key · 400 = validation · 502 = Squads failure

Keep building

What's next