Phoenix Gamification
Rewards

Rewards

Rewards are the tangible prizes users receive for achievements, milestones, and competition victories. Phoenix separates what you give (Reward Items) from when you give it (Reward Configs and feature triggers).

Rewards

Rewards are the tangible prizes users receive for achievements, milestones, and competition victories. Phoenix provides a flexible reward system that separates what you give (Reward Items) from when you give it (Reward Configs and feature triggers).

🛒 Looking for the Rewards Store?

If you want to let users spend their points to purchase prizes, see the Rewards Store Guide. This page covers the reward system for automatic distribution through leaderboards, streaks, and achievements.


1. Core Concepts

Reward Items

Reward Items are standalone, reusable definitions of what a user receives. They live in the reward_items table and can be referenced by:

  • Coupons: Each coupon definition links to a reward_item_id
  • Reward Configs: Tiers reference items by item_ids
  • Leaderboards, Streaks, Achievements: Via attached reward configs

Reward Configs

Reward Configs define the conditions for when rewards are distributed (rank ranges, milestones, thresholds). They contain tiers that reference reward items.

Feature Integration

FeatureHow Rewards Work
CouponsEach coupon definition has a reward_item_id - users get the item when they redeem
LeaderboardsAttach a reward_config_id - distribute items when window completes based on rank
StreaksAttach a reward_config_id - distribute items when milestones are reached
AchievementsAttach a reward_config_id - distribute items when achievements complete

2. Reward Items API

Create a Reward Item

Endpoint

POST /v1/reward-items?tenant_id=${tenant_id}

Request Body

{
  "name": "1000 Gems",
  "description": "Premium currency bundle",
  "reward_type": "currency",
  "payload": {
    "currency_id": "gems",
    "amount": 1000
  }
}

Response

{
  "item_id": "550e8400-e29b-41d4-a716-446655440000",
  "tenant_id": "your-tenant-id",
  "name": "1000 Gems",
  "description": "Premium currency bundle",
  "reward_type": "currency",
  "payload": {"currency_id": "gems", "amount": 1000},
  "created_at": "2025-01-15T10:00:00Z",
  "updated_at": "2025-01-15T10:00:00Z"
}

Save the item_id - you'll use it when creating coupons or reward configs.

Reward Types

The reward_type field is flexible - use any string that makes sense for your fulfillment pipeline:

TypeDescriptionExample Payload
currencyIn-game currency{"currency_id": "gems", "amount": 1000}
itemVirtual item/consumable{"item_id": "legendary_chest", "quantity": 1}
xpExperience points{"amount": 5000}
badgeAchievement badge{"badge_id": "top_player_2025"}
physical_itemPhysical prize{"model": "iPhone 15 Pro", "shipping_required": true}
customAny custom reward{"your": "custom", "data": "here"}

Managing Reward Items

ActionEndpointMethod
List items/v1/reward-items?tenant_id=${tenant_id}GET
Get item/v1/reward-items/{item_id}?tenant_id=${tenant_id}GET
Create item/v1/reward-items?tenant_id=${tenant_id}POST
Update item/v1/reward-items/{item_id}?tenant_id=${tenant_id}PUT
Delete item/v1/reward-items/{item_id}?tenant_id=${tenant_id}DELETE

3. Using Reward Items with Coupons

The simplest integration is with coupons. Each coupon definition specifies which reward item users receive upon redemption.

Step 1: Create the Reward Item

POST /v1/reward-items?tenant_id=${tenant_id}
{
  "name": "Welcome Bonus - 500 Coins",
  "description": "Coins granted to new users",
  "reward_type": "currency",
  "payload": {
    "currency_id": "coins",
    "amount": 500
  }
}

Response: item_id: "reward-item-001"

Step 2: Create a Coupon Definition

POST /v1/coupons?tenant_id=${tenant_id}
{
  "name": "Welcome Bonus Coupon",
  "description": "New user welcome gift",
  "config": {
    "reward_item_id": "reward-item-001",
    "code_format": "random",
    "code_prefix": "WELCOME",
    "code_length": 8,
    "usage_limit": {
      "limit_type": "per_user",
      "max_uses": 1
    }
  }
}

Step 3: User Redeems Coupon

When a user redeems the coupon, the response includes the reward item details:

{
  "code": "WELCOME8X4F2K9P",
  "status": "redeemed",
  "reward_item": {
    "item_id": "reward-item-001",
    "name": "Welcome Bonus - 500 Coins",
    "reward_type": "currency",
    "payload": {"currency_id": "coins", "amount": 500}
  }
}

Your application then fulfills the reward (adds 500 coins to the user's account).


4. Reward Configs for Leaderboards

For leaderboards, you create a Reward Config that maps rank ranges to reward items. The config is attached to leaderboard definitions.

Step 1: Create Reward Items

Create items for each prize tier:

# First place prize
POST /v1/reward-items?tenant_id=${tenant_id}
{
  "name": "Champion's Crown",
  "reward_type": "badge",
  "payload": {"badge_id": "weekly_champion"}
}
# Response: item_id: "crown-item-001"

# Top 10 prize
POST /v1/reward-items?tenant_id=${tenant_id}
{
  "name": "5000 Gems",
  "reward_type": "currency",
  "payload": {"currency_id": "gems", "amount": 5000}
}
# Response: item_id: "gems-5000-item"

# Top 100 prize
POST /v1/reward-items?tenant_id=${tenant_id}
{
  "name": "1000 Gems",
  "reward_type": "currency",
  "payload": {"currency_id": "gems", "amount": 1000}
}
# Response: item_id: "gems-1000-item"

Step 2: Create Reward Config

For reward catalog entries (store items, etc.), use the rewards catalog. For leaderboard tier configs, the config is typically part of the leaderboard or a dedicated config API:

POST /v1/rewards-catalog?tenant_id=${tenant_id}
{
  "name": "Weekly Top 100 Rewards",
  "description": "Rewards for weekly leaderboard winners",
  "tiers": [
    {
      "condition": {
        "type": "rank_range",
        "start": 1,
        "end": 1
      },
      "item_ids": ["crown-item-001", "gems-5000-item"]
    },
    {
      "condition": {
        "type": "rank_range",
        "start": 2,
        "end": 10
      },
      "item_ids": ["gems-5000-item"]
    },
    {
      "condition": {
        "type": "rank_range",
        "start": 11,
        "end": 100
      },
      "item_ids": ["gems-1000-item"]
    }
  ]
}

Response: config_id: "weekly-top100-config"

Step 3: Attach to Leaderboard

POST /v1/leaderboards?tenant_id=${tenant_id}
{
  "leaderboard_id": "xp-weekly-global",
  "name": "Global Weekly XP",
  "reward_config_id": "weekly-top100-config",
  "config": {
    "timeframe": {
      "type": "weekly",
      "timezone": "UTC",
      "reset_day": "monday"
    }
  }
}

Step 4: Window Completion

When the weekly window completes, Phoenix:

  1. Finalizes standings (top 1000 users)
  2. Matches each user's rank to reward tiers
  3. Sends webhook with reward distribution:
{
  "event_type": "leaderboard.window_completed",
  "tenant_id": "your-tenant-id",
  "leaderboard_id": "xp-weekly-global",
  "window_key": "2025-W02",
  "completed_at": "2025-01-13T00:00:02Z",
  "reward_distribution": [
    {
      "user_id": "user-123",
      "rank": 1,
      "score": 12850,
      "items": [
        {
          "item_id": "crown-item-001",
          "name": "Champion's Crown",
          "reward_type": "badge",
          "payload": {"badge_id": "weekly_champion"}
        },
        {
          "item_id": "gems-5000-item",
          "name": "5000 Gems",
          "reward_type": "currency",
          "payload": {"currency_id": "gems", "amount": 5000}
        }
      ]
    },
    {
      "user_id": "user-456",
      "rank": 2,
      "score": 12510,
      "items": [
        {
          "item_id": "gems-5000-item",
          "name": "5000 Gems",
          "reward_type": "currency",
          "payload": {"currency_id": "gems", "amount": 5000}
        }
      ]
    }
  ]
}

5. Rank-Specific Rewards

For different prizes at each rank position, use rank_items instead of item_ids:

{
  "name": "Top 3 Physical Prizes",
  "description": "Different devices for top 3 players",
  "tiers": [
    {
      "condition": {
        "type": "rank_range",
        "start": 1,
        "end": 3
      },
      "rank_items": {
        "1": ["macbook-item"],
        "2": ["iphone-item"],
        "3": ["samsung-item"]
      }
    }
  ]
}

Result:

  • Rank 1 → MacBook Pro
  • Rank 2 → iPhone 15 Pro
  • Rank 3 → Samsung Galaxy S24

6. Reward Config Condition Types

ConditionWorks WithExample
rank_rangeLeaderboardsTop 10 players get rewards
threshold_rangeStreaks, Scores7-14 day streaks get rewards
milestoneProgression, LevelsReaching level 20 triggers reward
customAny featureAdvanced JSON-based rules

Examples

Rank Range (Leaderboards)

{
  "type": "rank_range",
  "start": 1,
  "end": 10
}

Threshold Range (Streaks)

{
  "type": "threshold_range",
  "metric": "streak_days",
  "min": 7,
  "max": 14
}

Milestone (Exact Value)

{
  "type": "milestone",
  "metric": "streak_days",
  "value": 30
}

7. Managing Reward Configs

ActionEndpointMethod
List catalog/v1/rewards-catalog?tenant_id=${tenant_id}GET
Get reward/v1/rewards-catalog/{reward_id}?tenant_id=${tenant_id}GET
Create/v1/rewards-catalog?tenant_id=${tenant_id}POST
Update/v1/rewards-catalog/{reward_id}?tenant_id=${tenant_id}PUT
Delete/v1/rewards-catalog/{reward_id}?tenant_id=${tenant_id}DELETE

8. Best Practices

Create a Reward Item Library

Build a library of reusable reward items:

// Good: Reusable items
{"name": "100 Gems", "reward_type": "currency", ...}
{"name": "500 Gems", "reward_type": "currency", ...}
{"name": "1000 Gems", "reward_type": "currency", ...}
{"name": "Weekly Champion Badge", "reward_type": "badge", ...}

Then reference them in multiple configs and coupons.

Use Descriptive Names

{
  "name": "Q1 2025 Tournament - Top 10 Rewards",
  "description": "Prizes for Winter 2025 tournament top performers"
}

Test Before Production

  1. Create reward items and configs on staging
  2. Attach to test features (coupons, leaderboards)
  3. Verify webhook payloads match expectations
  4. Deploy to production

Monitor Fulfillment

Ensure your webhook endpoint:

  • Returns 200 OK quickly (< 5 seconds)
  • Handles duplicate deliveries (idempotent)
  • Logs all reward distributions for audit

9. Webhook Integration

Configure your tenant's webhook URL to receive reward distribution events:

Event TypeTriggered When
leaderboard.window_completedLeaderboard window ends
streak.milestone_reachedUser hits streak milestone
achievement.completedUser completes achievement
coupon.redeemedUser redeems coupon

All events include full reward item details for fulfillment.


Next Steps

On this page