Top-ups

An agent adds USDC to a balance from its own wallet. A card payment is a person, on Billing or through a link your code fetches.

Balance

GET /api/v1/balance returns the balance and the ways to add to it. These calls use the console (https://app.klinn.dev), not the model API host. The older /v1/… paths keep working.

From an agent's wallet

POST /api/v1/topup?amount=20 is an x402 payment. The server answers 402 with the price, the agent's wallet signs, and the credit lands once the USDC transfer settles on Base. Unlike one completion, a top-up settles before it answers, and the response carries PAYMENT-RESPONSE with the transaction. Amounts are from $1 to $1000.

import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";

// The agent's own wallet, holding USDC on Base
const wallet = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY);
const pay = wrapFetchWithPaymentFromConfig(fetch, {
  schemes: [{ network: "eip155:*", client: new ExactEvmScheme(wallet) }],
  spendControls: { maxAmountPerPayment: "$25" },
});

const res = await pay("https://app.klinn.dev/api/v1/topup?amount=20", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.KLINN_API_KEY}` },
});
console.log(await res.json()); // { creditedUsd: 20, balanceUsd: …, transaction: "0x…" }

The private key stays on the agent. Klinn receives the USDC at one treasury address and credits the account that owns the API key.

A card link

POST /api/v1/topup/checkout returns a Stripe link for a person to pay. It credits the same balance as Add credits on Billing. Stripe handles the card. Card top-ups are from $5 to $1000: a smaller amountUsd is raised to $5, and the person can change the amount on Stripe's page.

curl https://app.klinn.dev/api/v1/balance -H "Authorization: Bearer $KLINN_API_KEY"

curl https://app.klinn.dev/api/v1/topup/checkout -H "Authorization: Bearer $KLINN_API_KEY" \
  -H "Content-Type: application/json" -d '{ "amountUsd": 50 }'
# → { "url": "https://checkout.stripe.com/…", "amountUsd": 50, "minUsd": 5, "maxUsd": 1000 }