How Paperclip Tracks Costs for Agents and Tasks: A Complete Technical Guide

Paperclip tracks agent and task costs by recording every token usage and monetary expense as a cost event, then aggregating these events in real-time to update monthly spend counters, enforce budget limits, and provide detailed reporting APIs.

The Paperclip platform implements a comprehensive cost accounting system that gives operators full visibility into LLM spending. This article explains how the open-source codebase captures, stores, aggregates, and enforces costs for AI agents and their tasks.

Cost Event Creation: The Foundation of Tracking

Every cost-tracking flow begins with a cost event. When an agent completes work, the adapter extracts critical metadata from the LLM response: provider, model, input/output token counts, and dollar cost. This data is sent to the server's POST /api/companies/{companyId}/cost-events endpoint.

The CLI supports manual event creation via paperclip cost event:create, which is useful for testing or integrating non-standard providers:


# Record a cost event manually (CLI)

paperclip cost event:create \
  -C my-company-id \
  --payload-json '{
    "agentId": "agent-123",
    "provider": "openai",
    "model": "gpt-4o-mini",
    "inputTokens": 1350,
    "outputTokens": 420,
    "costCents": 5,
    "billingType": "metered_api"
  }'

According to the Paperclip source code in server/src/services/costs.ts, the costService.createEvent function handles validation, persistence, and downstream processing in a single transaction.

Database Schema for Cost Events

Cost events are stored in the cost_events table, defined in packages/db/src/schema/cost_events.ts. The schema captures granular details for auditability and flexible aggregation:

Column Purpose
companyId Organization scope for multi-tenant isolation
agentId Agent responsible for the expense
issueId / projectId Optional task-level attribution
provider LLM vendor (e.g., "openai", "anthropic")
biller Entity charging for usage (may differ from provider)
billingType Pricing model: "metered_api", "subscription", etc.
model Specific model identifier
inputTokens / cachedInputTokens / outputTokens Token breakdown
costCents Monetary value in smallest currency unit
occurredAt Precise timestamp for temporal queries

The schema includes composite indexes on (companyId, agentId, occurredAt) and on provider/biller to enable fast monthly aggregations and filtering.

Real-Time Monthly Spend Aggregation

Immediately after inserting a cost event, costService.createEvent recomputes month-to-date totals. This eager aggregation pattern maintains live spend counters without requiring expensive queries at read time:

// Server-side creation (excerpt from costService.createEvent)
await db
  .insert(costEvents)
  .values({
    ...data,
    companyId,
    biller: data.biller ?? data.provider,
    billingType: data.billingType ?? "unknown",
    cachedInputTokens: data.cachedInputTokens ?? 0,
  })
  .returning()
  .then(rows => rows[0]);

// Update monthly aggregates
await db.update(agents).set({
  spentMonthlyCents: agentMonthSpend,
  updatedAt: new Date(),
}).where(eq(agents.id, event.agentId));
await db.update(companies).set({
  spentMonthlyCents: companyMonthSpend,
  updatedAt: new Date(),
}).where(eq(companies.id, companyId));

The getMonthlySpendTotal helper calculates these values by summing costCents for the current UTC month. Results are written to agents.spentMonthlyCents and companies.spentMonthlyCents, providing instant access to consumption data.

Budget Evaluation and Enforcement

Cost tracking enables automatic budget enforcement. After persisting each event, costService.createEvent invokes budgets.evaluateCostEvent(event) to check utilization against configured limits.

Budget thresholds operate as follows:

  • 80% utilization: Soft alert emitted to notify operators
  • 100% utilization: Agent automatically paused to prevent overage
  • Reset schedule: All monthly budgets reset at 00:00 UTC on the first day of each month

Budgets are defined at two scopes:

  1. Company-wide: companies.budgetMonthlyCents controls organizational spending
  2. Agent-specific: agents.budgetMonthlyCents limits individual agent consumption

This dual-layer approach allows flexible governance—teams can set generous company limits while constraining experimental agents to minimal budgets.

Reporting APIs for Cost Analysis

The server exposes read-only endpoints that aggregate cost events for dashboards and operational tooling:

Summary Endpoint

GET /api/companies/{companyId}/costs/summary returns totals, budgets, and utilization percentages:


# Get the company-wide cost summary

paperclip cost summary -C my-company-id

# → {"spendCents":12345,"budgetCents":50000,"utilizationPercent":24.69}

Per-Agent Breakdown

GET /api/companies/{companyId}/costs/by-agent lists spend, token counts, and run counts per agent:


# Retrieve per-agent spend for the current month

paperclip cost by-agent -C my-company-id

# → [{ "agentId":"agent-123","agentName":"ResearchBot","costCents":6400,… }, …]

Issue-Level Cost Trees

GET /api/companies/{companyId}/costs/issue-tree-summary provides hierarchical cost breakdowns for issues and their descendants. The UI uses this to display task-level spend in project management views.

Additional Aggregations

The costs.ts service layer supports filtering by provider, biller, project, and rolling time windows (5 hours, 24 hours, 7 days).

CLI Integration for Operators

The CLI in cli/src/commands/client/cost.ts wraps the reporting APIs for convenient terminal access:

Command API Endpoint Purpose
paperclip cost summary /costs/summary Quick budget check
paperclip cost by-agent /costs/by-agent Identify expensive agents
paperclip cost event:create /cost-events Manual cost reporting

These commands share authentication and formatting logic with other CLI operations, ensuring consistent behavior across the tool.

Summary

Paperclip's cost tracking system combines several architectural patterns to deliver real-time, auditable spending control:

  • Cost events capture every LLM invocation with full metadata
  • Eager aggregation maintains live monthly counters in agents and companies tables
  • Budget evaluation enforces spend limits with automatic pausing at 100% utilization
  • Reporting APIs provide flexible, index-optimized queries for operational analysis
  • CLI tooling exposes these capabilities for scripting and interactive use

The implementation in packages/db/src/schema/cost_events.ts, server/src/services/costs.ts, and related files demonstrates how to build cost accounting directly into an AI agent platform.

Frequently Asked Questions

How does Paperclip handle cost tracking for agents that use multiple LLM providers?

Paperclip stores the provider and biller separately in each cost event, allowing accurate attribution even when agents route requests across vendors. The by-agent and summary APIs aggregate across all providers automatically. Operators can also filter reports by specific providers using query parameters on the cost endpoints.

What happens when an agent exceeds its monthly budget?

When budgets.evaluateCostEvent detects 100% utilization of an agent's budgetMonthlyCents, it triggers an automatic pause on that agent. The agent stops accepting new tasks until the budget resets at the start of the next UTC month or an operator manually increases the limit. At 80% utilization, only a soft alert is emitted, giving teams time to adjust before hard limits apply.

Can cost events be backdated or modified after creation?

The cost_events table is append-only by design. The occurredAt timestamp accepts historical values, allowing adapters to report costs retroactively if network delays occur. However, once stored, events are not modified—corrections are handled by issuing offsetting events with negative costCents values, preserving a complete audit trail.

How does Paperclip distinguish between cached and uncached input tokens?

The schema includes separate columns for inputTokens and cachedInputTokens. Adapters that receive cache hit information from LLM providers (like Anthropic's prompt caching) populate both fields. This enables accurate cost modeling where cached tokens may be billed at different rates or excluded from certain provider pricing tiers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →