Server event reference
Server-side PlayGenus events — purchases, subscriptions, progression, economy, player lifecycle, matchmaking, guilds, LiveOps, moderation — with full property schemas.
These events are recommended for the Server SDK. Send them from your backend
after the action has been verified and committed — that's the whole point
of sending them server-side. If your game has no backend, most of these can
be sent from the client instead; see
Choosing your SDK.
Send this after validating the receipt with Apple, Google, or Steam.
This is your revenue source of truth — treat it with respect.
| Property | Type | Required | Example |
|---|
transaction_id | string | Yes | "GPA.1234-5678-9012" |
product_id | string | Yes | "com.game.gems_500" |
product_name | string | No | "500 Gems Pack" |
price_usd | float | Yes | 4.99 |
currency_code | string | No | "USD" |
store | string | Yes | "apple", "google", "steam" |
receipt_valid | boolean | Yes | true |
is_first_purchase | boolean | No | true |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
transaction_id | string | Yes | "GPA.1234-5678-9012" |
product_id | string | Yes | "com.game.gems_500" |
refund_amount_usd | float | Yes | 4.99 |
refund_reason | string | No | "player_request", "fraud" |
| Property | Type | Required | Example |
|---|
subscription_id | string | Yes | "sub_abc123" |
plan_id | string | Yes | "vip_monthly" |
plan_name | string | No | "VIP Monthly" |
price_usd | float | Yes | 9.99 |
billing_period | string | Yes | "monthly", "yearly" |
| Property | Type | Required | Example |
|---|
subscription_id | string | Yes | "sub_abc123" |
plan_id | string | Yes | "vip_monthly" |
renewal_count | int | Yes | 3 |
price_usd | float | Yes | 9.99 |
| Property | Type | Required | Example |
|---|
subscription_id | string | Yes | "sub_abc123" |
plan_id | string | Yes | "vip_monthly" |
cancel_reason | string | No | "too_expensive", "not_using", "switching" |
remaining_days | int | No | 12 |
Scope: these three events are for discrete-levels games only. If
your progression model is match-based,
soft-progression, or open-world, your tracking plan uses genre-shaped
custom events instead.
Send when the player begins a level, stage, or any progression unit.
| Property | Type | Required | Example |
|---|
level_id | string | Yes | "world1_stage3_level12" |
level_name | string | No | "Candy Forest 12" |
level_index | int | No | 12 |
difficulty | string | No | "normal", "hard", "nightmare" |
attempt_number | int | No | 1 |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
level_id | string | Yes | "world1_stage3_level12" |
level_name | string | No | "Candy Forest 12" |
level_index | int | No | 12 |
score | int | No | 45200 |
stars | int | No | 3 (0–3) |
duration_seconds | int | No | 87 |
attempt_number | int | No | 2 |
items_used | string[] | No | ["hammer", "extra_moves"] |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
level_id | string | Yes | "world1_stage3_level12" |
level_name | string | No | "Candy Forest 12" |
level_index | int | No | 12 |
fail_reason | string | No | "out_of_moves", "time_expired", "died" |
progress_percent | float | No | 0.72 |
duration_seconds | int | No | 95 |
attempt_number | int | No | 1 |
player_id | string | Yes | "player-uuid" |
Send when the player receives virtual currency. Don't fire this on every
coin pickup — aggregate per level or action, or your event volume will make
everyone sad.
| Property | Type | Required | Example |
|---|
currency_type | string | Yes | "coins", "gems", "energy" |
amount | int | Yes | 150 |
balance_after | int | Yes | 2340 |
source | string | Yes | "level_reward", "daily_bonus", "purchase", "ad_reward", "gift" |
source_id | string | No | "world1_stage3_level12" |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
currency_type | string | Yes | "gems" |
amount | int | Yes | 50 |
balance_after | int | Yes | 200 |
sink | string | Yes | "item_purchase", "upgrade", "gacha_pull", "continue", "boost" |
sink_id | string | No | "booster_hammer" |
item_id | string | No | "hammer_01" |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
item_id | string | Yes | "sword_legendary_01" |
item_name | string | No | "Blade of Fire" |
item_type | string | Yes | "weapon", "armor", "consumable", "cosmetic" |
item_rarity | string | No | "common", "rare", "epic", "legendary" |
acquisition_method | string | Yes | "purchase", "craft", "drop", "reward" |
player_id | string | Yes | "player-uuid" |
| Property | Type | Required | Example |
|---|
item_id | string | Yes | "health_potion_01" |
item_name | string | No | "Health Potion" |
item_type | string | Yes | "consumable" |
context | string | No | "level", "menu", "pvp" |
context_id | string | No | "world1_stage3_level12" |
player_id | string | Yes | "player-uuid" |
Send when a new player account is registered.
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
registration_method | string | Yes | "email", "google", "apple", "guest" |
referral_source | string | No | "friend_invite", "ad_campaign" |
campaign_id | string | No | "ua_spring2026" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
login_method | string | Yes | "email", "google", "apple", "token" |
days_since_last_login | int | No | 3 |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
new_level | int | Yes | 15 |
previous_level | int | Yes | 14 |
total_playtime_seconds | int | No | 36000 |
Send when a player requests account deletion (GDPR).
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
account_age_days | int | No | 120 |
total_spend_usd | float | No | 24.97 |
Scope: these three events are for match-based games. They model the
matchmaking and post-match outcome envelope; the genre's progression events
(match won/lost, seasons, contracts, transfers) are seeded as
custom events.
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
game_mode | string | Yes | "ranked_1v1", "casual_3v3" |
player_rating | int | No | 1450 |
queue_region | string | No | "eu-west" |
| Property | Type | Required | Example |
|---|
match_id | string | Yes | "match-uuid" |
game_mode | string | Yes | "ranked_1v1" |
player_count | int | Yes | 2 |
avg_rating | int | No | 1420 |
rating_spread | int | No | 60 |
queue_duration_seconds | int | Yes | 12 |
| Property | Type | Required | Example |
|---|
match_id | string | Yes | "match-uuid" |
game_mode | string | Yes | "ranked_1v1" |
duration_seconds | int | Yes | 480 |
winner_id | string | No | "player-uuid" |
player_results | object[] | Yes | [{"player_id": "abc", "score": 1200, "placement": 1}] |
disconnect_count | int | No | 0 |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
guild_id | string | Yes | "guild-uuid" |
guild_size | int | No | 24 |
join_method | string | No | "invite", "search", "auto" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
guild_id | string | Yes | "guild-uuid" |
membership_duration_days | int | No | 45 |
leave_reason | string | No | "inactive", "kicked", "voluntary" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
friend_player_id | string | Yes | "friend-uuid" |
source | string | No | "in_game", "external", "suggested" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
recipient_player_id | string | Yes | "friend-uuid" |
gift_type | string | Yes | "life", "coins", "item" |
gift_value | int | No | 1 |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
event_id | string | Yes | "spring_event_2026" |
event_name | string | No | "Spring Blossom Festival" |
event_type | string | Yes | "seasonal", "tournament", "challenge" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
event_id | string | Yes | "spring_event_2026" |
milestone_id | string | Yes | "collect_100_flowers" |
milestone_index | int | No | 3 |
progress_percent | float | No | 0.60 |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
event_id | string | Yes | "spring_event_2026" |
completion_time_seconds | int | No | 259200 (3 days) |
rewards_earned | string[] | No | ["avatar_spring", "gems_500"] |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
day_number | int | Yes | 7 |
streak_count | int | Yes | 7 |
reward_type | string | Yes | "coins", "gems", "item" |
reward_amount | int | Yes | 100 |
| Property | Type | Required | Example |
|---|
reporter_player_id | string | Yes | "player-uuid" |
reported_player_id | string | Yes | "other-player-uuid" |
report_reason | string | Yes | "cheating", "harassment", "inappropriate_name" |
context | string | No | "in_match", "chat", "profile" |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
ban_type | string | Yes | "temporary", "permanent" |
ban_reason | string | Yes | "cheating", "harassment" |
ban_duration_days | int | No | 7 (null for permanent) |
| Property | Type | Required | Example |
|---|
player_id | string | Yes | "player-uuid" |
message_hash | string | Yes | "sha256-abc123..." |
flag_reason | string | Yes | "profanity", "spam", "hate_speech" |