Skip to main content
Product-credit amounts are exact decimal strings. Keep them as str; do not convert them to float when precision matters.

List credit systems

The SDK follows all active pages and returns normalized CreditSystem typed dictionaries.

Customer balances

Customer operation history

Limits must be integers from 1 to 100. Operations include exact amounts, status, reason, rate snapshot, occurrence time, and source allocations.

Entity balances

pool_policy is entity_only, entity_then_customer, customer_only, or None.

Entity operation history

Allocate credits

Deallocate credits

Transfer amounts must be positive decimal strings with at most 12 decimal places. Idempotency keys are required and limited to 255 UTF-8 bytes.

Advisory usage check

usage.check() does not reserve or mutate credits. occurred_at is optional: pass RFC 3339 with an offset or Z, or Unix seconds as a numeric string (the latter from the Engine release that includes the broader timestamp forms). It defaults to the current time. usage.check() takes occurred_at, not timestamp; timestamp= raises TypeError.

Atomic usage tracking

usage.track() atomically evaluates the metric conversion, selects eligible sources, deducts credits, and records the operation. Entity IDs enable per-Entity attribution and configured pool policy. timestamp is optional in the SDK, which fills in the current time; the API itself requires it. Pass RFC 3339 with an offset or Z, or Unix seconds as a numeric string (the latter from the Engine release that includes the broader timestamp forms). A date only, an offset-less value, and zero or negative seconds return 400 invalid_request.
Retrying usage.track. Pass the same idempotency_key and the same timestamp on every retry. If you omit timestamp, the SDK fills in the current time once per idempotency key and reuses it when the same key is sent again on the same client (it remembers the last 1,000 keys). A retry from another process, or after a restart, gets a new time, no longer matches the first request, and the API returns 409 idempotency_key_reused; pass a fixed timestamp there. Store one time per unit of work (RFC 3339 with an offset, for example 2026-10-12T16:00:00.000Z) and reuse it. A matching replay returns the original operation_id, and the balance changes once. The event time must fall after the credit rate became effective. A 409 means the first call was committed: do not retry.

Legacy wallet adapter

nozle.check_and_deduct(customer_id, credits=5) remains available for the legacy wallet path. It is not idempotent: a retry after a timeout can deduct again, so the SDK never retries it. The old check_and_deduct(customer_id, feature, credits) form still works: feature is deprecated, ignored and never sent. A missing credits raises NozleValidationError. New product-credit integrations should use usage.check() and usage.track(). Keep reads and mutations behind authenticated backend routes and derive customer and Entity IDs from trusted identity data.