# AI operations and Tokens

> Paid AI through the API, max_tokens, prices, per-key caps and what a sandbox does instead.

Some endpoints run NOWScale's AI and spend the Workspace's Tokens, exactly as the same feature in the app does. Your key needs the `ai:use` permission. Today the API offers drafting a reply to a comment (`POST /v1/ai/comment_replies`); more operations follow.

## Every paid call states its limit

Send `max_tokens`, the most the call may cost, in Tokens:

```bash
curl https://api.nowscale.com/v1/ai/comment_replies \
  -H "Authorization: Bearer $NOWSCALE_KEY" \
  -H "Idempotency-Key: 3f2a9c4e-1b7d-4e6a-9c2f-8d1e0b4a7c55" \
  -H "Content-Type: application/json" \
  -d '{"comment": "What camera do you use?", "video_title": "My studio tour", "max_tokens": 1}'
```

- Without `max_tokens` the call is refused with `402 max_tokens_required` and nothing is charged. The problem's `quote` tells you the price: its `operation` and `tokens`, a decimal string.
- When the price is higher than `max_tokens`, the call is refused with `402 max_tokens_exceeded` and the same `quote`.
- Otherwise the operation runs at that price, and the response's `tokens` says what was charged.

The price is fixed when the call starts: if it changes before the charge, the call is refused rather than charged more. Send an `Idempotency-Key` so a retry after a network error never charges twice.

## Caps per key

When you create a key with the `ai:use` permission in **Settings > API keys**, you can give it a daily and a monthly Token cap. A call that would pass a cap is refused with `402 key_spend_cap_reached`, which names the cap and the window (`day` or `month`, counted in UTC). A call that fails gives its reservation back.

The Workspace's own balance, plan allowance and Extra Usage settings still apply first: `402 insufficient_balance` or `402 overage_disabled` mean the Workspace, not the key, is out of Tokens.

## In a sandbox

AI in a sandbox is simulated: the answer is a realistic placeholder marked `"simulated": true`, no model runs and nothing is charged (`tokens` is `"0"`). Prices, `max_tokens` and key caps behave exactly as in live mode, so you can test the whole flow. The sandbox's test balance only refuses a call it could not cover.
