SDK Reference · Reading costs

Reading your costs

Once you are tracking, every read resource queries the same data. Pull usage, break cost down by any dimension, scope to a single end user, and turn cost into margin.

Querying usage

The usage resource is read-only: it queries the events you have already tracked. Writes happen through track(), not here.

MethodDescription
usage.events(params)Paginated usage events in a date window (read-only)
usage.summary(params)High-level totals for a date window
usage.aggregation(params)Usage aggregated by metric name

List events

TypeScript
// The last 7 days of events. lastDays is an alternative to { startDate, endDate }.
const page = await bear.usage.events({
  lastDays: 7,
  limit: 100,        // optional (default 100, max 1000)
  offset: 0,         // optional
});
// Query INPUTS are camelCase; response FIELDS are snake_case (1:1 with the API wire).
for (const e of page.events) console.log(e.model, e.input_tokens);
// -> gpt-4o 12
// -> claude-3-5-sonnet 340 ...

Summary

TypeScript
const s = await bear.usage.summary({ lastDays: 30 });
console.log(s.total_events, s.total_input_tokens, s.total_output_tokens);
// -> 1240 8460210 2103400

Cost analysis

Break cost down by model, provider, feature, agent, or workflow, pull trends and period-over-period summaries, or scope any query to a single end user.

MethodDescription
costs.byModel(params)Cost grouped by model
costs.byProvider(params)Cost grouped by provider
costs.byFeature(params)Cost grouped by feature label
costs.byAgent(params)Cost grouped by agent
costs.byWorkflow(params)Cost grouped by workflow
costs.trend(params)Org-level cost trend time series
costs.summary(params?)Cost with period-over-period comparison
costs.detailedByModel(params)Per-model breakdown with token counts
costs.detailedByProvider(params)Per-provider breakdown with token counts
costs.detailedByEndUser(params)Per-end-user breakdown with token counts
costs.forUser(externalId)Scope cost queries to one end user (chainable)
costs.byOutcome(params)Cost per declared outcome: completed, failed, and unresolved units side by side (true cost per unit of value)

Cost by model

TypeScript
const byModel = await bear.costs.byModel({ lastDays: 30 });
for (const item of byModel.items) {
  console.log(item.attribution_value, item.total_cost, item.percent_of_total);
}
// -> gpt-4o 1284.55 61.2
// -> claude-3-5-sonnet 640.18 30.5
console.log('Total:', byModel.total_cost); // -> Total: 2098.90

Scope to one end user

TypeScript
// Scope any cost query to one end user by external id.
const user = bear.costs.forUser('user_123');
const summary = await user.summary({ lastDays: 30 });
const byModel = await user.byModel({ lastDays: 30 });

Attribution & custom dimensions

These queries slice by the attributes you attached at track() time (see Add attribution & custom attributes on Tracking usage). Every metadata key you set (team, customer, environment) becomes a dimension here, and numeric dimensions feed the numeric analytics. List the agents and workflows that have data, and inspect sessions.

MethodDescription
attribution.byDimension(params)Cost by an arbitrary tagged dimension
attribution.dimensionValues(params)Unique values for a dimension
attribution.dimensionKeys(params)Dimension keys with data in the window
attribution.timeSeries(params)Cost time series by dimension
attribution.agents(params)List agents with data in the window
attribution.workflows(params)List workflows with data in the window
attribution.sessions(params)Session cost breakdown (paginated)
attribution.sessionComparison(params)Compare cost across session types
attribution.sessionDetail(sessionId)Detailed breakdown for one session
attribution.sessionTree(sessionId)The call tree for one session: per-span own cost and subtree roll-ups, with untraced and orphaned cost as visible buckets

Cost by a custom dimension

TypeScript
// Break cost down by any custom dimension you tagged events with.
const result = await bear.attribution.byDimension({
  dimension: 'team',
  lastDays: 30,
});
for (const item of result.items) console.log(item.attribution_value, item.total_cost);
// -> growth 1420.30
// -> platform 678.60   ('growth' / 'platform' came from metadata.team at track() time)

// List the agents / workflows that have data in a range:
const { values } = await bear.attribution.agents({ lastDays: 30 });
// -> ['support-triage', 'billing-helper']

Custom dimensions

MethodDescription
dimensions.definitions()List configured custom dimensions
dimensions.costBreakdown(params)Cost broken down by a dimension key
dimensions.costTrend(params)Cost trend for a dimension
dimensions.numericSummary(params)Aggregate a numeric dimension (avg/sum/...)
dimensions.numericTrend(params)Numeric dimension trend over time

Margins & insights

If you report revenue to Bear Lumen, the margin and insight resources turn cost into profitability: margin by period, by end user, and over time.

MethodDescription
margins.summary(params)Revenue vs cost margin for a date window
margins.byEndUser(params)Margin broken down per end user
margins.trend(params)Margin trend over time
insights.summary(params)Cost/usage insights with distributions

Margin summary

TypeScript
// Absolute dates pin an exact reporting window (a calendar month here).
// Every dated reader also accepts { lastDays: n } instead; lastDays is
// resolved client-side into start/end dates before the request is sent.
const result = await bear.margins.summary({ startDate: '2026-01-01', endDate: '2026-01-31' });
console.log(result.summary.margin_percent); // -> 72.4

const byUser = await bear.margins.byEndUser({ startDate: '2026-01-01', endDate: '2026-01-31' });
for (const u of byUser.end_users) console.log(u.end_user_name, u.margin_percent);
// -> acme-corp 81.2
// -> globex 54.9

Insights

TypeScript
// insights names its absolute bounds start/end, but lastDays works the same way.
const result = await bear.insights.summary({
  lastDays: 30,
  include: ['distributions'],
  limit: 10,
});
console.log(result.totals.cost.current); // -> 2098.90 (total cost this period)