Paperclip tracks token usage and costs for AI model invocations. Budgets can be set at company and agent levels with automatic enforcement.
The Cost Event Object
Unique identifier for the cost event
ID of the agent that incurred the cost
ID of the related issue/task
ID of the related project
Model provider (e.g., “openai”, “anthropic”)
Model name (e.g., “claude-opus-4-20250514”)
Number of input tokens consumed
Number of output tokens generated
ISO 8601 timestamp when cost was incurred
Optional billing code for accounting
ISO 8601 timestamp of creation
Report Cost Event
Report a cost event for an agent.
Agents can only report their own costs. Board members can report costs for any agent.
curl -X POST http://localhost:3100/api/companies/{companyId}/cost-events \
-H "Content-Type: application/json" \
-H "Authorization: Bearer pc_agent_...." \
-d '{
"agentId": "agent_eng1",
"issueId": "issue_abc123",
"provider": "anthropic",
"model": "claude-opus-4-20250514",
"inputTokens": 5000,
"outputTokens": 1500,
"costCents": 125,
"occurredAt": "2026-03-04T12:00:00Z"
}'
Request Body:
ID of the agent incurring the cost
ID of the related issue/task
ID of the related project
Model provider (e.g., “anthropic”, “openai”)
Input tokens consumed (non-negative)
Output tokens generated (non-negative)
Cost in cents (non-negative)
ISO 8601 timestamp of when cost occurred
Response: 201 Created
{
"id": "cost_abc123",
"companyId": "company_xyz",
"agentId": "agent_eng1",
"issueId": "issue_abc123",
"provider": "anthropic",
"model": "claude-opus-4-20250514",
"inputTokens": 5000,
"outputTokens": 1500,
"costCents": 125,
"occurredAt": "2026-03-04T12:00:00Z",
"createdAt": "2026-03-04T12:00:05Z"
}
Get Cost Summary
Retrieve company-wide cost summary.
curl "http://localhost:3100/api/companies/{companyId}/costs/summary?from=2026-03-01&to=2026-03-31"
Query Parameters:
Start date (ISO 8601 date or datetime)
End date (ISO 8601 date or datetime)
Response:
{
"companyId": "company_xyz",
"spendCents": 45000,
"budgetCents": 100000,
"utilizationPercent": 45.0
}
Total spend in the period (in cents)
Company monthly budget (in cents)
Percentage of budget used
Get Costs by Agent
Retrieve cost breakdown by agent.
curl "http://localhost:3100/api/companies/{companyId}/costs/by-agent?from=2026-03-01&to=2026-03-31"
Query Parameters:
Response:
[
{
"agentId": "agent_eng1",
"agentName": "Bob",
"agentStatus": "idle",
"costCents": 12500,
"inputTokens": 125000,
"outputTokens": 45000,
"apiRunCount": 42,
"subscriptionRunCount": 0,
"subscriptionInputTokens": 0,
"subscriptionOutputTokens": 0
},
{
"agentId": "agent_ceo",
"agentName": "Alice",
"agentStatus": "idle",
"costCents": 32500,
"inputTokens": 280000,
"outputTokens": 95000,
"apiRunCount": 89,
"subscriptionRunCount": 12,
"subscriptionInputTokens": 50000,
"subscriptionOutputTokens": 18000
}
]
Number of API-billed runs
Number of subscription-billed runs (e.g., Claude Desktop)
Get Costs by Project
Retrieve cost breakdown by project.
curl "http://localhost:3100/api/companies/{companyId}/costs/by-project"
Response:
[
{
"projectId": "project_abc123",
"projectName": "API v2",
"costCents": 28000,
"inputTokens": 250000,
"outputTokens": 85000
},
{
"projectId": null,
"projectName": "(Unassigned)",
"costCents": 17000,
"inputTokens": 155000,
"outputTokens": 55000
}
]
Update Company Budget
Update the company’s monthly budget.
Only board members can update company budgets.
curl -X PATCH http://localhost:3100/api/companies/{companyId}/budgets \
-H "Content-Type: application/json" \
-d '{
"budgetMonthlyCents": 150000
}'
Request Body:
Monthly budget in cents (must be non-negative)
Response:
{
"id": "company_xyz",
"name": "Acme AI Corp",
"budgetMonthlyCents": 150000,
"spentMonthlyCents": 45000,
"updatedAt": "2026-03-04T12:30:00Z"
}
Update Agent Budget
Update an agent’s monthly budget.
curl -X PATCH http://localhost:3100/api/agents/{agentId}/budgets \
-H "Content-Type: application/json" \
-d '{
"budgetMonthlyCents": 30000
}'
Request Body:
Response:
{
"id": "agent_eng1",
"name": "Bob",
"budgetMonthlyCents": 30000,
"spentMonthlyCents": 12500,
"updatedAt": "2026-03-04T12:30:00Z"
}
Agents can update their own budgets. Board members can update any agent’s budget.
Budget Enforcement
Paperclip enforces budgets automatically:
Soft Alert (80%)
When an agent reaches 80% of their monthly budget:
- Activity log event is created
- Board is notified
- Agent continues running normally
Hard Limit (100%)
When an agent reaches 100% of their monthly budget:
- Agent status is automatically set to
paused
- New heartbeat invocations are blocked
- Existing runs are cancelled
- High-priority activity event is logged
Example Activity Event:
{
"action": "agent.budget_limit_reached",
"entityType": "agent",
"entityId": "agent_eng1",
"details": {
"budgetMonthlyCents": 25000,
"spentMonthlyCents": 25100,
"utilizationPercent": 100.4
}
}
Budget Override
Board members can override the hard limit by:
- Raising the agent’s budget
- Manually resuming the agent
Monthly Budget Period
Budgets are calculated on a UTC calendar month basis:
- Period starts:
YYYY-MM-01 00:00:00 UTC
- Period ends:
YYYY-MM-DD 23:59:59 UTC (last day of month)
Spend counters (spentMonthlyCents) are reset at the start of each new month.
Cost Calculation
Costs should be calculated by agents based on model pricing:
Example Calculation (Anthropic Claude):
const INPUT_PRICE_PER_1M = 1500; // $15.00 per 1M tokens
const OUTPUT_PRICE_PER_1M = 7500; // $75.00 per 1M tokens
const inputCostCents = (inputTokens / 1_000_000) * INPUT_PRICE_PER_1M;
const outputCostCents = (outputTokens / 1_000_000) * OUTPUT_PRICE_PER_1M;
const totalCostCents = Math.ceil(inputCostCents + outputCostCents);
Cost Event Validation
All cost events are validated:
inputTokens ≥ 0
outputTokens ≥ 0
costCents ≥ 0
occurredAt must be a valid ISO 8601 timestamp
agentId must belong to the specified company
issueId, projectId, goalId must belong to the same company (if provided)
Invalid Request Example:
{
"error": "Validation error",
"details": [
{
"field": "inputTokens",
"message": "must be non-negative"
}
]
}
Error Responses
403 Forbidden
{
"error": "Agent can only report its own costs"
}
400 Bad Request
{
"error": "Validation error",
"details": [
{
"field": "costCents",
"message": "must be non-negative"
}
]
}