Scrydon
Platform

Billing and usage metering

Per-capability cost attribution, CO₂ estimates, and chargeback reports — available to organisation admins via client.billing.*

Every AI capability call — LLM completion, speech-to-text transcription, embedding, TTS synthesis, OCR, image generation, video analysis — produces a metered usage event. The billing.* API lets organisation admins query cost, token, run, and CO₂ estimates across any combination of workspace, team, user, capability, vendor, model, or region.

Billing metering is observe-only. A failed billing write never blocks the capability call. Figures labelled CO₂ are modelled estimates, not energy-meter readings — see Carbon methodology below.


API overview

All billing.* methods are available on the Better Auth admin client (getAdminClient()) from @scrydon/multi-tenancy/auth/client.

MethodAuth requiredWhat it returns
billing.log(...)M2M internal (billing:admin)Records one usage event. Called by the capability runtime — not by product code directly.
billing.summary(...)Org admin sessionTotals + optional grouped breakdown
billing.timeseries(...)Org admin sessionDay-by-day series
billing.topN(...)Org admin sessionTop N keys by a metric
billing.chargeback(...)Org admin sessionPer-key cost + share of org total
billing.carbonFactors(...)Org admin sessionFull carbon-factor table (for auditors)

Usage event fields

Each metered event captures:

FieldTypeDescription
organizationIdstringOrganisation that owns the event
occurredAtstring (ISO)When the capability call completed
workspaceIdstring | nullWorkspace that drove the call, if known
teamIdstring | nullTeam that drove the call, if known
userIdstring | nullUser who triggered the call, if known
source"workflow" | "copilot" | "chat" | "wand" | "kb_ingest" | "api"Product surface
capability"llm" | "stt" | "embedding" | "tts" | "ocr" | "video" | "image"Capability category
vendorstringVendor slug (e.g. openai, anthropic)
modelstringModel identifier (e.g. gpt-4o, whisper-1)
regionstring | nullHosting region used for carbon estimation
tokensInnumberInput tokens consumed
tokensOutnumberOutput tokens produced
unitsnumber | nullNon-token usage (audio-seconds, pages, images, video-seconds)
durationMsnumberWall-clock time of the capability call
successbooleanWhether the call succeeded
costUsdnumberFrozen cost at write time (USD)
co2GramsnumberFrozen CO₂ estimate at write time (grams CO₂e)
pricingVersionstringPricing-catalog version used to compute costUsd
carbonVersionstringCarbon-factor-table version used to compute co2Grams
executionIdstring | nullWorkflow execution that triggered the call, if any
workflowIdstring | nullWorkflow definition that triggered the call, if any

Summary

Returns aggregate totals for the organisation over a date range, with an optional per-dimension breakdown.

const { data, error } = await getAdminClient().billing.summary({
  organizationId: "org_abc123",
  range: { from: "2026-06-01T00:00:00Z", to: "2026-07-01T00:00:00Z" },
  groupBy: "workspace",            // optional
  filters: { capability: "llm" }, // optional dimension filter
})

Request

FieldTypeRequiredDescription
organizationIdstringYesOrganisation to query
range.fromstring (ISO)YesStart of the range (inclusive)
range.tostring (ISO)YesEnd of the range (exclusive)
groupByUsageDimensionNoGroup the breakdown by this dimension
filtersPartial<Record<UsageDimension, string>>NoNarrow results to a single dimension value

UsageDimension is one of: workspace, team, user, source, capability, vendor, model, region.

Response (UsageSummary)

{
  costUsd: number,       // total cost over the range
  co2Grams: number,      // total COestimate (grams CO₂e)
  tokensIn: number,
  tokensOut: number,
  runs: number,          // total capability calls
  successes: number,
  groups: Array<{
    key: string,         // dimension value (e.g. workspace id)
    costUsd: number,
    co2Grams: number,
    tokens: number,
    runs: number,
  }>,
}

Timeseries

Returns a day-by-day series for charting consumption over time.

const { data, error } = await getAdminClient().billing.timeseries({
  organizationId: "org_abc123",
  range: { from: "2026-06-01T00:00:00Z", to: "2026-07-01T00:00:00Z" },
  granularity: "day",
  groupBy: "capability",  // optional
})

Request

FieldTypeRequiredDescription
organizationIdstringYesOrganisation to query
range.fromstring (ISO)YesStart (inclusive)
range.tostring (ISO)YesEnd (exclusive)
granularity"day"YesOnly daily granularity is supported in v1
groupByUsageDimensionNoAdditional grouping key per bucket

Response

{
  points: Array<{
    bucket: string,      // ISO day (YYYY-MM-DD)
    costUsd: number,
    co2Grams: number,
    tokens: number,
    runs: number,
  }>,
}

Top-N

Returns the top N keys by a chosen metric over a date range — useful for identifying the highest-cost workspaces, models, or vendors.

const { data, error } = await getAdminClient().billing.topN({
  organizationId: "org_abc123",
  range: { from: "2026-06-01T00:00:00Z", to: "2026-07-01T00:00:00Z" },
  dimension: "model",
  metric: "cost_usd",
  limit: 10,
})

Request

FieldTypeRequiredDescription
organizationIdstringYesOrganisation to query
rangeUsageRangeYesDate range
dimensionUsageDimensionYesWhat to rank
metricUsageMetricYesWhat to rank by: cost_usd, co2_grams, tokens, runs
limitnumber (1–100)YesNumber of rows to return

Response

{
  rows: Array<{
    key: string,    // dimension value
    value: number,  // metric total
  }>,
}

Chargeback

Returns cost, CO₂, token, and run totals per key, plus each key's share of the organisation total. Use this for internal cost allocation.

const { data, error } = await getAdminClient().billing.chargeback({
  organizationId: "org_abc123",
  range: { from: "2026-06-01T00:00:00Z", to: "2026-07-01T00:00:00Z" },
  dimension: "workspace",
})

Response (ChargebackRow[])

Array<{
  key: string,        // dimension value (e.g. workspace id)
  costUsd: number,
  co2Grams: number,
  tokens: number,
  runs: number,
  share: number,      // 0..1fraction of org-total cost
}>

share values across all rows sum to approximately 1. Events with no value for the chosen dimension are grouped under "(unattributed)".


Carbon factors

Returns the full carbon-factor table used to compute co2Grams on every event. Intended for auditors and ESG reporting.

const { data, error } = await getAdminClient().billing.carbonFactors({
  organizationId: "org_abc123",
})

Response

{
  version: string,                    // e.g. "2026.06.0" — matches usage_event.carbon_version
  regionFallback: string,             // region used when vendor region is unknown
  gridGco2PerKwh: Record<string, number>,    // gCO₂e per kWh by region
  energyWhPer1k: Record<string, number>,     // Wh per 1k tokens/units by model class
  pue: number,                        // power-usage effectiveness multiplier
  citation: string,                   // provenance string for audit
}

Carbon methodology

CO₂ figures are modelled estimates, not energy-meter readings. Present them as estimates in any external report.

Scrydon estimates AI-capability carbon footprint using a three-factor model:

CO₂ (g) = energy_per_1k_units_Wh × (total_tokens_or_units / 1000) × PUE × (grid_gco2_per_kwh / 1000)
  • Energy per 1k tokens (Wh): Binned by model class (llm_large, llm_small, embedding, stt, etc.) using published per-token energy estimates. Non-token classes (STT, OCR, image, video) use per-audio-second, per-page, or per-image denominators.
  • PUE (Power-Usage Effectiveness): A fixed multiplier of 1.12 — a mid-range value within the 1.1–1.2 range published by major hyperscalers.
  • Grid carbon intensity (gCO₂e/kWh): Region-specific values from public electricity-grid carbon intensity databases. Requests without a known hosting region fall back to the global average (436 gCO₂e/kWh).

The factor table is versioned (carbon_version). Every usage_event row records the version in use at write time, so historical totals remain reproducible after factor updates. Retrieve the current table and its provenance string via billing.carbonFactors(...).


Required role

All billing.summary, billing.timeseries, billing.topN, billing.chargeback, and billing.carbonFactors calls require an org-admin session for the queried organizationId. A non-admin member receives a 403 Forbidden response.

billing.log is an internal M2M endpoint gated on the billing:admin capability. It is called by the capability runtime — not by product code or SDK consumers.


On this page

On this page