JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 21
  • Score
    100M100P100Q81744F
  • License MIT

AI Cost Control Plane — budget guardrails, auto-downgrade, and kill switch for AI API calls

Package Exports

  • caplyr

Readme

Caplyr

AI Cost Control Plane — Stop runaway API bills automatically.

Caplyr wraps your AI client and enforces cost controls based on your project settings in the Caplyr dashboard. Budget guardrails, auto-downgrade, and kill switch — in 2 lines of code.

Install

npm install caplyr

Quick Start

import Anthropic from "@anthropic-ai/sdk";
import { protect } from "caplyr";

// Wrap your client — everything else stays the same
const client = protect(new Anthropic(), {
  apiKey: "caplyr_...",                    // Get yours at https://app.caplyr.com
  mode: "cost_protect",                    // Enforce budget limits
  budget: { monthly: 500, daily: 50 },    // Budget caps in dollars
  fallback: "claude-haiku-4-5-20251001",   // Auto-downgrade target
});

// Use exactly as before — Caplyr is invisible
const response = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello" }],
});

Works with OpenAI too:

import OpenAI from "openai";
import { protect } from "caplyr";

const client = protect(new OpenAI(), {
  apiKey: "caplyr_...",
  mode: "cost_protect",
  budget: { monthly: 500 },
  fallback: "gpt-4o-mini",
});

const response = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

What It Does

Feature Description
Budget Guardrails Daily and monthly caps. Hit the limit → requests are blocked. Budget limits are configured in the Caplyr dashboard and enforced via the SDK.
Auto Downgrade When budget threshold is reached, automatically route to a cheaper model. Your app keeps working.
Kill Switch One-click emergency stop from the dashboard. Halts all AI API calls instantly.

How Enforcement Works

Budget limits are managed server-side in your Caplyr project settings. The SDK sends your configured budget values to the server via heartbeats, and the server returns the current budget status (usage, limits, kill switch state). The SDK enforces limits locally based on that server response — the server is the source of truth, not the local config.

If you set budget in the SDK but have different limits in your dashboard, the dashboard settings take precedence.

Modes

// Alert-only (default): observe and log, don't enforce
protect(client, { apiKey: "..." });

// Cost protect: enforce budget caps and auto-downgrade
protect(client, { apiKey: "...", mode: "cost_protect", budget: { monthly: 500 } });

Tip: Setting budget without specifying mode will automatically enable cost_protect.

Currently Wrapped Endpoints

  • Anthropic: client.messages.create()
  • OpenAI: client.chat.completions.create()

Other endpoints (embeddings, images, Responses API) are not yet wrapped. Streaming requests (stream: true) are passed through but usage tracking may be incomplete.

Configuration

Option Type Default Description
apiKey string required Your Caplyr project API key
budget { monthly?: number, daily?: number } Budget caps in dollars
fallback string auto Fallback model for auto-downgrade
mode "alert_only" | "cost_protect" "alert_only" Enforcement mode
downgradeThreshold number 0.8 Budget % at which downgrade activates
endpoint_tag string Custom tag for cost attribution
dashboardUrl string https://app.caplyr.com Dashboard URL for error messages
endpoint string https://api.caplyr.com API endpoint for heartbeat/ingestion

Handling Blocked Requests

When a request is blocked in cost_protect mode, Caplyr throws a structured error:

try {
  const response = await client.messages.create({ ... });
} catch (err) {
  if (err.caplyr) {
    console.log(err.caplyr.code);        // "BUDGET_EXCEEDED" | "KILL_SWITCH_ACTIVE"
    console.log(err.caplyr.retry_after); // ISO timestamp for next reset
    console.log(err.caplyr.budget_used); // Current spend
  }
}

In alert_only mode, the request proceeds and the onEnforcement callback is fired instead.

Shutdown

Caplyr does not register SIGINT/SIGTERM handlers — your app owns its process lifecycle. Call shutdown() in your own signal handler to flush pending logs before exit:

import { shutdown } from "caplyr";

async function gracefulShutdown() {
  await shutdown();
  process.exit(0);
}

process.on("SIGTERM", gracefulShutdown);
process.on("SIGINT", gracefulShutdown);

License

MIT