Billable Units
Define what you charge for — API calls, tokens, sessions, data, or any custom metric — with Aforo's billable units.
Billable Units
Billable Units (internally called metrics) define what you charge for. They are the atomic measurement your usage events report against and your rate plans price.
Every charge in Aforo traces back to a billable unit — an API call, an LLM token, an active session, a volume of data, or a custom dimension you define.
Built-in templates
When you create a product, Aforo seeds a set of standard billable units for that product type. The tables below list what each type seeds.
These templates are generated from the product-type descriptors — the same source the create wizard reads at runtime. If a name here ever looks off, the create wizard's list is authoritative.
Standard API
AI Agent
AI Agent seeds a single Tokens Consumed meter, not separate input/output token meters. If you price prompt and completion tokens differently, add custom units for each — the split isn't a default.
MCP Server
Agentic API
Aggregation types
How a unit rolls up the events it counts:
Unit type
Beyond how events aggregate, each billable unit has a unit type that says what its value measures:
Unit type defaults to COUNT. The one that changes pricing behavior is MONETARY: it marks the unit as a currency amount and carries a currency (e.g. USD). This is what Revenue Share (Percentage) pricing charges against — it bills a percentage of a MONETARY unit summed over the period (your GMV). Set the unit type to Monetary + a currency, and aggregate with SUM, before binding it to a Revenue Share rate plan.
Revenue Share on a non-monetary unit bills a percentage of a count, which is meaningless. Mark the unit MONETARY with a currency and SUM aggregation so the percentage applies to real money.
Custom billable units
Create a custom unit when a template doesn't fit your pricing model:
- Go to Catalog → Billable Units.
- Click New Billable Unit.
- Set:
- Name — e.g. "Compute Minutes"
- Unit Label — e.g. "minutes"
- Unit Type — Count / Monetary / Data / Time (pick Monetary + a currency for Revenue Share units)
- Aggregation — how events roll up (
COUNT,SUM,COUNT_DISTINCT, …) - Event Field — the numeric field from your event payload to aggregate
- Product Types — which product types can use this unit
You cannot change a unit's aggregation type once it's used in a rate plan — that would silently change what every bound plan bills. Create a new unit if you need a different aggregation.
Filtering
Custom units support filter conditions to narrow which events count. For example, count only API calls where status_code < 400:
{
"filterConditions": [
{
"field": "status_code",
"operator": "LESS_THAN",
"value": "400"
}
]
}
Supported operators: EQUALS, NOT_EQUALS, GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, CONTAINS, NOT_CONTAINS, IN, NOT_IN, EXISTS, NOT_EXISTS.
Product associations
Billable units are associated with products many-to-many (product_metrics junction). A single unit like "Tokens Consumed" can price both your AI Agent product and your Agentic API product — change its definition once and every product using it picks it up.
Deletion protection
Like products, billable units are protected from deletion when they're referenced by active rate plans. The GET /api/v1/metrics/{id}/deletion-check returns ALLOW, WARN, or BLOCK; a BLOCK means you must migrate subscribers off the referencing plans first.
Archived units can be restored (POST /api/v1/metrics/{id}/restore), and any unit can be cloned (POST /api/v1/metrics/{id}/clone) as the starting point for a variant — cloning is a billable-unit feature, not a product one.
Bulk operations
Bulk create from templates
curl -X POST https://catalog.aforo.ai/api/v1/metrics/bulk \
-H "Authorization: Bearer $AFORO_API_KEY" \
-H "X-Tenant-Id: $TENANT_ID" \
-d '{ "productType": "AI_AGENT" }'
This seeds the standard templates for the product type in one call (nine for AI Agent, five for Standard API, eight each for MCP Server and Agentic API).
Export / import
Use export to back up your custom units or move them between workspaces. Export returns your custom, non-archived units only — the built-in templates are seeded fresh in every workspace (nothing to carry over), and archived units are left out since you're moving live configuration.
curl https://catalog.aforo.ai/api/v1/metrics/export \
-H "Authorization: Bearer $AFORO_API_KEY" \
-H "X-Tenant-Id: $TENANT_ID" > units.json
In the console (Billable Units → All Units) you can narrow what you export before downloading: check specific rows to export just those, export everything matching your current filters, or export all custom units. System defaults are never included.
Import is all-or-nothing. If any unit in the file collides with an existing name (active or archived), repeats another name in the same file, or fails validation, the whole import stops and nothing is written — the response lists every problem so you can fix the file and retry:
curl -X POST https://catalog.aforo.ai/api/v1/metrics/import \
-H "Authorization: Bearer $AFORO_API_KEY" \
-H "X-Tenant-Id: $TENANT_ID" \
-H "Content-Type: application/json" \
--data @units.json
There's no skip-and-continue mode: a partial import would leave you guessing which units landed. Rename or remove the conflicts in the file, then import again.