API keys & scopes
- Written for
- + Written for
- Deprecated
- + Deprecated
- Applies to
- + Applies to
API keys & scopes
API keys let your servers, scripts, CI jobs, the CLI, the Publisher SDK and the MCP server act on your Cool GPT Games account without a browser. This page covers creating, listing and revoking keys, what each scope unlocks, what keys can never do, and how to handle keys safely.
Quick facts
Format | New keys start with |
How to send |
|
Lifetime | No expiry. A key works until you revoke it. |
Revocation | Takes effect on the very next request |
Shown | Once, at creation. It can't be retrieved later. |
Creation limit | 10 new keys per hour per account |
Who can manage keys | You, signed in to the dashboard. Keys can't create, list or revoke keys. |
Creating a key
In the dashboard
Sign in and open Dashboard → API keys.
Enter a name that says where the key will live, for example
github-actionsormy-laptop.Choose scopes:
Leave Full access (
*) ticked for a key that can do everything a key can do, orUntick it and tick only the scopes the key needs (at least one).
Select Create key and copy the key straight away. It's shown once. If you lose it, revoke the key and create a new one.
With the API
POST /v1/me/keys creates a key. It requires an interactive session (you signed in on the website). An API key calling it gets 403 session_required. In practice, use the dashboard.
Request body:
Field | Type | Required | Notes |
|---|---|---|---|
| string, 1–80 chars | Yes | A label for your own reference |
| array of scope names | No | Any of |
Response (201 Created):
{
"id": "0f9c…",
"name": "github-actions",
"keyPrefix": "ak_aed3cbe11f59",
"scopes": ["publish", "read"],
"createdAt": "2026-09-21T10:02:11.000Z",
"key": "ak_…",
"availableScopes": ["read", "publish", "tournaments", "webhooks", "config", "analytics", "economy"]
}key is the secret. This is the only response that ever contains it.
Errors:
Status | Code | Why |
|---|---|---|
|
| Called with an API key instead of a signed-in session |
|
| Your sign-in session predates the current sign-in system. Sign out, sign in again, then retry. |
|
| More than 10 keys created in the past hour |
|
| Missing name, or an unknown scope name |
|
| The key service is temporarily unreachable. Retry shortly. |
Listing keys
GET /v1/me/keys (session only) returns every key on your account, newest first, including revoked ones. It never includes the secret.
{
"keys": [
{
"id": "0f9c…",
"name": "github-actions",
"keyPrefix": "ak_aed3cbe11f59",
"scopes": ["publish", "read"],
"createdAt": "2026-09-21T10:02:11.000Z",
"revokedAt": null,
"lastUsedAt": null,
"kind": "atlas"
}
]
}keyPrefixis the start of the key. Use it to match a key you hold to a row here.revokedAtis set once a key is revoked.lastUsedAtis alwaysnullat the moment, so the dashboard shows "never" for every key. Don't rely on it to find unused keys.kindis always"atlas". It exists for compatibility and you can ignore it.
Revoking a key
In the dashboard, select Revoke next to the key. Through the API, DELETE /v1/me/keys/:id (session only) does the same and returns { "ok": true }.
Revocation is immediate. Anything using the key gets
401 unauthorizedon its next request.Revoking an already-revoked key succeeds and changes nothing.
An id that isn't one of your keys returns
404 not_found.Revoked keys can't be restored. Create a new one.
Scopes
A key's scopes are fixed when it's created. To change them, create a new key and revoke the old one.
A signed-in session is never scope-limited. Scopes only restrict API keys.
What each scope unlocks
Some endpoints check a scope; the others accept any valid key. The table lists every endpoint that checks one.
Scope | Endpoints it unlocks | Typical use |
|---|---|---|
| Games: | CI publishing, the CLI, the Publisher SDK |
|
| Read-only dashboards and reporting |
|
| Pull event, crash and player stats into your own tools |
|
| Change remote config from a script or ops tool |
|
| Manage webhook endpoints |
|
| Schedule tournaments from your server |
|
| Manage your in-game store items |
| Everything a key can do | Personal keys on a trusted machine |
A key without the required scope gets:
{ "error": { "code": "forbidden", "message": "This API key lacks the \"publish\" scope." } }(HTTP 403.)
Two details to know:
publishcoversread. A publishing key can read back what it just published (moderation status, versions) without also holdingread. Nothing else implies another scope.Unpublished games stay hidden from keys without
read.GET /v1/games/:slugis public for published games. For your own draft, scanning, rejected or taken-down game, a key withoutread(orpublish) gets404 not_found, exactly as a stranger would.
Endpoints that accept any key
These don't check a scope. Any valid key on your account can call them, whatever scopes it holds:
GET /v1/auth/me(a handy "does this key work?" check)Player-facing endpoints that act as the account holder and don't move coins, for example saves and social features. These are normally driven by the game player page, not by developer tooling.
What keys can never do
These routes reject every API key, including full-access (*) keys, with 403 session_required. Do them signed in on coolgptgames.com (account and key management live in the dashboard).
Route | Action |
|---|---|
| Create, list or revoke API keys |
| Set up or change where payouts are sent |
| Edit your public profile |
| Change your email |
| Delete your account |
| Account settings and preferences |
| Claim the daily coin reward |
| Gift coins to a friend |
| Buy from the platform cosmetics shop |
| Claim a season reward tier |
| Buy an in-game store item |
| Fund a tournament prize pool from your coins |
So even a leaked full-access key can't lock you out, hide itself by revoking your other keys, mint fresh keys, redirect your payouts, or spend or move your coins. Free tournaments (no prize pool) can still be created with a tournaments key. A leaked key with publish can still act on your games, so revoke a leaked key immediately.
How key checks work
On every request that carries a key:
The key's secret is verified.
The key must belong to your account and must not be revoked.
Your account must not be banned or deleted.
If the endpoint needs a scope, the key must hold that scope or
*.
A failure at steps 1–3 returns 401 unauthorized, exactly as if no key had been sent. A failure at step 4 returns 403 forbidden.
If the key-verification service is briefly unreachable, requests fail with 503 atlas_unavailable rather than 401. This is temporary: retry with backoff, and don't treat it as a bad key.
Best practices
Least privilege
Create one key per place it's used: one per CI pipeline, one per server, one per laptop. When one leaks, you revoke only that key.
Pick the narrowest scopes that work. For example:
Job | Scopes |
|---|---|
CI that publishes builds (and checks the verdict) |
|
Reporting or dashboard script |
|
Ops tool that tweaks remote config |
|
Tournament scheduler |
|
Webhook provisioning |
|
Store management |
|
A
publishkey already coversread, so a CI job that publishes and then checks moderation status needs onlypublish.
Storing keys
Keep keys in a secret store: your CI's encrypted secrets, a cloud secret manager or a password manager. Never commit them to git, and never put them in a game bundle, a web page or client-side JavaScript. Everything in a game bundle is public.
Read the key from an environment variable at runtime (the CLI and MCP server use
ARCADEY_API_KEY).Keys never appear in API responses after creation, but they can leak through logs. Don't print request headers in CI output.
CI
A typical GitHub Actions setup:
# .github/workflows/publish.yml
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check the key works
env:
COOLGPTGAMES_API_KEY: ${{ secrets.COOLGPTGAMES_API_KEY }}
run: |
curl -fsS https://api.coolgptgames.com/v1/auth/me \
-H "Authorization: Bearer $COOLGPTGAMES_API_KEY" > /dev/nullStore the key as a repository or environment secret, not a plain variable.
Remember the shared limit of 100 requests per minute per IP, and the hourly upload allowance (see Errors & limits). CI runners that share IPs share that per-IP budget.
Rotation
Keys don't expire, so rotate them on your own schedule (for example every 90 days) and whenever someone with access leaves:
Create the new key in the dashboard with the same scopes.
Update the secret everywhere the old key is used.
Confirm the new key works (
GET /v1/auth/me).Revoke the old key.
Because each key is independent, the old and new keys can overlap for as long as you need.
If a key leaks
Revoke it in Dashboard → API keys straight away. It stops working on the next request.
Check your games in the dashboard for unexpected new versions, edits or deletions, and roll back if needed.
Create a replacement key and update your secrets.
See also
REST API overview: authentication, errors, the full endpoint index - Errors & limits: every error code and limit - CLI, Publisher SDK, MCP server: tools that use API keys