Skip to content

API key request limits

Requires a license with the apikey-pro feature. See pricing.

A request limit caps how many requests one API key may make in a calendar month. Once the key reaches it, every further request answers 429 until the next month starts or you raise the limit. Everything else about keys, from creating them to reading their history, stays free on every install.

QuestionAnswer
What is countedEvery request the key makes on the Content API, whatever it answers, except the ones refused at the limit.
When the count resetsAt the start of each calendar month, in UTC.
What a key over its limit gets429 with X-RateLimit-Exceeded: true and {"error": "monthly request limit (100000) exceeded"}.
What 0 meansNo limit. It is the default.
Who countsUsage and quotas, which runs on every install. If the count cannot be read, the request goes through.

Run this on an install whose license carries apikey-pro. You need an admin token in TOKEN. The quickstart shows how to get one, and creates the post content type used here.

  1. Create a key that may make three requests this month:

    Terminal window
    curl -X POST http://localhost:3001/api/admin/api-keys \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"name": "partner-feed", "scopes": ["content:read"], "monthly_limit": 3}'

    The answer is 201 with "monthly_limit": 3. Copy raw_key into KEY and id into KEY_ID.

  2. Call the Content API four times with it:

    Terminal window
    for i in 1 2 3 4; do
    curl -s -o /dev/null -w "%{http_code}\n" http://localhost:3002/api/v1/content/post \
    -H "X-API-Key: $KEY"
    done

    You see 200, 200, 200, then 429.

  3. Read the key's use this month:

    Terminal window
    curl http://localhost:3001/api/admin/usage/api-key/$KEY_ID \
    -H "Authorization: Bearer $TOKEN"
    { "api_key_id": "bab86a15-...", "tenant_id": "default", "billing_period": "2026-10", "requests": 3, "bytes_in": 0, "bytes_out": 9 }

    The refused fourth call is not counted.

  4. Clear the limit, and the key is served again:

    Terminal window
    curl -X PATCH http://localhost:3001/api/admin/api-keys/$KEY_ID/monthly-limit \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"monthly_limit": 0}'

    The answer is the key with "monthly_limit": 0.

  5. In the admin console, Access > API keys shows how much of its limit each key has used this month, and lets you change the limit one key at a time.

Give a new key a limit with monthly_limit on POST /api/admin/api-keys, as in step 1, or change the limit of an existing key:

Terminal window
curl -X PATCH http://localhost:3001/api/admin/api-keys/$KEY_ID/monthly-limit \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"monthly_limit": 50000}'

Both routes take an admin or super_admin with a signed-in session. An admin token or another API key is refused.

WriteNeeds apikey-pro
Create a key with a monthly_limit above 0Yes
Give a key with no limit its first oneYes
Raise a key's limitYes
Lower a key's limitNo
Clear a limit with 0No
Send back the value the key already holdsNo

Every limit you set keeps being enforced, because it caps what a client can spend and a lapse must not lift it. Lowering and clearing a limit stay free, so you can still tighten a key you worry about. Setting a first limit or raising one needs apikey-pro again.

StatusMessageCause
400validation failed on field "monthly_limit"The limit is below 0.
402payment_required, naming feature:apikey-proThe write sets a first limit or raises one without apikey-pro. Nothing is stored.
404api key not foundNo key with that id in your tenant.
429monthly request limit (<n>) exceededThe key used its limit for this month.

The 402 body in full:

{"error": "payment_required", "plugin": "apikey", "feature": "feature:apikey-pro", "upgrade_url": ""}

The other errors of the key routes are on API keys.