> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nozle.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Entity-scoped Credits

> Model per-user credit pools, shared fallback, lifecycle, and exact transfers

Entities are stable customer-owned subjects such as users, seats, agents, or projects. They add a scoped credit pool without replacing the customer pool.

```text theme={null}
Customer  = workspace or company
Entity    = one stable subject inside that customer
```

An Entity belongs to exactly one customer and organization. Recreating an Entity with the same external ID produces a different incarnation; financial history remains bound to the original durable Entity UUID.

## Pool policies

Each active plan can select one policy per Credit System:

* `entity_only` spends only Entity-owned sources;
* `entity_then_customer` spends Entity sources first, then the shared customer pool;
* `customer_only` records Entity attribution while spending only shared customer sources.

The balance API returns all three exact-decimal views:

```json theme={null}
{
  "entity_available": "480.000000000001",
  "shared_available": "250",
  "effective_available": "730.000000000001",
  "pool_policy": "entity_then_customer"
}
```

`effective_available` is zero for an inactive Entity or when no unambiguous active plan policy exists. The API never infers a fallback policy from available sources.

## Sources and transfers

Entity plan grants and allocated paid top-ups remain separate sources. Allocation moves value from a customer paid-top-up source into an `allocated_top_up` child while preserving its parent source, payment provenance, priority, and expiry.

Only unused allocated top-up value can be returned. Subscription grants are never presented as transferable company value.

Paid top-ups initially belong to the customer pool. They are not assigned automatically to the Entity that initiated checkout or to the first paid Entity. Your backend can:

* leave the credits in the customer pool for a plan that allows shared-pool spending;
* allocate an exact amount to one Entity; or
* split the purchase across multiple Entities.

For example, a 250-credit top-up can allocate 100 credits to `user_42`, 100 to `support_bot`, and leave 50 in the customer pool. Each allocation remains linked to the exact paid parent source.

<Warning>
  Allocation and deallocation are backend-only mutations. They require a secret credential, an idempotency key, and eligible paid top-up sources.
</Warning>

Keep amounts as decimal strings throughout your application. Do not convert them to JavaScript numbers or binary floating-point values.

## Lifecycle

Entities can be `active`, `suspended`, or `deleted`.

* Active Entities can read and spend according to their pool policy.
* Suspension or deletion blocks new usage, expires unused Entity subscription grants, and returns unused allocated top-ups to their original parents.
* Operations, allocations, source provenance, and status history remain immutable.
* Reactivation does not reuse an older incarnation's idempotency results or mint duplicate period grants.

## Seat billing

Entities and billable seats are separate contracts. Creating, suspending,
reactivating, or deleting an Entity never changes billed usage.

Entity subscriptions are also separate from credit pools and seat metrics. Use an Entity subscription only when that Entity owns an independent plan. Credit allocation still follows the configured pool policy, while seat billing still follows explicit usage events.

An Entity-owned subscription grant is materialized only for that subscription's owning Entity. A Pro Entity receives the Pro grant and a Max Entity receives the Max grant; Nozle does not copy every active Entity plan grant to every Entity under the customer.

If your product bills per seat, configure a recurring unique-count Billable
Metric:

```text theme={null}
consumable=false
recurring=true
aggregation=unique_count_agg
field_name=user_id
```

Your authenticated backend sends explicit `add` and `remove` events with a
stable user ID and a unique transaction ID for each business transition. The
same external ID may be used for both an Entity and a seat, but neither API
automatically calls the other.

```json theme={null}
{
  "event": {
    "transaction_id": "membership_user_42_v7_add",
    "code": "additional_seats",
    "external_subscription_id": "workspace_123_subscription",
    "properties": {
      "user_id": "user_42",
      "operation_type": "add"
    }
  }
}
```

Removal uses a new transaction ID, the same `user_id`, and
`"operation_type": "remove"`. Nozle rejects a reused transaction ID and does
not create a second usage effect.

## Dashboard

The customer **Entities** tab provides:

* active, suspended, and deleted Entity filters;
* create/edit, bulk upsert, activation, and suspension flows;
* plan, allocated top-up, shared, consumed, and effective balances;
* source provenance and expiry;
* immutable Entity operation history;
* allocation/deallocation previews and confirmations.

All mutation retries preserve their idempotency key until the result is known. Changing the payload starts a new key.

## Integration sequence

1. Create or bulk-upsert stable Entity IDs from your backend.
2. Configure per-Entity grant rules and one pool policy per plan/Credit System.
3. Read Entity balances before enabling mutation traffic.
4. Test transfers with a sandbox customer and Credit System.
5. Track usage with both `customer_id` and `entity_id` after the sandbox results are accepted.
6. If applicable, send seat events independently from your backend and verify current usage.
7. Run the acceptance audit before enabling shared fallback or broader traffic.

<CardGroup cols={2}>
  <Card title="Entity API" href="/api/customer-entities" />

  <Card title="Entity subscriptions" href="/api/entity-subscriptions" />

  <Card title="Entity balances" href="/api/entity-credit-balances" />

  <Card title="Node SDK" href="/sdks/node/credits" />

  <Card title="React components" href="/sdks/react/components" />
</CardGroup>
