---
title: "Usage and quotas"
description: "Usage statistics, quotas and credit mode."
requested_language: hu
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/hu/payload/ai/usage-and-quotas
version: unreleased (main)
docs_index: https://docs.systhema.app/hu/llms.txt
---
> This page isn't translated yet. Showing English.


## Usage statistics

Every generation — text and image, including aborted and failed runs — is logged to a hidden **AI Usage** collection (`systhema-ai-usage`): kind, mode, action, provider and model, token counts, an **estimated cost** (built-in list prices, correctable via `pricing`), the prompts, inputs and outputs (stored verbatim but length-capped for inspection, not archival), and for images the source/result upload references. Documents are immutable and written server-side only; the `ai.usage.read` gating below is the privacy boundary for this content. A run that finds nothing to generate (empty target) short-circuits to success without reserving a quota slot or billing.

The log is gated by the **`ai.usage.read` capability**, which no built-in role except `dev` holds (via its `*` wildcard) — admins and editors never see it, and the collection is hidden from their admin nav entirely. Grant the capability to a custom role to share it deliberately.

## Quotas (subscription limits)

`quota` turns the usage log into enforced subscription limits. Counters cover the current billing period (computed in UTC from `period`), count every billed generation — completed, aborted, and failures that occurred after a successful (billed) provider call — and reset automatically when the period rolls over:

```ts
ai: {
  text: { ... },
  quota: {
    text: 200,        // 200 text generations per period
    image: 50,        // 50 images per period (0 = images not in the plan)
    period: { interval: 'month', startDay: 1 },
  },
}
```

Once a limit is hit, the matching endpoint blocks with HTTP 429 and a human-readable message (including the reset date) that surfaces directly in the admin UI. Enforcement counts persisted usage plus in-flight generations, so concurrent requests can't slip past the last remaining slot (in-flight tracking is per server instance; the persisted log is the cross-instance source of truth).

Whenever AI is enabled, a compact **AI usage** panel is pinned to the bottom of the admin sidebar (`admin.components.afterNavLinks`) — always visible while editing, showing per-kind (or pooled-credit) usage for the current period and the reset date. Any signed-in admin user sees it; it carries no costs and no per-generation detail. With quota limits set, the rows become used/limit progress bars; without, they show plain counts marked "Unlimited".

An **AI usage** dashboard widget (`admin.dashboard.widgets`) with the same data is also **registered** — but it is **not** placed in the default dashboard layout, because the sidebar panel already surfaces usage. To show it on the dashboard, add it from the dashboard editor. A consumer's own `defaultLayout` is never touched.

When a limit is set, the widget also shows a **pace-based forecast** for the binding metric (the pooled credit balance in credit mode, otherwise whichever capped kind is pacing hottest): how much of the allowance is used, how much is projected to remain in reserve at the current burn rate, the countdown to reset, and a verdict — _"Lasts until reset"_ when the projection stays within budget, or _"Runs out in ~Nd"_ when it doesn't.

A compact version of the same panel is also pinned to the **bottom of the admin sidebar** (via `admin.components.afterNavLinks`), so editors can watch their usage move while they work without leaving the page. It refreshes on a light poll, on window focus and after each generation, is **collapsible** (the collapsed state persists per-user through Payload's native preferences — account-tied, so it survives refreshes and follows you across devices), and notes that the allowance is **shared across all users**. The quota/credits are project-wide — every user draws from the same pool. Both surfaces share one data hook and never show USD.

Set `packageName` to label the plan you sell (e.g. `"Systhema AI Free"` / `"Systhema AI Pro"`). It appears as a heading on the usage widget and is woven into the "limit reached" message when a quota runs out (e.g. _"Your Systhema AI Pro plan's text generation limit for this period is used up…"_). Purely cosmetic — it has no effect on what is allowed.

### Credit mode

For plans where per-kind counts can't bound cost — a long translation costs several times a short meta title, and one image can cost as much as dozens of texts — set `quota.credits` to switch to a single **pooled credit balance** instead:

```ts
ai: {
  text: { provider: 'openai', model: 'gpt-5.5', /* … */ },
  image: { provider: 'openai', model: 'gpt-image-2' },
  quota: {
    credits: 5000,        // pooled budget per period (≈ $5 at the default creditValue)
    // creditValue: 0.001, // USD per credit (hidden from editors); default 0.001
    period: { interval: 'month', startDay: 1 },
  },
}
```

Each generation debits `actual_cost ÷ creditValue` credits, computed from the same token/image pricing used for the usage log — so spend tracks real provider cost regardless of kind. `creditValue` is never shown to editors; it only sets the granularity (`0.001` ⇒ a typical text generation ≈ 1 credit, a `$5` budget ≈ 5,000 credits). When `credits` is set it **supersedes** the `text`/`image` counts: the gate blocks once the pooled balance is exhausted, and the widget shows a single **Credits** balance with a `(?)` tooltip of this site's average credit cost per text / per image. Leave `credits` unset (the default) to stay in count mode.

The widget and `/systhema/ai/usage` endpoint are visible to **any authenticated admin user** and never expose USD — dollar amounts stay in the developer-only usage collection.
