Loot Boxes, Keys & APIs

Panel configuration, player inventory, purchase, open flow, and Unity integration

Loot Box API



API v1 endpoints for loot boxes, keys, purchase, and opening. All routes require game session auth (auth.api middleware) unless noted.

Panel guide: Loot Boxes & Keys (panel)
Developer API page: Loot Boxes & Keys API
Test script: php Example_lootbox_flow.php

Panel: creating loot boxes



  • 1. Loot Boxes (sidebar) โ€” name, slug, rarity, loot table, max items

  • 2. Requires key โ€” enable + select required key rarity

  • 3. Prices โ€” soft/hard coin cost for POST /user/loot-boxes/buy

  • 4. Simulate โ€” test rolls on the box detail page


  • Panel: creating keys (items)



    Keys are ItemVariants (consumables), not a separate table:

  • 1. Items Configuration โ†’ Item Type: Key (consumable, stackable)

  • 2. Item Definition: Loot Box Key โ€” must define schema field key_rarity

  • 3. Master Item: e.g. Common Key

  • 4. Item Variant (level 0) โ†’ section Item Properties โ†’ field Key rarity (dropdown)

  • - Stored in DB column item_variants.content as { "key_rarity": "common" }
    - Not unlock_features โ€” that JSON is unrelated
    - If you only see โ€œNo schema definedโ€, fix the Item Definition json_schema (see seeder/migration)
  • 5. Item Variant Price โ€” for shop / buy-item API


  • Run seeder: php artisan db:seed --class=LootBoxesAndKeysSeeder

    API: where key_rarity appears



    | Endpoint | Field |
    |----------|-------|
    | GET /user/inventory โ†’ inventory[] | content.key_rarity and top-level key_rarity (when item is a key) |
    | GET /user/inventory โ†’ consumables[] | Same fields per key (is_key: true) |
    | POST /user/loot-boxes/open response | key_consumed.key_rarity |
    | Shop / buy-item response | inventory[] updated with key fields above |

    IDs for Unity



    Each reward uses two separate fields (not a composite ID):

    | Field | Purpose |
    |-------|---------|
    | item_variant_id | Operative ID โ€” grant, equip, consume |
    | master_item_id | Base weapon/item โ€” map prefab / weapon family |

    Key compatibility



    | Box required_key_rarity | Valid keys |
    |---------------------------|------------|
    | common | Common Key |
    | rare | Rare Key |
    | epic | Epic Key |
    | legendary | Legendary Key |
    | unique | Unique Key (opens any locked box) |

    Keys are ItemVariant consumables with content.key_rarity.

    Endpoints



    GET /api/v1/loot-boxes



    Catalog of active loot boxes for the user's game.

    GET /api/v1/user/loot-boxes



    Loot boxes owned by the player (unopened stacks).

    GET /api/v1/user/keys



    Keys owned by the player only (no weapons/materials). Each entry includes key_rarity, quantity, item_variant_id, acquisition_method, etc.

    GET /api/v1/user/loot-box-inventory



    Recommended for Unity loot-box screen โ€” single call returning both:

    {
    "success": true,
    "loot_boxes": [ "...unopened boxes..." ],
    "keys": [ "...owned keys with key_rarity..." ]
    }


    GET /api/v1/user/inventory



    Full player inventory. Also includes loot_boxes[] and keys inside inventory[] / consumables[] (filter by is_key). Prefer the dedicated endpoints above for loot-box UI.

    POST /api/v1/user/loot-boxes/buy



    {
    "loot_box_id": 1,
    "quantity": 1,
    "currency": "soft_coins"
    }


    Deducts currency (uses box soft_coin_cost / hard_coin_cost) and adds boxes to player inventory.

    POST /api/v1/user/loot-boxes/add



    Grant boxes (rewards/events):

    {
    "loot_box_id": 1,
    "quantity": 1
    }


    POST /api/v1/user/loot-boxes/open



    Free box (no key):

    {
    "loot_box_id": 1,
    "times": 1
    }


    Locked box:

    {
    "loot_box_id": 2,
    "times": 1,
    "key_item_variant_id": 501
    }


    Success response (abbreviated):

    {
    "success": true,
    "loot_box_id": 2,
    "times_opened": 1,
    "key_consumed": {
    "item_variant_id": 501,
    "master_item_id": 40,
    "key_rarity": "common",
    "quantity": 1
    },
    "rewards": [
    {
    "item_variant_id": 140,
    "master_item_id": 39,
    "name": "AK-47",
    "rarity": "rare",
    "quantity": 1,
    "guaranteed": false
    }
    ],
    "remaining_boxes": 0,
    "loot_boxes": [],
    "inventory": []
    }


    Error codes



    | Code | HTTP | Meaning |
    |------|------|---------|
    | KEY_REQUIRED | 422 | Box needs a key |
    | KEY_NOT_REQUIRED | 422 | Key sent but box is free |
    | INVALID_KEY | 422 | Key item invalid |
    | INVALID_KEY_RARITY | 422 | Key rarity mismatch |
    | INSUFFICIENT_BOXES | 422 | Not enough boxes |
    | INSUFFICIENT_KEYS | 422 | Not enough keys |
    | INSUFFICIENT_FUNDS | 422 | Cannot afford purchase |
    | LOOT_BOX_INACTIVE | 400 | Box missing or inactive |

    Unity flow



  • 1. GET /user/inventory โ€” show boxes + keys

  • 2. POST /user/loot-boxes/buy โ€” purchase box (optional)

  • 3. POST /user/loot-boxes/open โ€” pass key_item_variant_id only when requires_key is true

  • 4. Map each reward: master_item_id โ†’ weapon prefab, item_variant_id โ†’ skin/variant


  • Seeder examples (game 3)



    Run php artisan db:seed --class=LootBoxesAndKeysSeeder after migrations.

  • Starter Crate (Free Open) โ€” no key, soft coins 100

  • Common/Rare/Epic/Legendary/Mythic locked boxes โ€” matching key rarity

  • 5 keys โ€” Common, Rare, Epic, Legendary, Unique