API keys
Every request to a/api/v1/public/ endpoint authenticates with a key in the X-API-Key header, except
requests to /api/v1/public/status, which needs none. The pay-per-call route under /api/v1/x402/ needs no key (see Pay per call with x402):
cck_ followed by 56 hex characters. There is no
Authorization: Bearer support. From a browser a Bearer token returns 401.
From a command-line client such as curl or python-requests it is rejected one
layer earlier, as 403 {"error":"Forbidden"} with no code field, because a
request carrying no X-API-Key is not recognised as an API client at all.
Always send X-API-Key.
Create, list, and revoke keys at
cctools.network/profile/api. The
cleartext is shown exactly once at creation; afterward only the prefix is
visible. Once you hold one,
cctools.network/api-docs runs any endpoint
against it in the browser.
How many active keys you can hold depends on your plan; the number for each is
in Plans and limits. The per-minute limit is counted per key and
endpoint, so each extra key adds throughput, while the daily limit is counted
for the whole account and does not grow with the number of keys.
Plans
Your key has the plan of your account, and the plan sets your rate limits. It is echoed on every response asmeta.tier.
The limits count differently. The per-minute limit is per key and endpoint. The
daily limit is per account, over a UTC day, and the calls of all your own keys add up.
What each plan may be used for. An evaluation key is for testing and Pro is for
personal use. The Data plans allow commercial use, with attribution, of the
endpoints marked Data plans in the Use column of the
endpoint reference. The endpoints marked Personal use are
personal use on every plan. The terms are at
cctools.network/terms/api, and the figures
and prices at Plans and limits.
The Free plan has ended. A key made on it answers
401 with the code
tier_retired and a renew_url that points to the plans: take a plan, then
create a new key.
Getting a plan
Open /profile/api. The plan panel shows what your account can take, and New key stays off until it holds a plan.- Pro: with a CCTools Pro subscription, the plan panel shows Pro as your plan. Press Set up keys once (an account that had a Free or an evaluation key sees Upgrade to Pro tier instead), then New key.
- Evaluation: to test the API before you buy, ask our team for an evaluation key. An account that has never held a plan applies on that page; any other account contacts us. Our team issues it on request, for testing only; how long it lasts is in Plans and limits.
- Data Starter and Data Team: Buy Data Starter or Buy Data Team and pay in Canton Coin, for a month or a year. You accept the API terms at checkout. Data plan payments are not refunded, except where the law requires it. A plan does not renew by itself: access ends at the end of the period unless you renew. A Data plan bought while the same or a larger Data plan runs starts when that one ends. A smaller Data plan that is running pauses while a larger one runs and resumes after it.
- Validator: submit a party ID on the same page.
- Enterprise: contact us.
401 with the code plan_ended).
Your keys follow your account’s plan, up to the plan’s number of keys. A key
you make takes the limits of the plan your account holds, and it runs until that
plan’s coverage ends. If you hold more keys than the plan allows, the most
recently used stay and the others end. When you
renew Pro or buy a Data plan, your existing keys take the new
coverage, so there is no new key to make: after renewing Pro, press Extend access
on /profile/api and your keys are
extended to match. Pressing it never lowers anything: a Validator or Enterprise
plan granted to your account stays. When no plan is left, your keys answer 401
with the code plan_ended and a renew_url. Renewing Pro or a Data plan brings them back; an ended evaluation is extended by our team, so contact us.
Rate limits
Two limits count your calls. The per-minute limit is counted per key, per endpoint, per minute, per process. The API runs as a multi-process cluster where each process keeps its own counter, so a client spreading requests across many connections can exceed the stated figure before anything pushes back. Treat the number as the sustained rate to design for rather than a ceiling to probe. When you do exceed it you get429 with a Retry-After: 60 header:
429 with the code daily_limit, a Retry-After set to the seconds left
until 00:00 UTC, and X-RateLimit-Remaining-Day: 0:
daily_limit too,
with the same Retry-After. A key under a daily cap gets X-RateLimit-Limit-Day
and X-RateLimit-Remaining-Day on every successful response and on both 429s,
rate_limited and daily_limit; if the counter cannot be read, only
X-RateLimit-Limit-Day is sent.
Every successful response also carries your ceiling in
meta.rate_limit_remaining. On plans with no per-key limit it is null, so
type it as nullable. meta.daily_limit_remaining is the calls you have left
today; it is null when your plan has no daily cap or the counter could not be
read.
Errors
Most errors carry
{ "error": "...", "code": "..." }, but the code is
specific to the endpoint rather than drawn from a fixed list. Branch on the
HTTP status, which is stable, and treat code as detail. Two responses come
from the edge layer before the handler runs and carry only { "error" } with
no code at all: the 403 for a keyless tool client, and the 429 for the
per-IP ceiling.
Good practice
Keep keys server-side
Keep keys server-side
Never ship a key in a browser bundle or mobile app. Proxy through a backend
you control. A leaked key can be used up to its rate limit until you revoke it.
Rotate on suspicion
Rotate on suspicion
Revoking is immediate: the key starts returning
401 right away. Mint a
replacement first, cut over, then revoke the old one.Handle 429 gracefully
Handle 429 gracefully
Respect
Retry-After. For steady workloads, stay under your plan’s limits
rather than bursting and backing off.