API keys and scopes
How API keys are created, rotated and revoked, how to send them, and what each scope allows.
An API key identifies your back end to Tanitar. Each key belongs to one account, carries a set of scopes that decide which routes it may call, and is limited by your plan. You manage keys in the dashboard.
Key format
A key looks like this:
defendr_key_2b0f3c1e-8d7a-4f55-9a61-0c4e2d9b7f13.Yq3n…43 characters…It has two parts: a public key identifier (key_…) and a secret. Tanitar keeps only a keyed
digest of the secret, so the full key is shown exactly once: when you create or rotate it.
Send it as a bearer token:
GET /v1/currencies HTTP/1.1
Authorization: Bearer defendr_key_2b0f3c1e-8d7a-4f55-9a61-0c4e2d9b7f13.Yq3n…The APIs also accept the key in an X-API-Key header. Send one or the other; if you send both
they must carry the same key, or the request is refused with 401 and ACCESS_CREDENTIAL_INVALID.
Managing keys in the dashboard
Only administrators of your organization can create, change, rotate or revoke keys. Any member can see the key list, which shows each key's name, display prefix, scopes, state and revision. It never shows the secret.
| Action | What happens |
|---|---|
| Create | You give the key a name, select its scopes and, optionally, an expiry. The full key is shown once in Save this key now. |
| Edit | You can rename a key or reduce its scopes. The dashboard cannot add scopes to an existing key: create a new key instead. |
| Rotate | Tanitar issues a new key identifier and secret on the same key record, keeping its name and scopes. The new key is shown once; the old value stops working. |
| Revoke | The key moves to revoked and can never be used again. Revocation is final. |
A few rules apply to every key:
- Scopes cannot exceed your plan. Selecting a scope your account is not entitled to is refused
with
409andSCOPE_CEILING_EXCEEDED. - Events assistant scopes never go on a key. The Events assistant acts only for a signed-in
member of your organization, so creating or updating a key with one of its four scopes is refused
with
409andAPI_KEY_SCOPE_EXCLUDED, whatever your plan includes. They are listed under "Scopes a key cannot carry" below. - Your plan caps active keys. The default plan allows 5 active, unexpired keys; creating
another is refused with
409andACTIVE_KEY_LIMIT. Revoke a key you no longer use to free a slot. - Changes are revision-checked. If two administrators edit the same key at once, the second
change is refused with
409andREVISION_CONFLICT; reload and try again. - Expired keys stop working at their expiry time.
Resolved key state is cached by the APIs for at most 30 seconds. A key you rotate or revoke can therefore keep working for up to 30 seconds afterwards. When you rotate, deploy the new key first, then retire the old one.
How scopes are checked
Each route declares the scope it requires. On every request Tanitar checks two things:
- The key carries the scope. If not, the request is refused with
403andACCESS_SCOPE_DENIED. - Your account is still entitled to it. If your plan no longer includes the scope, the request
is refused with
403andACCESS_ENTITLEMENT_DENIED, even if the key was created with it.
Give each key only the scopes it needs. A service that ingests gameplay events needs
gamification-events:ingest and nothing else; a shop fulfilment worker needs shop:read and
shop:fulfill.
Scope reference
The tables below list every scope a key can carry, grouped by API, with the routes it unlocks. The guides document each route in detail. The last table lists the scopes a key can never carry.
Tournament API
Served from TOURNAMENT_API_URL. Tournament routes have no /v1 prefix.
| Scope | Allows |
|---|---|
organizations:read | Read your organizations: GET /organizations, GET /organizations/:organizationId. |
organizations:mutate | Create, update, enable, disable and delete organizations, for example POST /organizations and POST /organizations/:organizationId/disable. |
tournaments:read | Read tournaments and their structure: GET /tournaments, GET /tournaments/:slug, GET /tournaments/:slug/public, entrants, stages, stage compositions and matches, GET /teams/:teamId, and the stage previews POST /tournaments/:slug/stages/preview and POST /tournaments/:slug/stage-compositions/preview. On the Game API it also reads the game catalog (GET /games/find, GET /games/:gameId). |
tournaments:mutate | Create, update and delete tournaments and drive their lifecycle with POST /tournaments/:slug/publish, POST /tournaments/:slug/start, POST /tournaments/:slug/complete, POST /tournaments/:slug/cancel, registration and check-in closing. It also covers stages, teams and members, enrollments (confirm, check-in, withdraw, roster decisions), free-agent requests and PATCH /matches/:matchId. |
participants:mutate | Act for participants in a match: mark readiness with POST /matches/:matchId/ready and submit, update, upload and withdraw evidence, for example POST /matches/:matchId/evidence. |
participants:read | Grants no route an API key can call. |
results:read | Read results: GET /tournaments/:slug/standings, GET /matches/:matchId/result-revisions, match evidence and its media URL. On the Game API it also reads player game statistics (GET /player-game-stats/find). |
results:mutate | Decide results: PUT /matches/:matchId/result, POST /matches/:matchId/result/revert, POST /matches/:matchId/evidence/:evidenceId/review, and evidence media removal with DELETE /matches/:matchId/evidence/:evidenceId/media/:mediaId. |
Events API
Served from EVENT_API_URL. Event routes have no /v1 prefix.
| Scope | Allows |
|---|---|
events:read | Read events and their published details. |
events:mutate | Create and update events, publish or unpublish them, and delete events. |
events:pages:read | Read an event's page with GET /events/:eventId/page, list its revisions with GET /events/:eventId/page/revisions, and preview a design with POST /events/:eventId/page/preview. |
events:registrations:read | Read the registration settings with GET /events/:eventId/registration-settings, the registrations with GET /events/:eventId/registrations, and the state of a registration operation. |
events:registrations:mutate | Configure registration with PUT /events/:eventId/registration-settings, register players with POST /events/:eventId/registrations, and retry a registration operation. Adding contact details to a registration operation needs players:contact:mutate as well. |
events:badges:read | Read an event's badges with GET /events/:eventId/badges, its badge definitions, templates and jobs, and a badge's history, and create a print link with POST /events/:eventId/badges/:issueId/print-link. |
events:badges:mutate | Set badge definitions and templates, issue badges with POST /events/:eventId/badges/issues, start and retry badge jobs, and resend or revoke a badge. |
events:tickets:read | Read an event's ticketing: its settings with GET /events/:eventId/tickets/configuration, its orders with GET /events/:eventId/tickets/orders, and its ticket templates, presentation and authentication settings (GET /events/:eventId/tickets/templates, GET /events/:eventId/tickets/presentation, GET /events/:eventId/tickets/authentication). |
events:tickets:mutate | Configure ticketing with PUT /events/:eventId/tickets/configuration and the templates, presentation and authentication settings with PUT on the same paths. Retrying an order with POST /events/:eventId/tickets/orders/:orderId/retry needs messaging:replay as well. Manual orders (create, cancel, payment link emails) are made in the dashboard only. |
events:tickets:admit | Admit a ticket holder at the door with POST /events/:eventId/tickets/admission. |
Gamification API
Served from GAMIFICATION_API_URL.
| Scope | Allows |
|---|---|
gamification-events:ingest | Send gameplay events with POST /v1/gamification/events. |
gamification-catalog:author | Author the catalog: create, update, disable and read missions (POST /v1/gamification/catalog/missions), read the event registry, and manage the level curve, chest economy, chest and tier settings, and battle-pass seasons. |
gamification-catalog:approve | Approve catalog changes with POST /v1/gamification/catalog/approvals. |
gamification-config:mutate | Register, archive and delete event types in the event registry: POST /v1/gamification/event-registry, POST /v1/gamification/event-registry/:eventKey/archive, DELETE /v1/gamification/event-registry/:eventKey. |
gamification-progress:read | Read player progress with GET /v1/gamification/players/:playerId/progress and leaderboards with GET /v1/gamification/leaderboards/:period/:entityType. |
gamification-progress:replay | Replay progress with POST /v1/gamification/replay and grant chests with POST /v1/gamification/chests/grants. |
quizzes:read | Read quizzes and what they hold: GET /v1/quizzes, GET /v1/quizzes/:quizId, its analytics with GET /v1/quizzes/:quizId/analytics, its allocations with GET /v1/quizzes/:quizId/allocations, and quiz media with GET /v1/quizzes/media/:mediaId. |
quizzes:mutate | Create, update, publish and extend quizzes (POST /v1/quizzes, PATCH /v1/quizzes/:quizId, POST /v1/quizzes/:quizId/publish, POST /v1/quizzes/:quizId/extend) and upload their media with POST /v1/quizzes/media. |
quizzes:recover | Act on one player's quiz allocation with POST /v1/quizzes/:quizId/allocations/:playerId/:action. |
Reward API: rewards
Served from REWARD_API_URL.
| Scope | Allows |
|---|---|
rewards:read | Read currencies, wallets (GET /v1/wallets/:playerId), reward grants, award kinds, award definitions and awards, exchanges, payouts and payout capabilities, KPIs, search, and Web3 capabilities, deployments and self-tests. |
rewards:mutate | Manage currencies (POST /v1/currencies) and award kinds, author and publish award definitions, grant awards (POST /v1/awards/grants), settle tournament awards, request fulfilment, mint records and payouts, reconcile or release exchanges and payouts, run Web3 verifications and self-tests, and post wallet value with POST /v1/wallet-value/post. |
Reward API: shop
Served from REWARD_API_URL.
| Scope | Allows |
|---|---|
shop:read | Read listings and orders: GET /v1/shop/listings, GET /v1/shop/listings/:listingKey, GET /v1/shop/orders, GET /v1/shop/orders/:orderId. |
shop:mutate | Create, update, publish and retire listings, and load code stock with POST /v1/shop/listings/:listingKey/stock/codes. |
shop:fulfill | Claim and fulfil orders: POST /v1/shop/orders/:orderId/claim, POST /v1/shop/orders/:orderId/fulfillment. |
shop:reverse | Reverse an order with POST /v1/shop/orders/:orderId/reversal. |
shop:disclose-code | Disclose a delivered code with POST /v1/shop/orders/:orderId/code-disclosures. Keep this scope on as few keys as possible. |
Identity API
Served from IDENTITY_API_URL.
| Scope | Allows |
|---|---|
player-membership:grant | Grant membership with POST /v1/player-memberships/grant and read a player's membership with GET /v1/player-memberships/:playerId. |
player-membership:revoke | Revoke membership with POST /v1/player-memberships/revoke. |
player-membership-tier:read | List membership tiers with GET /v1/membership-tiers. |
player-membership-tier:author | Create, update, publish, archive and set the default membership tier, for example POST /v1/membership-tiers and POST /v1/membership-tiers/:levelKey/publish. |
player-rename:read | Read the nickname-change price with GET /v1/nickname-pricing. |
player-rename:configure | Set the nickname-change price with PUT /v1/nickname-pricing. |
players:contact:read | Read a player's contact details with GET /v1/players/:playerId/contact. |
players:contact:mutate | Set a player's contact details with PUT /v1/players/:playerId/contact. With events:registrations:mutate, it also lets a key add contact details to an event registration. |
Notification API
Served from NOTIFICATION_API_URL.
| Scope | Allows |
|---|---|
notifications:mutate | Send a notification to a player's inbox with POST /v1/player-notifications. |
Tenant API
Served from TENANT_API_URL.
| Scope | Allows |
|---|---|
audit:read | Read your account's audit history with GET /v1/audits. |
Message recovery
Served by the Tournament and Gamification APIs, each for its own messages. These routes have no
/v1 prefix.
| Scope | Allows |
|---|---|
messaging:read | List and read dead-lettered messages: GET /platform/recovery/dead-letters, GET /platform/recovery/dead-letters/:deadLetterId. |
messaging:replay | Replay or discard dead letters, revive outbox entries and schedules, and redispatch from the archive, for example POST /platform/recovery/dead-letters/:deadLetterId/replay. |
See dead-letter recovery.
Scopes with no API-key route
You can select these scopes, but no route an API key can call requires them. Webhooks (see webhooks) and event page changes, in particular, are managed in the dashboard.
| Scope | Allows |
|---|---|
automation:read | No API-key route. |
automation:mutate | No API-key route. |
automation:execute | No API-key route. |
events:pages:mutate | No API-key route. Your organization's administrators save, reset, restore and edit event page drafts in the dashboard; an API key gets 403 with ACCESS_ROLE_DENIED. |
events:pages:publish | No API-key route. Your organization's administrators publish and withdraw event pages in the dashboard; an API key gets 403 with ACCESS_ROLE_DENIED. |
webhooks:read | No API-key route. |
webhooks:mutate | No API-key route. |
webhooks:replay | No API-key route. |
Scopes a key cannot carry
The Events assistant in the dashboard uses these scopes. Its routes accept only a signed-in member
of your organization, never a key, so the dashboard does not offer these scopes when you create a
key, and creating or updating a key with one of them is refused with 409 and
API_KEY_SCOPE_EXCLUDED. The scope catalog still lists them; whether your members can use the
assistant depends on your plan.
| Scope | Allows |
|---|---|
agent:read | With events:agent:read, a member reads their own conversations with the Events assistant and follows its runs. |
agent:run | With events:agent:run, a member starts, continues and deletes their own conversations with the Events assistant. |
events:agent:read | The Events assistant's part of agent:read. |
events:agent:run | The Events assistant's part of agent:run. |