# Secure Captcha API Keys: IP Allowlists, Rotation, Spend Caps

> Protect a captcha API key and your balance: scopes, IP allowlists, daily spend caps, rotation with an overlap, instant revocation, and spotting a leaked key.

- Source: https://zerocaptcha.io/guides/secure-captcha-api-keys
- Published: 2026-09-30
- Updated: 2026-10-01
- Author: ZeroCaptcha Engineering

A CAPTCHA-solving key spends money. Anyone who has it can create tasks that are charged to your
balance, so it deserves the same care as a payment credential. ZeroCaptcha gives each key five
controls: scopes, an IP allowlist, a daily spend cap, rotation with an overlap, and instant
revocation. This guide explains each one and a setup that limits the damage of a leak.

## What a key looks like, and why

A ZeroCaptcha key is 41 characters: `zc_live_`, 27 random characters, then a 6-character
checksum. The fixed prefix makes a leaked key easy to spot in logs and code, and the checksum lets
a secret scanner confirm a match without calling the API.

A key is shown once, when you create it, and only its hash is stored. Put it straight into a
secret manager or your deployment's environment, never into source control. After that, the
dashboard shows it only by its first and last characters, such as `zc_live_8K2p…f41c`.

## 1. Scopes: only what the code needs

Each key has one or both of two scopes:

- `tasks`: create tasks and read them, their results and their live updates.
- `balance`: read the balance.

A monitoring job that only watches the balance needs a `balance` key and nothing else. A call
outside a key's scopes is refused with `ERROR_ACCESS_DENIED` (`insufficient_scope` in REST).

## 2. IP allowlist: only from your servers

A key can be held to up to 100 IPv4 or IPv6 addresses or CIDR networks, such as `203.0.113.24` or
`198.51.100.0/24`. A call from any other address is refused with `ERROR_IP_NOT_ALLOWED`. A leaked
key then does nothing for whoever found it, unless they are also on your network.

Write networks with no bits set past their prefix: `198.51.100.0/24`, not `198.51.100.7/24`.
Changes apply from the key's next call.

## 3. Daily spend cap: a ceiling per day

A key can have a daily spend cap in US dollars: the most its tasks may hold or be charged in one
UTC day. A task that would pass it is refused before any money moves, with
`ERROR_SPEND_CAP_REACHED` (HTTP 402 `spend_cap_reached` in REST). Tasks that fail or expire stop
counting toward it.

Set the cap a little above a normal day's spend. A runaway loop or a stolen key then costs at most
one day's cap, and the refusals tell you something is wrong. See
[Captcha solving cost](https://zerocaptcha.io/guides/captcha-solving-cost) to size a normal day.

## 4. Rotation with an overlap

Rotate keys on a schedule, and at once when one may have leaked. Rotating makes a new key with the
old one's name, scopes and allowed addresses, and shows it once. The old key keeps working for the
overlap you choose: **1 hour, 24 hours or 7 days**. Deploy the new key during the overlap, and your
running code never stops. When you are done, end the overlap from the keys page, or let it run
out. After that, the old key is refused as revoked.

## 5. Revocation: stop a key now

Revoking stops a key at once: every later call is refused with `ERROR_KEY_REVOKED`. Tasks it
already created run to their end, charged only if they succeed. A revoked key stays listed, so
older tasks can still be traced to it, but it can never work again.

## Know when a key was used

The keys page shows when each key last made a call it was allowed to make, and the address it came
from, recorded in batches up to half a minute behind. A key that shows use from an address you do
not recognize is the signal to revoke it.

## A setup that works

- **One key per service or environment**, named after it, so a leak is contained and easy to trace.
- **Scopes** matched to what each service does.
- **An allowlist** with your servers' egress addresses.
- **A daily cap** on every key that creates tasks.
- **Rotation** every few months, with a 24-hour overlap.
- **Callbacks checked** with their HMAC signature, so a forged result cannot reach your code:
  see [Verify a webhook's HMAC signature](https://zerocaptcha.io/guides/verify-webhook-hmac-signature).

Keys are managed only from a signed-in dashboard session: no API key can create, change or revoke
keys, its own included. Two-factor authentication on the account is optional, and worth turning on
for the people who manage keys.

The [API keys](https://zerocaptcha.io/docs/keys) docs have the full reference. To put a key to work, see the
[Cloudflare Turnstile solver](https://zerocaptcha.io/cloudflare-turnstile-solver) page.

## Questions

### Can ZeroCaptcha show me my API key again?

No. A key is shown once, when it is created, and only its hash is stored. If you lose it, create a new key or rotate the old one.

### What happens to running tasks when I revoke a key?

They run to their end and are charged only if they succeed. Every later call with the revoked key is refused.

### How many keys can an account have?

Up to 20 active keys. A key being replaced by a rotation, and a revoked key, does not count toward the limit.
