How spending works
A key has credits whencredits.remaining is a number. If it’s null or missing, the key is unlimited. Each keys.verifyKey call costs 1 unless the request sets credits.cost, any integer from 0 to 1,000,000,000,000.
Credits are checked last, so a key that fails any other check (disabled, expired, rate limited, missing permissions) doesn’t lose credits. What happens next depends on the balance:
- Enough credits. The cost is deducted and the response’s
creditsfield shows the new balance. - Not enough. Nothing is deducted, the verification fails with
code: USAGE_EXCEEDED, andcreditsshows the unchanged balance.
0 checks the key without spending anything, so you can check a key or read its metadata for free.
Add credits to a key
Setcredits.remaining when creating the key, or later with keys.updateKey.
integer | null
Starting balance, 0 or more. On
keys.updateKey, null removes the limit entirely and also clears any refill schedule. On keys.createKey, null isn’t allowed, so omit credits instead.Refill on a schedule
A refill resets the balance to a fixed amount on a schedule. It replaces the balance rather than adding to it: a key with 50 credits left and a refill of 1000 has 1000 afterward, not 1050. You must setcredits.remaining in the same request.
string
required
daily or monthly.integer
required
The balance after each refill, 1 or more.
integer
1 to 31. Required when
interval is monthly. Leaving it out fails with HTTP 400 err:unkey:application:invalid_input. With daily, keys.updateKey rejects it with the same error and keys.createKey ignores it. If the month is shorter, the refill runs on its last day, so 31 works in February.refillDay. A key that’s already at or above its amount is left alone.
To stop refilling but keep the current balance, send credits.refill: null on keys.updateKey. To change the schedule, send the whole refill object again.
Change a balance directly
Usekeys.updateCredits for top-ups, purchases, and refunds. It changes the balance and leaves the refill schedule alone.
string
required
The key to change.
string
required
set replaces the balance with value, increment adds value, and decrement subtracts value and clamps at zero.integer | null
0 or more. Required for
increment and decrement. With set, null makes the key unlimited.increment and decrement fail with HTTP 400 err:unkey:application:invalid_input. To give an unlimited key a quota, send set first.
api.*.update_key or api.<api_id>.update_key for both keys.updateKey and keys.updateCredits. See Root key permissions.
Credits vs rate limits
Use both when you sell a quota and also want burst protection. The rate limit stops a client from burning the quota in a second, and credits enforce the quota. See Key and identity rate limits.