TANITARDevelopers
GuidesRewards

Award kinds and awards

The six system award kinds, your own award-kind registry, award definitions, and how awards are granted, read, resolved and optionally minted on a testnet.

An award is a durable record that a player (or an organization) earned something: a badge, a medal, a trophy. Every award is an instance of an award definition you author, and every definition has a kind.

Kinds

The six system kinds

These always exist, cannot be renamed or redefined, and each carries its own rules:

KindRules
achievementEarned automatically when a condition is met (see Achievement conditions)
badgeA player badge, usually paid by a mission or granted by you
medalBound to a tournament and a finishing rank; awarded when the tournament completes
trophyBound to a tournament and a finishing rank
prizeBound to a tournament and a finishing rank; the only kind that may declare a cash payout
organization-badgeAwarded to an organization rather than a player; carries no wallet value

Your own kinds

You can add kinds to your tenant's award-kind registry, such as season-champion or community-hero. A custom kind is a label for your own vocabulary: it carries none of the system rules (no condition, no tournament binding, no payout) and it is off-chain only.

RouteScopeDoes
GET /v1/award-kindsrewards:readYour custom kinds with the registry revision; system kinds are not listed
POST /v1/award-kindsrewards:mutateCreate a kind in draft: awardKindKey (lowercase slug, up to 64 characters) and displayName (up to 120)
PATCH /v1/award-kinds/:awardKindKeyrewards:mutateChange displayName; the key never changes
POST /v1/award-kinds/:awardKindKey/publishrewards:mutatedraft to published
POST /v1/award-kinds/:awardKindKey/archiverewards:mutatepublished to archived
curl -X POST "$REWARD_API_URL/v1/award-kinds" \
  -H "Authorization: Bearer $TANITAR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"awardKindKey":"season-champion","displayName":"Season champion"}'

A definition can name a custom kind only while it is published. Archiving a kind blocks new definitions from naming it; definitions and awards that already use it are unaffected. Every write raises the registry revision, so you can cache the list against it.

StatuserrorCodeCause
422AWARD_KIND_INVALIDThe key is not a canonical lowercase slug
422AWARD_KIND_RESERVEDThe key is one of the six system kinds
422AWARD_KIND_UNAVAILABLEThe key does not exist, or a definition names a kind that is not published
409AWARD_KIND_EXISTSThe key already exists
409AWARD_KIND_TRANSITION_INVALIDPublishing a non-draft or archiving a non-published kind
409AWARD_KIND_REVISION_CONFLICTThe entry changed concurrently; read and retry

Award definitions

A definition says what an award is and what it carries. Definitions move from draft to published to retired; only a published definition can be awarded, and a retired one can no longer change.

RouteScope
GET /v1/awards/definitions (filters kind, status, tournamentId)rewards:read
GET /v1/awards/definitions/:awardKeyrewards:read
POST /v1/awards/definitionsrewards:mutate
PATCH /v1/awards/definitions/:awardKeyrewards:mutate
POST /v1/awards/definitions/:awardKey/publishrewards:mutate
POST /v1/awards/definitions/:awardKey/retirerewards:mutate
FieldRule
awardKeyLowercase slug, up to 64 characters, unique in your tenant
kindA system kind or one of your published kinds
name, descriptionUp to 120 and 2000 characters
mediaOptional image and artwork URLs
valueOptional, up to 8 entries of currencyKey and a positive integer amount; every currency must be published
walletScope, gameSlugWhere value is credited; gameSlug is required for game
conditionRequired for, and only allowed on, achievement
tournamentId, rankRequired for, and only allowed on, medal, trophy and prize
payoutOnly on prize: ISO currency currency (three lowercase letters) and amountMinor
curl -X POST "$REWARD_API_URL/v1/awards/definitions" \
  -H "Authorization: Bearer $TANITAR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"awardKey":"autumn-cup-gold","kind":"medal","name":"Autumn Cup gold","description":"First place, Autumn Cup","value":[{"currencyKey":"red","amount":1000}],"walletScope":"platform","tournamentId":"autumn-cup","rank":1}'

A definition bound to a tournament can only be created or changed by a caller that owns the tournament's organization. Shape violations are refused with 422 and a specific code such as AWARD_CONDITION_REQUIRED, AWARD_BINDING_REQUIRED, AWARD_CURRENCY_UNPUBLISHED or AWARD_VALUE_INVALID.

Achievement conditions

An achievement definition names one condition from a closed set, each observed on an event the Gamification service publishes:

condition.kindMet whenExtra field
mission-completedThe named mission has been completed threshold timesmissionKey
streak-daysThe player's streak reaches threshold daysnone
level-reachedThe player reaches level thresholdnone
total-xpThe player's total XP reaches thresholdnone

GET /v1/awards/trigger-policy returns this table as data: each condition, the event that produces it and whether it is producible.

Awards

Awards are created in three ways:

  • Automatically on tournament completion, for every published medal, trophy and prize definition bound to that tournament and a finishing rank.
  • Automatically when an achievement condition is met.
  • By your integration with POST /v1/awards/grants.

Each trigger produces exactly one award record. If the definition has a value, the currency is credited through the grant spine in the same transaction, and a value that cannot settle makes the award rejected as a whole.

Award statusMeaning
appliedThe award is held, and its value (if any) is in the wallet
rejectedSettled as refused, with rejection.code and rejection.reason; for example AWARD_ALREADY_HELD or AWARD_DEFINITION_MISSING
unresolvedA tournament placement could not be attributed to a player; the award waits for you to name the recipient

Grant an award

POST /v1/awards/grants with scope rewards:mutate. This is the route behind the product term "operator grant", and awards created this way carry the provenance operator-grant.

FieldRule
awardKeyA published definition
subjectTypeplayer or organization
playerId or organizationIdThe recipient, matching subjectType
reasonOptional, up to 500 characters
curl -X POST "$REWARD_API_URL/v1/awards/grants" \
  -H "Authorization: Bearer $TANITAR_API_KEY" \
  -H "Idempotency-Key: 6c1d0f4e-2b8a-4f0e-9d51-8a0f3b7c2e11" \
  -H "Content-Type: application/json" \
  -d '{"awardKey":"community-hero","subjectType":"player","playerId":"player-7f3a","reason":"Moderated the September finals"}'

The award's identity is derived from your Idempotency-Key, so repeating the request with the same key returns the same award rather than a second one. Granting an organization badge, or a definition bound to a tournament, requires that you own the organization concerned.

Read and resolve awards

  • GET /v1/awards lists awards, newest first. It requires one of playerId, organizationId or tournamentId, unless you ask for status=unresolved. Other filters: awardKey, kind, status, and limit (1 to 100, default 50). No cursor. Invalid filters are refused with 400 AWARD_QUERY_INVALID.
  • GET /v1/awards/:awardId reads one award, or 404 AWARD_NOT_FOUND.
  • POST /v1/awards/:awardId/recipient with { "playerId": "…" } settles an unresolved award to the player you name.
  • POST /v1/awards/tournaments/:tournamentId/settle re-runs award settlement for a completed tournament from its stored placements. Use it after publishing a definition that should have applied: it only adds awards that are missing and never duplicates one.

Players see their own awards through the Player surface and may equip one of their applied awards as a displayed title. Every settled award publishes reward.award-granted (see the event catalog).

On-chain fulfillment (testnets)

When your deployment has Web3 enabled, an applied award of a system kind that has a collection on the chain can be minted as a token on a testnet: Ethereum Sepolia, Hedera testnet or Solana. Mainnets are refused.

  • GET /v1/web3/capabilities lists the chains your tenant can use now. A chain that is absent is disabled.
  • POST /v1/awards/:awardId/fulfillments with chain, the player's destination address and an optional metadataUri (at most 200 characters) mints the award. There is one fulfillment per award and chain: a repeated request reaches the existing record, and answers 409 FULFILLMENT_PENDING while its transaction is still unconfirmed rather than broadcasting again.
  • GET /v1/awards/:awardId/fulfillments reads its status: claimed, submitted, confirmed, failed or unresolved.
  • GET /v1/awards/:awardId/mint-records and POST /v1/awards/:awardId/mint-records read and record the resulting token identity (chain, contract, token id, wallet, transaction).

A custom kind has no collection on any chain, so a fulfillment request for one is refused with FULFILLMENT_KIND_UNSUPPORTED before any chain is contacted. To check what the chains are running, see Web3 verification.

On this page