Skip to main content
API Key Management - visual guide

API Key Management

How to create, scope, rotate and revoke API keys safely. One key per job, least privilege, and exactly what to do when a key leaks.

What a key looks like

An API key authenticates every Customer API request. It is 56 characters and always has the same shape:

gsk_a1b2c3d4_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
โ”‚    โ”‚        โ”‚
โ”‚    โ”‚        โ””โ”€ 43-character secret
โ”‚    โ””โ”€ 8-character key id - safe to log, safe to show
โ””โ”€ prefix, always gsk_

Send it as a bearer token: Authorization: Bearer gsk_....

PartLengthSafe to share?
gsk_ prefix4Yes
Key id8Yes - this is the identifier to use in logs, dashboards and support tickets
Separator _1-
Secret43No. Anyone holding it can act as the key

The full key is shown once, on the screen where you create it. It is stored only as a one-way hash, so nobody - including GameGrid support - can show it to you again. If you lose it, create a new key and revoke the old one.

Player tokens are not API keys

A key starting gsk_ belongs to your account and acts for it. A player token starts gpt_: one of your players creates it with /my api-token create in Discord, where you allow it, and it reads only that player's own statistics under /api/public/v1/me/. It cannot manage anything or read anyone else, never appears in this list, and is controlled from Player access and the player's profile (see Player Self-Service).

Creating a key

Keys are created and destroyed in the customer panel, under Account โ†’ API Keys, signed in as yourself. This is deliberate: there is no scope that lets an API key create another API key, so a leaked key cannot mint a broader or longer-lived successor.

1. Open Account โ†’ API Keys and choose Create Key.

2. Give it a name that says what it is for. nightly-backup-script will still mean something in six months; test2 will not. Names must be unique within your organization.

3. Pick the scopes. Grant the smallest set that lets the job finish - see API Scopes and Permissions.

4. Copy the key. This is the only time it is shown.

Every key created in the panel expires 90 days after it is made. The form asks for a name, a description and the scopes, and nothing else - there is no expiry picker, so the platform default is what you get. The expiry date is shown on the key in the list, and rotating a key carries the same date across. There is no expiry notification, so put the date in your own calendar.

Restricting a key to particular servers is not something the create form offers. The platform enforces the restriction where it exists - a restricted key gets 404 server_not_found for anything outside its list, the same response as a server that does not exist, so it cannot be used to discover what else you own - and GET /account/keys/current reports it. Setting one up is a support request today.

You can only grant scopes you personally hold. Asking for more returns 422 scope_exceeds_permissions - which is usually a sign you are creating the key from the wrong account.

Start from a preset

The scope list on the create form is long, and most keys are one of a handful of jobs. So the form offers a preset for each of those jobs: one click ticks the scopes that job needs, and you can tick or untick anything afterwards.

Each preset carries a line saying what a key made from it will and will not be able to do. Read it before you create the key - a key cannot be widened later, and a key that holds more than its job needs is the thing this whole article is about.

PresetWhat a key made from it can doWhat it cannot do
Uptime & status pageRead whether each server is up, its CPU, memory and history, and the player count and player listsStart, stop or change anything
BackupsTake a backup, list backups, and delete, relabel or reschedule old ones so a nightly run stays inside your quotaRestore a backup over your live server
Server control & consoleStart, stop and restart a server, read its status and metrics, and send console commandsChange settings, files, mods or backups
Discord botReport status, start and stop servers, send console commands, create and run scheduled commands, schedule and run config events, message players in game, post leaderboards and answer each member's /my with their own statisticsRead the live map, or change settings, files, mods or backups
Community & economyRead your shop, wallets and transactions, let a player spend their own balance, and link or unlink a player's chat account to their in-game oneAward currency or rewrite your shop
Key & audit reviewList your keys - names and dates, never a secret - and read the last 24 hours of API calls and panel actions, including the refused onesChange or revoke anything
Everything read-onlyEvery read scope there is, including your billing summary, your files, your console history and the live mapChange anything

Only one preset reads where your players are standing. Reading the live map covers player positions, so it is left out of the Discord bot preset on purpose - tick it yourself if you want the bot's map commands. Everything read-only is the one preset that includes it, and its line on the form says so before you click.

A preset is a starting point, not a ceiling. If your job is close to one of them, pick it and adjust; if it is nothing like any of them, press Clear and tick what you need. The form shows the exact scope behind every tick, and API Scopes and Permissions explains each one.

One key per job

The single most useful habit with API keys is to stop having one key that does everything.

Separate keys mean you can revoke a compromised integration without taking down the other five; the audit trail tells you which integration did something, not just "a key did"; and each key carries only the scopes its own job needs, so a leaked status-page key cannot wipe a server.

Instead ofUse
One key with every scopestatus-page with servers:read
backup-cron with servers:read, backups:create, backups:read
discord-bot with the scopes that bot actually needs
admin-tools with maintenance:execute, used by hand and nothing else

Scope is the lever you have in the panel, so use it hard. A key for one community's Minecraft server has no business holding economy:admin, and a status-page key has no business holding anything but servers:read.

Rotating a key

Rotation replaces a key's secret without changing what the key is allowed to do. Use it on a schedule, when someone leaves, or any time you are not certain where a key has been.

Rotate from Account โ†’ API Keys โ†’ Rotate. Only the member who created a key can rotate it, whatever their role: a rotation hands the new secret to whoever presses the button, and the new key still acts as the member who created it. An account owner or administrator can revoke another member's key instead (below); on such a key the page offers Revoke and says only its creator can rotate it. The panel rotates with no overlap: the old secret stops working the moment the new one is minted, and the old key then returns 401 token_expired. There is no grace-period control on the dialog, and none is implied.

So treat a rotation as a cutover, not a migration. Have the new secret ready to deploy before you press the button, and expect anything still holding the old one to start failing immediately. If that is not acceptable for an integration, create a second key alongside the first, move the integration onto it, and revoke the original once nothing is using it.

Rotation carries over the key's name, description, scopes, expiry date and every server restriction. Rotation does not carry over the secret (a brand-new one is minted) or the 8-character key id - so any logging or dashboard that matches on the key id needs updating.

Rotation is a panel action. There is no API endpoint that rotates a key, by design.

Revoking a key

Revoking is immediate and permanent. A revoked key cannot be restored; create a new one instead. Revoked keys take effect within about a minute across the platform.

From the panel

Delete the key in Account โ†’ API Keys. This is the normal route. Every member who can see the list sees every key, but only the member who created a key, or an account owner or administrator, can revoke it; on anyone else's key the page says so in place of the buttons.

From the key itself

A key can switch itself off:

DELETE /api/public/v1/account/keys/{its own key id}
Authorization: Bearer gsk_...

This is a containment tool. A script that detects it has been compromised can kill its own access at 3am without waiting for a human to sign in.

Two things to get right before you rely on it. The key must hold the keys:revoke scope - without it the call returns 403 insufficient_scope. And a key can only revoke itself: passing any other key id returns 403 insufficient_scope with the rule self_revocation_only, even if you own that other key. If self-revocation is part of your incident plan, put keys:revoke on the key when you create it and test the call once.

If a key leaks

Work in this order.

1. Revoke it. Panel, or the key's own DELETE /account/keys/{keyId} if it holds keys:revoke. Do this before investigating - a revoked key cannot do further damage while you read logs.

2. Read the audit trail. GET /account/audit (scope audit:read) covers a rolling 24-hour window and records every Customer API call made with your organization's keys - including calls that were rejected - alongside panel actions on your servers. Rejected calls matter: they show what an attacker tried and failed to do, which tells you what they were after.

3. Check when it was last used. GET /account/keys reports last_used_at for each key, and the panel shows the same thing on the key's row. For *where* a call came from, use GET /account/audit - the key list does not carry an address.

4. Check what changed. Settings history (GET /servers/{id}/settings/history), backups, mods and player lists all keep their own records. Restore from a backup taken before the window if anything is wrong.

5. Create the replacement with narrower scopes than the one that leaked. A leak is the best evidence you will ever get about which scopes a job actually needed.

The audit trail is your detection tool for key misuse. Webhooks are not - there is no event for "a key did something unexpected", and no webhook fires on a wipe or a reinstall. Poll GET /account/audit on a schedule if you want alerting. See Webhook Configuration for what webhooks can and cannot tell you.

Checking what a key can do

GET /account/keys/current returns the calling key's own record - its id, name, scopes, expiry, server restrictions, last use and organization_id, the id of the account the key belongs to (the same id GET /account returns). The Discord bot reads it so that re-running /setup with another key of the same account keeps your role grants. It needs no scope, precisely so that a key with a mistyped scope list can still discover what it holds.

Two fields in that response are worth reading in a deploy check:

  • unrecognized_scopes - scope strings written on the key that the platform does not recognise. Usually a typo, and always worth fixing, because a typo'd scope grants nothing.
  • server_restrictions - the servers this key is limited to, if any.

If a call fails, this endpoint plus GET /servers/{id}/capabilities will explain almost every 403 and 501 without a support ticket.

Key expiry and hygiene

HabitWhy
Diary the 90-day expiry when you create a keyEvery panel-created key gets one, and nothing reminds you. An integration that stops at 3am on day 91 is the most common "the API broke" ticket there is.
Watch expires_at on GET /account/keysThere is no expiry notification. A key that lapses returns 401 token_expired, and the integration simply stops. Poll for it.
Store keys in a secret manager or environment variableNever in source control, a shared document, a screenshot or a support ticket.
Quote the 8-character key id, never the whole keyThe key id identifies a key uniquely and is safe to share, including with support.
Revoke keys for departed staff and retired integrationsUnused keys are the ones nobody notices being used.