Skip to content
CampaignsGift Codes

Gift Codes

Formerly Redemption Codes. API endpoints and event names are unchanged.

Learn how to validate and redeem campaign codes through the Tokenz Redemption Codes API.

The Redemption Codes API helps you run campaigns where players enter a code and receive a reward. Your server validates a code, confirms eligibility, redeems it, and then handles a redemption.completed webhook for fulfillment.

Overview

The redemption flow includes:

  • Validation: Check whether a code is redeemable and return a reward preview
  • Redemption: Consume the code for a specific player and create a redemption record
  • Webhook fulfillment: Receive redemption.completed and grant the reward in your game backend

Campaign setup and management

Campaigns and redemption codes are created and managed in the Tokenz Dashboard. Merchants use the Tokenz Dashboard to:

  • Create campaigns with active periods and reward configuration
  • Generate or manage redemption codes
  • Pause, resume, or end campaign operations

Campaign statuses

Campaigns can be in one of the following statuses:

  • draft: Work in progress. Redemption not allowed. All fields are editable.
  • scheduled: Published and queued. Automatically transitions to active at the configured start_at time.
  • active: Campaign is live and redemptions can succeed
  • paused: Manually paused. Redemptions are rejected. Can be resumed to active
  • ended: Campaign is finished. Redemptions are rejected. This state is irreversible

validate and redeem succeed when the campaign is active, and also when it is scheduled and its startAt has already been reached. They are rejected from endAt onwards. A scheduled campaign moves to active on its own at startAt, so this only matters in the short window around the transition.

Code statuses

Redemption code statuses are derived from the campaign status and the code's own status:

  • pending: Code is valid but the campaign is not currently active (e.g., draft, scheduled, or paused). Redemption is not allowed, except for a scheduled campaign whose startAt has been reached, which does accept redemptions.
  • active: Code is ready for use. Requires the campaign to be active. This is not the only redeemable status, because a pending code becomes redeemable once a scheduled campaign reaches its startAt.
  • deactivated: Code is disabled. This happens when a merchant manually deactivates a code, or when the campaign has ended.

The displayed code status depends on the campaign state:

Scroll horizontally if needed
Campaign statusCode status
activeactive
draft, scheduled, pausedpending
endeddeactivated

Once a campaign has passed its endAt, the code cannot be redeemed even though its status may still show as active. The API returns a redemptionCode.campaign-invalid error in this case, and the same error for a campaign that has not started yet.

If a merchant manually deactivates a code, it always shows as deactivated regardless of the campaign status.

Additionally, the Tokenz Dashboard displays a code as Redeemed when currentRedemptions >= maxRedemptions, even though the API status remains active. This is a display-only state in the Dashboard and is not returned by the API.

Redemption lifecycle

  1. Player enters a code in your promotional campaign UI
  2. Your server calls POST /v2/redemption-codes/validate
  3. Your server shows the reward preview to the player
  4. Player confirms redemption
  5. Your server calls POST /v2/redemption-codes/redeem
  6. Tokenz returns a successful redemption response
  7. Tokenz sends a redemption.completed webhook
  8. Your backend fulfills the reward and should use redemptionId to guard against duplicate fulfillment
Diagram
Diagram
100%
Scroll to explore · Zoom for detail

Validate a code

Validate checks campaign and code eligibility and returns the campaign preview plus reward preview. A successful validation requires the campaign to be active, or scheduled with its startAt reached, and before its endAt.

bash
curl --request POST \
  --url https://api.tokenz.one/v2/redemption-codes/validate \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --data '{
    "redemptionCode": "SPRING2026FREE",
    "playerId": "player_98765"
  }'

Request fields

  • redemptionCode (required): Code entered by the player
  • playerId (optional): Merchant player identifier. If provided, per-player limits are also checked. If omitted, only global code and campaign limits are validated

Success response (200)

json
{
  "campaign": {
    "id": "campaign_1AbCdEfGh12",
    "name": "Spring Campaign 2026"
  },
  "rewardPreview": {
    "name": "SSR Reimu Card",
    "imageUrl": "https://images.example.com/rewards/reimu.png",
    "quantity": 1
  }
}

Redeem a code

Redeem consumes the code for a player and creates a redemption record. A successful redemption requires the campaign to be active, or scheduled with its startAt reached, and before its endAt.

bash
curl --request POST \
  --url https://api.tokenz.one/v2/redemption-codes/redeem \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer secret_test_YOUR_KEY_HERE' \
  --data '{
    "redemptionCode": "SPRING2026FREE",
    "playerId": "player_98765"
  }'

Request fields

  • redemptionCode (required): Code entered by the player
  • playerId (required): Merchant player identifier

Success response (201)

json
{
  "redemptionId": "redemption_1XyZaBcDe34",
  "source": "CODE_REDEMPTION",
  "code": "SPRING2026FREE",
  "playerId": "player_98765",
  "campaign": {
    "id": "campaign_1AbCdEfGh12",
    "name": "Spring Campaign 2026"
  },
  "reward": {
    "skuRedemptionReward": {
      "type": "EXTERNAL_SKU",
      "sku": "ITEM_SSR_REIMU",
      "name": "SSR Reimu Card",
      "quantity": 1
    }
  },
  "redeemedAt": "2026-03-25T08:10:00Z"
}

Redemption webhook

After a successful redemption, Tokenz sends redemption.completed to webhook endpoints subscribed to this event.

Verify the signature before you grant anything. Every delivery carries a Tokenz-Signature header, and a handler that skips verification will grant rewards to anyone who finds or guesses its URL. Verify over the raw request body, then parse. See Secure your webhook endpoint for the steps. Treat the fields below as trustworthy only once the signature checks out.

json
{
  "id": "f75ff6f0-bdf9-4b25-bb96-968f8733a7e3",
  "object": "redemption.completed",
  "createdAt": "2026-03-25T08:10:00Z",
  "test": false,
  "eventData": {
    "type": "redemption",
    "version": "v2",
    "data": {
      "redemption": {
        "redemptionId": "redemption_1XyZaBcDe34",
        "campaign": {
          "id": "campaign_1AbCdEfGh12",
          "name": "Spring Campaign 2026"
        },
        "source": "CODE_REDEMPTION",
        "code": "SPRING2026FREE",
        "playerId": "player_98765",
        "reward": {
          "skuRedemptionReward": {
            "type": "EXTERNAL_SKU",
            "sku": "ITEM_SSR_REIMU",
            "name": "SSR Reimu Card",
            "quantity": 1
          }
        },
        "redeemedAt": "2026-03-25T08:10:00Z"
      }
    }
  }
}

Use the top-level event id for webhook delivery tracing, and use redemptionId to guard against duplicate fulfillment in your backend.

The same redemption.completed event is also sent for free item claims. Use source to tell CODE_REDEMPTION from FREE_ITEM_CLAIM. The code field is omitted for free item claims.

Error handling

Redemption endpoints return standard HTTP status codes with structured error objects.

Common errors

  • 401 Unauthorized: Invalid or missing API key
  • 403 Forbidden: API key does not have the required scope
  • 404 Not Found (entity.not-found): Redemption code not found
  • 422 Unprocessable Entity (campaign.limit-reached): The campaign has reached its total redemption limit
  • 422 Unprocessable Entity (campaign.player-limit-reached): The player has reached the per-campaign redemption limit
  • 422 Unprocessable Entity (redemptionCode.campaign-invalid): Campaign is not active, is outside its valid time window, or code is deactivated. The error message field distinguishes between these reasons
  • 422 Unprocessable Entity (redemptionCode.limit-reached): The redemption code has reached its own usage limit
  • 422 Unprocessable Entity (redemptionCode.player-limit-reached): The player has reached the per-code redemption limit for this code
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Server Error: Unexpected server error

Testing

Use test mode to develop and test your redemption integration:

  1. Use test API keys (prefixed with secret_test_) to interact with test campaigns and codes
  2. Create test campaigns in the Tokenz Dashboard using test mode
  3. Test redemptions are fully isolated from live data — a test API key can only redeem test codes, and a live API key can only redeem live codes
  4. Test entity IDs include a _t suffix (e.g., redemption_1XyZaBcDe34_t)
  5. Test webhooks are delivered only to your test webhook endpoints, with "test": true in the payload