Skip to main content
Usage capture (Node.js, Python, Go, or the LLM proxy) only records events. Each LLM response becomes one usage event:
What that event does depends on what you set up. Nozle accepts an event whose code matches no Feature and stores it, but it is never billed, costed or shown in margin. The dashboard event debugger shows it as “No meter matches the event code”, and SDK capture reports it once per event code to your error callback as feature_not_found.

1. Bill tokens

  1. Create a metered Feature with the event code. In Usage → Meters → New, set Event code to the code your capture sends: llm_tokens by default, or your featureCode / X-Nozle-Feature-Code.
    • Method Sum, Value property total_tokens, Expression event.properties.input_tokens + event.properties.output_tokens. The expression writes the sum into total_tokens before the event is stored.
    • To charge more for output tokens, weight them in the expression, for example event.properties.input_tokens + event.properties.output_tokens * 4, and price per weighted token. One event code maps to one Feature, so a weighted expression is how one event carries both prices.
    • To bill only one side, skip the expression and set Value property to input_tokens or output_tokens.
    • A Feature with an expression cannot be used with product credits.
  2. Charge for it on the plan. Add a usage charge for the Feature, for example package pricing per 1,000,000 tokens. Add an entitlement limit if you want can() to stop customers at a limit. See plans.
  3. Give each customer one active subscription. The usage event is billed to a subscription. Capture looks up the customer’s single active subscription and records nothing for a customer with none or several. Pass a subscription id when a customer has several. The LLM proxy looks it up before it calls the provider and refuses the call with 422 active_subscription_not_found or 422 active_subscription_ambiguous; send X-Nozle-Subscription when a customer has several.
Usage counts towards the current period as soon as the event is processed. Revenue appears in margin reports when the invoice is finalized.

2. Record the cost of tokens and see margin

  1. Create a cost model from the AI tokens template (Usage → Cost models → New, cost path Detailed Cost Event). It creates the Cost Event Meter ai_tokens (sum of tokens, filtered by provider, model and type). Enter your rate for each token type: input, output, and optionally cached input, cache write and reasoning.
  2. Link it to the usage Feature. Set Linked feature to your token Feature (for example llm_tokens) and the composition to Detailed events only, then publish. With Linked feature set to none, each token cost event is still rated on its own meter and attributed to the customer, subscription and Feature of the usage event it points to, and counts in margin; the usage event itself stays uncosted with missing_cost_composition. A cost event for another customer than its parent is uncosted as parent_customer_mismatch, and one whose parent never resolved as parent_attribution_failed. Cost events recorded before this behavior are not rated again by themselves: replay the parent usage event, then its cost events. Linking a Feature is still the way to get a composition and the can() estimate.
  3. One cost model per provider and model you use. The template’s conditions must equal the provider and model values the capture sends (provider is the response format: openai, anthropic or gemini). A model without a matching rule is listed as uncosted with no_matching_cost_rule.
  4. Turn on cost events in capture. Set costMeterCode: "ai_tokens" (Node.js), cost_meter_code="ai_tokens" (Python) or CostMeterCode: "ai_tokens" (Go). Each response then also sends one cost event per token type, linked to its usage event.
  5. Check for uncosted events in the cost intelligence report or the Uncosted queue after the first calls. See cost models.
For can() to return an estimated cost and margin before work starts, also add Feature Event cost components on the token Feature, set the composition to Add both, and use a standard charge. Without them can() reports economics as not_configured.

3. Credits instead of invoices

Usage capture does not spend product credits. To deduct credits per call, make the Feature consumable (Count, or Sum on a property without an expression), give it a credit system rate, and call usage.track() with the token count after the LLM call instead of relying on capture. See credit usage tracking.

Checklist