# Usage and billing

> **Note**
>
> The usage endpoint, `POST /v1/admin/billing/usage`, is available on SaaS only. On-premises deployments have no credit allowance. See [SaaS](saas.md).

CKEditor AI counts the credits your requests consume and attributes each request to a user. Read those numbers from your backend for any period: the total for the environment, and the credits per user. This page covers the request, the response, and what happens when the allowance runs out.

<a id="what-you-can-use-it-for">

## What you can use it for

* **Find the heavy users:** get the credits per user for any period, then group them into your own teams or workspaces.
* **Stay inside your allowance:** read the usage on a schedule, and act before the environment reaches its plan limit.
* **Show usage in your product:** give admins in your app a view of their team’s AI usage without exporting anything.
* **Bill each tenant:** if you resell AI features, meter the usage per tenant or per seat.

<a id="how-usage-is-measured">

## How usage is measured

CKEditor AI measures usage in credits. Every billable request consumes credits from the allowance of your environment: a chat message, an action, a review, or a document processing call. The service attributes each request to the user ID in the `sub` claim of the token that sent the request. Your plan sets the size of the allowance.

> **Note**
>
> One allowance covers the whole environment. The per-user numbers show which users consumed the credits. They are not separate allowances.

<a id="read-your-usage">

## Read your usage

Send a `POST` request to `/v1/admin/billing/usage` with a token that has the `ai:admin` permission (see [Who can call it](#who-can-call-it)). The body takes these fields:

| Field   | Type            | Description                                                                                                                                             |
| ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from`  | string          | The start of the period, in ISO 8601 format.                                                                                                            |
| `to`    | string          | The end of the period, in ISO 8601 format. Must be later than `from`.                                                                                   |
| `users` | array or string | Optional. An array of user IDs, or the string `"*"` for every user with activity in the period. Without it, the `users` array in the response is empty. |

The simplest request returns the environment total:

```bash
curl -s "https://ai.cke-cs.com/v1/admin/billing/usage" \
	-H "Authorization: Bearer $ADMIN_TOKEN" \
	-H "Content-Type: application/json" \
	-d '{
		"from": "2026-06-01T00:00:00Z",
		"to": "2026-06-30T23:59:59Z"
	}'
```

```json
{
	"environment": {
		"id": "df5ghywes2e1r3hy7v4p",
		"credits": 9650
	},
	"users": []
}
```

<a id="break-it-down-per-user">

### Break it down per user

To get the credits for specific users, send an array of their user IDs:

```bash
curl -s "https://ai.cke-cs.com/v1/admin/billing/usage" \
	-H "Authorization: Bearer $ADMIN_TOKEN" \
	-H "Content-Type: application/json" \
	-d '{
		"from": "2026-06-01T00:00:00Z",
		"to": "2026-06-30T23:59:59Z",
		"users": [ "user_123", "user_456" ]
	}'
```

Send the string `"*"` to get every user with activity in the period:

```bash
curl -s "https://ai.cke-cs.com/v1/admin/billing/usage" \
	-H "Authorization: Bearer $ADMIN_TOKEN" \
	-H "Content-Type: application/json" \
	-d '{
		"from": "2026-06-01T00:00:00Z",
		"to": "2026-06-30T23:59:59Z",
		"users": "*"
	}'
```

```json
{
	"environment": {
		"id": "env-id-00000000",
		"credits": 9650
	},
	"users": [
		{ "userId": "user_123", "credits": 8500 },
		{ "userId": "user_456", "credits": 1150 }
	]
}
```

The response does not list users with no activity in the period. The user IDs are the IDs your token endpoint issues, so you can join the response to your own accounts, tenants, or teams.

<a id="who-can-call-it">

## Who can call it

The request needs a token with the `ai:admin` permission. That permission grants full administrative access to your environment. Call this endpoint from your backend only, and never issue an admin token to a browser or to an end user. See [Permissions](permissions.md) for the other scopes.

<a id="when-the-allowance-runs-out">

## When the allowance runs out

On the free plan, CKEditor AI blocks the environment when it exceeds its limit for the billing period, and rejects each request with this error:

```json
{
	"message": "Usage limits exceeded",
	"code": "usage-limits-exceeded",
	"explanation": "The environment is blocked because usage for the current billing period has exceeded the limit.",
	"action": "Please contact our customer support team or upgrade your plan.",
	"data": {
		"environmentId": "env-id-00000000",
		"usageExceededTo": "2025-12-19T12:00:00.000Z"
	}
}
```

The service rejects requests until the time in `data.usageExceededTo`, then accepts them again. To remove the block earlier, upgrade the plan.

On paid plans, CKEditor AI bills the extra usage as overage, and the AI features keep responding.

<a id="next-steps">

## Next steps

* **[Permissions](permissions.md)** lists the scopes you can put in a token, including `ai:admin`.
* **[Authentication](authentication.md)** shows how to build the token endpoint that sets the `sub` claim.
* **[REST API](rest-api.md)** links the API reference and lists the rate limits.

---

Full index of the Cloud Services documentation: [llms.txt](../../../llms.txt)
