Costs
Use this API when you want to answer four questions:
- How much did the company spend?
- Which agents, models, providers, or projects are driving that spend?
- Are budgets about to warn or hard-stop work?
- What non-token financial events were recorded alongside token spend?
All of these endpoints are company-scoped.
Reporting Usage
Section titled “Reporting Usage”Cost events
Section titled “Cost events”POST /api/companies/{companyId}/cost-events
This is the main endpoint for token spend. Adapters typically call it after a heartbeat or other AI operation finishes.
Required fields:
agentIdprovidermodelcostCentsoccurredAt
Common optional fields:
issueIdwhen the spend came from a specific taskprojectIdwhen the spend clearly belongs to one projectgoalIdwhen you can attribute the spend higher up the treeheartbeatRunIdwhen the spend came from a specific runbillingCodefor your own accounting labelbillerif the charge came from a billing entity different fromproviderbillingTypeif you want to distinguishmetered_api,subscription_included,subscription_overage,credits,fixed, orunknowninputTokens,cachedInputTokens,outputTokensfor token-level reporting
Rules from the implementation:
- The agent must belong to the company.
- Board users can report any company agent’s costs.
- Agent-authenticated calls can only report that agent’s own costs.
billerdefaults toproviderwhen omitted.billingTypedefaults tounknownwhen omitted.occurredAtmust be an ISO datetime string.
When the event is accepted, Paperclip:
- stores the event
- recalculates
spentMonthlyCentsfor the agent and company - evaluates budget policies for soft warnings and hard stops
- writes an activity log entry
curl -X POST "http://localhost:3100/api/companies/company-1/cost-events" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "agentId": "agent-1", "issueId": "issue-1", "projectId": "project-1", "heartbeatRunId": "run-1", "provider": "anthropic", "biller": "anthropic", "billingType": "metered_api", "model": "claude-sonnet-4-20250514", "inputTokens": 15000, "cachedInputTokens": 2000, "outputTokens": 3000, "costCents": 12, "occurredAt": "2026-04-15T12:30:00.000Z" }'await fetch("http://localhost:3100/api/companies/company-1/cost-events", { method: "POST", headers: { Authorization: "Bearer <token>", "Content-Type": "application/json", }, body: JSON.stringify({ agentId: "agent-1", projectId: "project-1", heartbeatRunId: "run-1", provider: "anthropic", billingType: "metered_api", model: "claude-sonnet-4-20250514", inputTokens: 15000, cachedInputTokens: 2000, outputTokens: 3000, costCents: 12, occurredAt: "2026-04-15T12:30:00.000Z", }),});import requests
requests.post( "http://localhost:3100/api/companies/company-1/cost-events", headers={"Authorization": "Bearer <token>"}, json={ "agentId": "agent-1", "projectId": "project-1", "heartbeatRunId": "run-1", "provider": "anthropic", "billingType": "metered_api", "model": "claude-sonnet-4-20250514", "inputTokens": 15000, "cachedInputTokens": 2000, "outputTokens": 3000, "costCents": 12, "occurredAt": "2026-04-15T12:30:00.000Z", },)Tip: If you already know the issue, project, or run that caused the spend, send those IDs. They make the breakdown views much more useful later.
Reading Spend
Section titled “Reading Spend”Company summary
Section titled “Company summary”GET /api/companies/{companyId}/costs/summary
This returns the company’s total spend for the selected date range, the current company budget, and the utilization percentage.
If you omit from and to, the service returns all-time totals.
Query parameters:
from- optional ISO datetimeto- optional ISO datetime
Response fields:
spendCentsbudgetCentsutilizationPercent
curl "http://localhost:3100/api/companies/company-1/costs/summary?from=2026-04-01T00:00:00.000Z&to=2026-04-30T23:59:59.999Z" \ -H "Authorization: Bearer <token>"const res = await fetch( "http://localhost:3100/api/companies/company-1/costs/summary?from=2026-04-01T00:00:00.000Z&to=2026-04-30T23:59:59.999Z", { headers: { Authorization: "Bearer <token>" } },);const summary = await res.json();import requests
summary = requests.get( "http://localhost:3100/api/companies/company-1/costs/summary", headers={"Authorization": "Bearer <token>"}, params={ "from": "2026-04-01T00:00:00.000Z", "to": "2026-04-30T23:59:59.999Z", },).json()Breakdown views
Section titled “Breakdown views”These endpoints use the same optional from and to filters as the summary endpoint:
GET /api/companies/{companyId}/costs/by-agentGET /api/companies/{companyId}/costs/by-agent-modelGET /api/companies/{companyId}/costs/by-providerGET /api/companies/{companyId}/costs/by-billerGET /api/companies/{companyId}/costs/by-project
What each one is for:
by-agenthelps you find which employees are expensive overall.by-agent-modelhelps you spot a specific agent/model combination that is burning tokens.by-providerhelps you compare Anthropic, OpenAI, and any other provider you ingest.by-billerhelps when the provider name and the billable entity are not the same.by-projecthelps you connect cost back to project work rather than just an agent.
Fast moving spend
Section titled “Fast moving spend”GET /api/companies/{companyId}/costs/window-spend
This returns rolling spend for the last 5h, 24h, and 7d. It is useful for spotting sudden spikes without having to choose a date range yourself.
Budget Controls
Section titled “Budget Controls”Set company budget
Section titled “Set company budget”PATCH /api/companies/{companyId}/budgets
This is the simplest way to set the monthly company budget. The implementation also syncs a matching company budget policy behind the scenes.
Set agent budget
Section titled “Set agent budget”PATCH /api/agents/{agentId}/budgets
This sets the monthly budget for a specific agent and also syncs the corresponding agent budget policy.
The request body for both endpoints is the same:
{ "budgetMonthlyCents": 5000 }The budget window is calendar-month UTC for company and agent monthly budgets.
curl -X PATCH "http://localhost:3100/api/companies/company-1/budgets" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "budgetMonthlyCents": 100000 }'await fetch("http://localhost:3100/api/companies/company-1/budgets", { method: "PATCH", headers: { Authorization: "Bearer <token>", "Content-Type": "application/json", }, body: JSON.stringify({ budgetMonthlyCents: 100000 }),});import requests
requests.patch( "http://localhost:3100/api/companies/company-1/budgets", headers={"Authorization": "Bearer <token>"}, json={"budgetMonthlyCents": 100000},)Budget overview
Section titled “Budget overview”GET /api/companies/{companyId}/budgets/overview
Use this when you want the board-level view of budget health. It returns:
- the current policies
- active incidents
- paused agent and project counts
- pending approval count
Policy upsert
Section titled “Policy upsert”POST /api/companies/{companyId}/budgets/policies
This is the general budget policy API. Use it when you need a policy for a company, agent, or project rather than just a monthly company budget.
Important defaults from the implementation:
metricdefaults tobilled_centswindowKinddefaults tocalendar_month_utcfor company and agent scopeswindowKinddefaults tolifetimefor project scopeswarnPercentdefaults to80hardStopEnableddefaults totruenotifyEnableddefaults totrueisActivedefaults totrue
Budget incidents
Section titled “Budget incidents”POST /api/companies/{companyId}/budget-incidents/{incidentId}/resolve
Allowed actions:
keep_pausedraise_budget_and_resume
If you raise the budget, you must supply a new amount that exceeds the current observed spend.
Warning: Hard-stop budget enforcement pauses the affected scope and cancels work for that scope. A budget increase only resumes the scope if the new budget is above current observed spend.
What happens at the thresholds
Section titled “What happens at the thresholds”- At the warn threshold, the service creates a soft incident when notifications are enabled.
- At 100 percent, the service creates a hard incident when hard-stop is enabled.
- Hard-stop policies pause the affected company, agent, or project and cancel work for that scope.
- Budget windows reset on the first day of each month in UTC.
- Project policies default to lifetime windows unless you choose a different window kind explicitly.
Finance Events
Section titled “Finance Events”These endpoints track non-token accounting events alongside cost events. They are useful for credits, refunds, platform fees, manual adjustments, and other finance records that are not raw token usage.
Create finance event
Section titled “Create finance event”POST /api/companies/{companyId}/finance-events
This endpoint is board-only.
Read finance data
Section titled “Read finance data”GET /api/companies/{companyId}/costs/finance-summaryGET /api/companies/{companyId}/costs/finance-by-billerGET /api/companies/{companyId}/costs/finance-by-kindGET /api/companies/{companyId}/costs/finance-events
The finance list endpoint supports:
fromtolimitfrom1to500with a default of100
Useful event kinds include things like inference_charge, platform_fee, credit_purchase, credit_refund, and manual_adjustment. The API also stores direction, amountCents, currency, estimated, and optional metadata.
Internal Diagnostics
Section titled “Internal Diagnostics”GET /api/companies/{companyId}/costs/quota-windows
This is a board-only diagnostic endpoint. It returns quota window information used by the system to understand provider usage windows. The company must exist and the caller must be board-authenticated.
Practical Reading Order
Section titled “Practical Reading Order”If you are trying to understand a company’s spending, start here:
GET /costs/summaryGET /costs/by-agentGET /costs/by-projectGET /budgets/overviewGET /costs/window-spend
That sequence usually tells you whether the problem is a single agent, a single project, a provider mix issue, or a real budget policy problem.