Files
cfw-autumn/apps/docs/mintlify/api-reference/core/trackTokens.mdx
2026-06-10 19:20:40 +01:00

623 lines
24 KiB
Plaintext

---
title: "Track Tokens"
openapi: "openapi POST /v1/balances.track_tokens"
---
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
import { DynamicResponseField } from "/snippets/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
### Body Parameters
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string">
The ID of the entity for entity-scoped balances.
</DynamicParamField>
<DynamicParamField body="feature_id" type="string">
The ID of the AI credit system feature. Auto-detected from the customer's entitlements if omitted — only required when a customer has multiple AI credit systems.
</DynamicParamField>
<DynamicParamField body="model_id" type="string" required>
The AI model as '<provider>/<model>' (e.g. 'anthropic/claude-opus-4-8', 'openrouter/openai/gpt-4o'). The provider is the first path segment and must match a provider + model key in models.dev.
</DynamicParamField>
<DynamicParamField body="input_tokens" type="integer" required>
Number of non-cached text input tokens consumed. Exclusive of cache and audio token pools.
</DynamicParamField>
<DynamicParamField body="output_tokens" type="integer" required>
Number of text output tokens consumed. Exclusive of the reasoning and audio output pools.
</DynamicParamField>
<DynamicParamField body="cache_read_tokens" type="integer">
Number of cached input tokens read.
</DynamicParamField>
<DynamicParamField body="cache_write_tokens" type="integer">
Number of input tokens written to the cache.
</DynamicParamField>
<DynamicParamField body="audio_input_tokens" type="integer">
Number of audio input tokens consumed.
</DynamicParamField>
<DynamicParamField body="audio_output_tokens" type="integer">
Number of audio output tokens generated.
</DynamicParamField>
<DynamicParamField body="reasoning_tokens" type="integer">
Number of reasoning tokens generated.
</DynamicParamField>
<DynamicParamField body="properties" type="object">
Additional properties to attach to this usage event.
</DynamicParamField>
### Response
<DynamicResponseField name="customer_id" type="string">
The ID of the customer whose usage was tracked.
</DynamicResponseField>
<DynamicResponseField name="entity_id" type="string">
The ID of the entity, if entity-scoped tracking was performed.
</DynamicResponseField>
<DynamicResponseField name="event_name" type="string">
The event name that was tracked, if event_name was used instead of feature_id.
</DynamicResponseField>
<DynamicResponseField name="value" type="number">
The amount of usage that was recorded.
</DynamicResponseField>
<DynamicResponseField name="balance" type="object | null">
The updated balance for the tracked feature. Null if tracking by event_name that affects multiple features.
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string">
The feature ID this balance is for.
</DynamicResponseField>
<DynamicResponseField name="feature" type="object">
The full feature object if expanded.
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The unique identifier for this feature, used in /check and /track calls.
</DynamicResponseField>
<DynamicResponseField name="name" type="string">
Human-readable name displayed in the dashboard and billing UI.
</DynamicResponseField>
<DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system' | 'ai_credit_system'">
Feature type: 'boolean' for on/off access, 'metered' for usage-tracked features, 'credit_system' for unified credit pools, 'ai_credit_system' for model-based token pricing.
</DynamicResponseField>
<DynamicResponseField name="consumable" type="boolean">
For metered features: true if usage resets periodically (API calls, credits), false if allocated persistently (seats, storage).
</DynamicResponseField>
<DynamicResponseField name="event_names" type="string[]">
Event names that trigger this feature's balance. Allows multiple features to respond to a single event.
</DynamicResponseField>
<DynamicResponseField name="credit_schema" type="object[]">
For credit_system features: maps metered features to their credit costs.
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string">
ID of the metered feature that draws from this credit system.
</DynamicResponseField>
<DynamicResponseField name="credit_cost" type="number">
Credits consumed per unit of the metered feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="model_markups.{key}" type="object | null">
Per-model markup overrides for AI credit systems.
<Expandable title="properties">
<DynamicResponseField name="markup" type="number" />
<DynamicResponseField name="input_cost" type="number" />
<DynamicResponseField name="output_cost" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="default_markup" type="number">
Default percentage markup for AI credit systems. Use -100 to make usage free.
</DynamicResponseField>
<DynamicResponseField name="provider_markups.{key}" type="object | null">
Per-provider default markup percentages for AI credit systems.
<Expandable title="properties">
<DynamicResponseField name="markup" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
Display names for the feature in billing UI and customer-facing components.
<Expandable title="properties">
<DynamicResponseField name="singular" type="string | null">
Singular form for UI display (e.g., 'API call', 'seat').
</DynamicResponseField>
<DynamicResponseField name="plural" type="string | null">
Plural form for UI display (e.g., 'API calls', 'seats').
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean">
Whether the feature is archived and hidden from the dashboard.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="granted" type="number">
Total balance granted (included + prepaid).
</DynamicResponseField>
<DynamicResponseField name="remaining" type="number">
Remaining balance available for use.
</DynamicResponseField>
<DynamicResponseField name="usage" type="number">
Total usage consumed in the current period.
</DynamicResponseField>
<DynamicResponseField name="unlimited" type="boolean">
Whether this feature has unlimited usage.
</DynamicResponseField>
<DynamicResponseField name="overage_allowed" type="boolean">
Whether usage beyond the granted balance is allowed (with overage charges).
</DynamicResponseField>
<DynamicResponseField name="max_purchase" type="number | null">
Maximum quantity that can be purchased as a top-up, or null for unlimited.
</DynamicResponseField>
<DynamicResponseField name="next_reset_at" type="number | null">
Timestamp when the balance will reset, or null for no reset.
</DynamicResponseField>
<DynamicResponseField name="breakdown" type="object[]">
Detailed breakdown of balance sources when stacking multiple plans or grants.
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The unique identifier for this balance breakdown.
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string | null">
The plan ID this balance originates from, or null for standalone balances.
</DynamicResponseField>
<DynamicResponseField name="included_grant" type="number">
Amount granted from the plan's included usage.
</DynamicResponseField>
<DynamicResponseField name="prepaid_grant" type="number">
Amount granted from prepaid purchases or top-ups.
</DynamicResponseField>
<DynamicResponseField name="remaining" type="number">
Remaining balance available for use.
</DynamicResponseField>
<DynamicResponseField name="usage" type="number">
Amount consumed in the current period.
</DynamicResponseField>
<DynamicResponseField name="unlimited" type="boolean">
Whether this balance has unlimited usage.
</DynamicResponseField>
<DynamicResponseField name="reset" type="object | null">
Reset configuration for this balance, or null if no reset.
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
</DynamicResponseField>
<DynamicResponseField name="interval_count" type="number">
Number of intervals between resets (eg. 2 for bi-monthly).
</DynamicResponseField>
<DynamicResponseField name="resets_at" type="number | null">
Timestamp when the balance will next reset.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
Pricing configuration if this balance has usage-based pricing.
<Expandable title="properties">
<DynamicResponseField name="amount" type="number">
The per-unit price amount.
</DynamicResponseField>
<DynamicResponseField name="tiers" type="object[]">
Tiered pricing configuration if applicable.
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="flat_amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="tier_behavior" type="'graduated' | 'volume'">
How tiers are applied: graduated (split across bands) or volume (flat rate for the matched tier).
</DynamicResponseField>
<DynamicResponseField name="billing_units" type="number">
The number of units per billing increment (eg. $9 / 250 units).
</DynamicResponseField>
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'">
Whether usage is prepaid or billed pay-per-use.
</DynamicResponseField>
<DynamicResponseField name="max_purchase" type="number | null">
Maximum quantity that can be purchased, or null for unlimited.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number | null">
Timestamp when this balance expires, or null for no expiration.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollovers" type="object[]">
Rollover balances carried over from previous periods.
<Expandable title="properties">
<DynamicResponseField name="balance" type="number">
Amount of balance rolled over from a previous period.
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number">
Timestamp when the rollover balance expires.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances.{key}" type="object | null">
Map of feature_id to updated balance for the tracked feature and any related features (e.g. linked credit systems). Value is null when the customer has no balance for that feature.
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string">
The feature ID this balance is for.
</DynamicResponseField>
<DynamicResponseField name="feature" type="object">
The full feature object if expanded.
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The unique identifier for this feature, used in /check and /track calls.
</DynamicResponseField>
<DynamicResponseField name="name" type="string">
Human-readable name displayed in the dashboard and billing UI.
</DynamicResponseField>
<DynamicResponseField name="type" type="'boolean' | 'metered' | 'credit_system' | 'ai_credit_system'">
Feature type: 'boolean' for on/off access, 'metered' for usage-tracked features, 'credit_system' for unified credit pools, 'ai_credit_system' for model-based token pricing.
</DynamicResponseField>
<DynamicResponseField name="consumable" type="boolean">
For metered features: true if usage resets periodically (API calls, credits), false if allocated persistently (seats, storage).
</DynamicResponseField>
<DynamicResponseField name="event_names" type="string[]">
Event names that trigger this feature's balance. Allows multiple features to respond to a single event.
</DynamicResponseField>
<DynamicResponseField name="credit_schema" type="object[]">
For credit_system features: maps metered features to their credit costs.
<Expandable title="properties">
<DynamicResponseField name="metered_feature_id" type="string">
ID of the metered feature that draws from this credit system.
</DynamicResponseField>
<DynamicResponseField name="credit_cost" type="number">
Credits consumed per unit of the metered feature.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="model_markups.{key}" type="object | null">
Per-model markup overrides for AI credit systems.
<Expandable title="properties">
<DynamicResponseField name="markup" type="number" />
<DynamicResponseField name="input_cost" type="number" />
<DynamicResponseField name="output_cost" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="default_markup" type="number">
Default percentage markup for AI credit systems. Use -100 to make usage free.
</DynamicResponseField>
<DynamicResponseField name="provider_markups.{key}" type="object | null">
Per-provider default markup percentages for AI credit systems.
<Expandable title="properties">
<DynamicResponseField name="markup" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="display" type="object">
Display names for the feature in billing UI and customer-facing components.
<Expandable title="properties">
<DynamicResponseField name="singular" type="string | null">
Singular form for UI display (e.g., 'API call', 'seat').
</DynamicResponseField>
<DynamicResponseField name="plural" type="string | null">
Plural form for UI display (e.g., 'API calls', 'seats').
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="archived" type="boolean">
Whether the feature is archived and hidden from the dashboard.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="granted" type="number">
Total balance granted (included + prepaid).
</DynamicResponseField>
<DynamicResponseField name="remaining" type="number">
Remaining balance available for use.
</DynamicResponseField>
<DynamicResponseField name="usage" type="number">
Total usage consumed in the current period.
</DynamicResponseField>
<DynamicResponseField name="unlimited" type="boolean">
Whether this feature has unlimited usage.
</DynamicResponseField>
<DynamicResponseField name="overage_allowed" type="boolean">
Whether usage beyond the granted balance is allowed (with overage charges).
</DynamicResponseField>
<DynamicResponseField name="max_purchase" type="number | null">
Maximum quantity that can be purchased as a top-up, or null for unlimited.
</DynamicResponseField>
<DynamicResponseField name="next_reset_at" type="number | null">
Timestamp when the balance will reset, or null for no reset.
</DynamicResponseField>
<DynamicResponseField name="breakdown" type="object[]">
Detailed breakdown of balance sources when stacking multiple plans or grants.
<Expandable title="properties">
<DynamicResponseField name="id" type="string">
The unique identifier for this balance breakdown.
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string | null">
The plan ID this balance originates from, or null for standalone balances.
</DynamicResponseField>
<DynamicResponseField name="included_grant" type="number">
Amount granted from the plan's included usage.
</DynamicResponseField>
<DynamicResponseField name="prepaid_grant" type="number">
Amount granted from prepaid purchases or top-ups.
</DynamicResponseField>
<DynamicResponseField name="remaining" type="number">
Remaining balance available for use.
</DynamicResponseField>
<DynamicResponseField name="usage" type="number">
Amount consumed in the current period.
</DynamicResponseField>
<DynamicResponseField name="unlimited" type="boolean">
Whether this balance has unlimited usage.
</DynamicResponseField>
<DynamicResponseField name="reset" type="object | null">
Reset configuration for this balance, or null if no reset.
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
</DynamicResponseField>
<DynamicResponseField name="interval_count" type="number">
Number of intervals between resets (eg. 2 for bi-monthly).
</DynamicResponseField>
<DynamicResponseField name="resets_at" type="number | null">
Timestamp when the balance will next reset.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
Pricing configuration if this balance has usage-based pricing.
<Expandable title="properties">
<DynamicResponseField name="amount" type="number">
The per-unit price amount.
</DynamicResponseField>
<DynamicResponseField name="tiers" type="object[]">
Tiered pricing configuration if applicable.
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="flat_amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="tier_behavior" type="'graduated' | 'volume'">
How tiers are applied: graduated (split across bands) or volume (flat rate for the matched tier).
</DynamicResponseField>
<DynamicResponseField name="billing_units" type="number">
The number of units per billing increment (eg. $9 / 250 units).
</DynamicResponseField>
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'">
Whether usage is prepaid or billed pay-per-use.
</DynamicResponseField>
<DynamicResponseField name="max_purchase" type="number | null">
Maximum quantity that can be purchased, or null for unlimited.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number | null">
Timestamp when this balance expires, or null for no expiration.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollovers" type="object[]">
Rollover balances carried over from previous periods.
<Expandable title="properties">
<DynamicResponseField name="balance" type="number">
Amount of balance rolled over from a previous period.
</DynamicResponseField>
<DynamicResponseField name="expires_at" type="number">
Timestamp when the rollover balance expires.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="deductions" type="object[]">
Per-balance breakdown of what this event deducted. A single event can consume from multiple balance rows when credit systems or rollovers are involved; this surfaces each one so callers can build per-feature usage views without polling.
<Expandable title="properties">
<DynamicResponseField name="balance_id" type="string">
ID of the underlying balance row that was deducted from (customer_entitlement or rollover).
</DynamicResponseField>
<DynamicResponseField name="feature_id" type="string">
The feature this balance belongs to.
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string | null">
ID of the plan/product this balance belongs to. Null when the balance can't be attributed to a single plan (e.g. it spans multiple).
</DynamicResponseField>
<DynamicResponseField name="reset" type="object | null">
Reset configuration for the balance this deduction came from, or null if the balance doesn't reset.
<Expandable title="properties">
<DynamicResponseField name="interval" type="'one_off' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'semi_annual' | 'year'">
The reset interval (hour, day, week, month, etc.) or 'multiple' if combined from different intervals.
</DynamicResponseField>
<DynamicResponseField name="interval_count" type="number">
Number of intervals between resets (eg. 2 for bi-monthly).
</DynamicResponseField>
<DynamicResponseField name="resets_at" type="number | null">
Timestamp when the balance will next reset.
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="value" type="number">
Amount deducted from this balance. Positive when usage was consumed, negative when credit was restored (e.g. a refund via negative track value).
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<ResponseExample>
```json 200
{
"customer_id": "cus_123",
"value": 0.006,
"balance": {
"feature_id": "ai_credits",
"granted": 10,
"remaining": 9.994,
"usage": 0.006,
"unlimited": false,
"overage_allowed": false,
"max_purchase": null,
"next_reset_at": 1773851121437,
"breakdown": [
{
"id": "cus_ent_39qmLooixXLAqMywgXywjAz96rV",
"plan_id": "pro_plan",
"included_grant": 100,
"prepaid_grant": 0,
"remaining": 72,
"usage": 28,
"unlimited": false,
"reset": {
"interval": "month",
"resets_at": 1773851121437
},
"price": null,
"expires_at": null
}
]
},
"deductions": [
{
"balance_id": "cus_ent_3DdSDoyFmoA9Neecl2a2Gc507X2",
"feature_id": "ai_credits",
"plan_id": "pro",
"reset": {
"interval": "month",
"resets_at": 1781288736881
},
"value": 0.006
}
]
}
```
</ResponseExample>