TANITARDevelopers
Getting started

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.

ActionWhat happens
CreateYou give the key a name, select its scopes and, optionally, an expiry. The full key is shown once in Save this key now.
EditYou can rename a key or reduce its scopes. The dashboard cannot add scopes to an existing key: create a new key instead.
RotateTanitar 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.
RevokeThe 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 409 and SCOPE_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 409 and API_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 409 and ACTIVE_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 409 and REVISION_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:

  1. The key carries the scope. If not, the request is refused with 403 and ACCESS_SCOPE_DENIED.
  2. Your account is still entitled to it. If your plan no longer includes the scope, the request is refused with 403 and ACCESS_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.

ScopeAllows
organizations:readRead your organizations: GET /organizations, GET /organizations/:organizationId.
organizations:mutateCreate, update, enable, disable and delete organizations, for example POST /organizations and POST /organizations/:organizationId/disable.
tournaments:readRead 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:mutateCreate, 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:mutateAct 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:readGrants no route an API key can call.
results:readRead 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:mutateDecide 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.

ScopeAllows
events:readRead events and their published details.
events:mutateCreate and update events, publish or unpublish them, and delete events.
events:pages:readRead 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:readRead 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:mutateConfigure 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:readRead 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:mutateSet 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:readRead 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:mutateConfigure 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:admitAdmit a ticket holder at the door with POST /events/:eventId/tickets/admission.

Gamification API

Served from GAMIFICATION_API_URL.

ScopeAllows
gamification-events:ingestSend gameplay events with POST /v1/gamification/events.
gamification-catalog:authorAuthor 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:approveApprove catalog changes with POST /v1/gamification/catalog/approvals.
gamification-config:mutateRegister, 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:readRead player progress with GET /v1/gamification/players/:playerId/progress and leaderboards with GET /v1/gamification/leaderboards/:period/:entityType.
gamification-progress:replayReplay progress with POST /v1/gamification/replay and grant chests with POST /v1/gamification/chests/grants.
quizzes:readRead 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:mutateCreate, 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:recoverAct on one player's quiz allocation with POST /v1/quizzes/:quizId/allocations/:playerId/:action.

Reward API: rewards

Served from REWARD_API_URL.

ScopeAllows
rewards:readRead 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:mutateManage 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.

ScopeAllows
shop:readRead listings and orders: GET /v1/shop/listings, GET /v1/shop/listings/:listingKey, GET /v1/shop/orders, GET /v1/shop/orders/:orderId.
shop:mutateCreate, update, publish and retire listings, and load code stock with POST /v1/shop/listings/:listingKey/stock/codes.
shop:fulfillClaim and fulfil orders: POST /v1/shop/orders/:orderId/claim, POST /v1/shop/orders/:orderId/fulfillment.
shop:reverseReverse an order with POST /v1/shop/orders/:orderId/reversal.
shop:disclose-codeDisclose 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.

ScopeAllows
player-membership:grantGrant membership with POST /v1/player-memberships/grant and read a player's membership with GET /v1/player-memberships/:playerId.
player-membership:revokeRevoke membership with POST /v1/player-memberships/revoke.
player-membership-tier:readList membership tiers with GET /v1/membership-tiers.
player-membership-tier:authorCreate, update, publish, archive and set the default membership tier, for example POST /v1/membership-tiers and POST /v1/membership-tiers/:levelKey/publish.
player-rename:readRead the nickname-change price with GET /v1/nickname-pricing.
player-rename:configureSet the nickname-change price with PUT /v1/nickname-pricing.
players:contact:readRead a player's contact details with GET /v1/players/:playerId/contact.
players:contact:mutateSet 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.

ScopeAllows
notifications:mutateSend a notification to a player's inbox with POST /v1/player-notifications.

Tenant API

Served from TENANT_API_URL.

ScopeAllows
audit:readRead 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.

ScopeAllows
messaging:readList and read dead-lettered messages: GET /platform/recovery/dead-letters, GET /platform/recovery/dead-letters/:deadLetterId.
messaging:replayReplay 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.

ScopeAllows
automation:readNo API-key route.
automation:mutateNo API-key route.
automation:executeNo API-key route.
events:pages:mutateNo 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:publishNo 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:readNo API-key route.
webhooks:mutateNo API-key route.
webhooks:replayNo 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.

ScopeAllows
agent:readWith events:agent:read, a member reads their own conversations with the Events assistant and follows its runs.
agent:runWith events:agent:run, a member starts, continues and deletes their own conversations with the Events assistant.
events:agent:readThe Events assistant's part of agent:read.
events:agent:runThe Events assistant's part of agent:run.

On this page