NAV
  • Introduction
  • Authentication
  • Player
  • Characters
  • Heroes
  • Leaderboards
  • Persistent Player Storage
  • Asset
  • Asset Instances
  • User Generated Content
  • Missions
  • Drop Tables
  • Maps
  • Purchasing
  • Trigger Events
  • Collectables
  • Messages
  • Crashes
  • Errors
  • Deprecations
  • Introduction

    Welcome to the LootLocker Game API Reference Documentation.

    We do our best to keep this documentation up to date, but if you find any issues, please reach out to us at hello@lootlocker.io, or swing by our Discord Server and talk to us directly.

    Authentication

    Player Verification

    curl -X POST "https://api.lootlocker.io/game/v1/player/verify" \
      -H "Content-Type: application/json" \
      -d "{\"key\": \"your_game_key\", \"platform\": \"steam\", \"token\": 123857128391}"
    

    If your game uses Player Verification, you need to call this endpoint before you can register a session.

    The function of this endpoint is to verify the player with the platform they're currently connecting from. Some platforms require the use of player verification. Please refer to the below table.

    A successful response:

    {
      "success": true
    }
    
    PlatformRequires Validation
    SteamOptional
    PlayStation NetworkYes
    RobloxYes
    iOSNot supported
    AndroidNot supported
    Amazon LunaNot supported

    After verifying the player, you should register a session within 5 minutes, or the token will expire, and you have to verify again.

    The token parameter is different depending on which platform it is.

    For Steam, you need to see the Auth documentation, under the headline Session Tickets and the Steamworks Web API, for information on how to obtain the token.

    For PlayStation Network you need to supply the same auth code as when performing a purchase. An example for obtaining this code can be found in the NPAuth sample provided by Sony.

    Roblox Verification

    curl -X POST "https://api.lootlocker.io/game/v1/player/verify" \
      -H "Content-Type: application/json" \
      -d "{\"key\": \"your_game_key\", \"platform\": \"roblox\", \"token\": roblox_player_id}"
    

    First response

    {
      "success": true,
      "challenge": "z2v5YkOWigKVi3v0B8Z8bJncQs56ZC0N0OuwJsf4"
    }
    

    Second / Future Verificaiton Requests

    curl -X POST "https://api.lootlocker.io/game/v1/player/verify" \
      -H "Content-Type: application/json" \
      -d "{\"key\": \"your_game_key\", \"platform\": \"roblox\", \"token\": roblox_player_id, \"roblox_user_challenge\": \"sha256_hashed_challenge\"}"
    

    For Roblox the token is the Roblox User ID. When using this platform, we require a challenge to be met by the client. On the first request, LootLocker returns a challenge for the Roblox client to save, and use for future verifications. As you see in the example, there is a field called roblox_user_challenge which is the challenge returned from LootLocker, sha256 hashed with the game api key. This is done by concatenating the two strings, with the challenge first (challenge+game_api_key), and no delimiter between them, then sha256 hashing the new string.

    The response to a successful Roblox verification is the same as any other verification.

    Authentication Request

    Registering a session:

    # Session registration example with Steam
    curl -X POST "https://api.lootlocker.io/game/v2/session" \
      -H "Content-Type: application/json" \
      -d "{\"game_key\": \"your_game_key\", \"platform\": \"steam\", \"player_identifier\": \"76561198023004363\",	\"game_version\": \"0.10.0.0\",	\"development_mode\": \"false\"}"
    

    A successful response looks like this:

      {
        "success": true,
        "session_token": "e6fa44946f077dd9fe67311ab3f188c596df9969",
        "player_id": 3,
        "public_uid": "TSEYDXD8",
        "check_grant_notifications": true,
        "check_deactivation_notifications": false,
        "seen_before": true
      }
    

    A successful response for a game using XP:

      {
        "success": true,
        "session_token": "e6fa44946f077dd9fe67311ab3f188c596df9969",
        "player_id": 3,
        "public_uid": "TSEYDXD8",
        "check_grant_notifications": true,
        "check_deactivation_notifications": false,
        "xp": 5,
        "level": 0,
        "seen_before": true
      }
    

    A successful response for a game using soft currency:

      {
        "success": true,
        "session_token": "e6fa44946f077dd9fe67311ab3f188c596df9969",
        "player_id": 3,
        "public_uid": "TSEYDXD8",
        "check_grant_notifications": true,
        "check_deactivation_notifications": false,
        "account_balance": 1856,
        "seen_before": true
      }
    

    A successful response for a game using constant DLC migrations:

      {
        "success": true,
        "session_token": "9178407f966bc58f79acbf96b030eaf43738ab84",
        "player_id": 12,
        "public_uid": "TSEYDXD8",
        "seen_before": true,
        "check_grant_notifications": true,
        "check_deactivation_notifications": true,
        "check_dlcs": [
          438800,
          438801,
          438802,
          439210
        ],
        "xp": 183188,
        "level": 44,
        "level_thresholds": {
          "current": 352300,
          "current_is_prestige": false,
          "next": 362300,
          "next_is_prestige": true
        },
        "account_balance": 97
      }
    

    The game API uses the API key for the initial request which registers a session.

    Four parameters are expected in this request, with three additional optional parameters.

    Required: player_identifier, game_key, game_version and platform.

    Optional: mac, session_id and development_mode

    player_identifier being the ID of the player on the platform the game is currently running on (steamId, PSN id, etc)

    game_key being your API key

    game_version being the current version of the game in the format 1.2.3.4 (the 3 and 4 being optional but recommended)

    mac (OPTIONAL) being the MAC address of the computer the user is currently playing on. This is used for submitting crash logs later and being able to connect it with a player.

    session_id (OPTIONAL) being a randomly generated string to identify this current session.

    development_mode (OPTIONAL) is a boolean flag you can set to true when you want to test your unpublished changes of assets, settings etc. See the Admin API documentation for more information.

    platform being the name of the platform the user is on, we currently support the following:

    PlatformParameter valueReference name
    Steamsteam64-bit SteamID
    Playstation NetworkpsnOnline ID
    RobloxrobloxRoblox user id
    iOSiosDevice ID
    AndroidandroidDevice ID
    Amazon LunalunaAmazon Luna GUID

    session_token is the token you need to make additional calls to LootLocker. To see how to send that along with further requests, see Sending Subsequent Requests.

    player_id is the players id in LootLocker. This can be used to integrate with third party tools such as Game Analytics and later generate reports on a per player basis.

    public_uid is a unique id for a player in your game, that can be used for searching for the player in the LootLocker Player Manager, or used by players to interact with other players, such as sending friend requests, or requesting UGC created by a specific player.

    The check_grant_notifications parameter is for cases where the registration of a session might have triggered asynchronously granting assets the the player. Eg. during DLC migration. If this value is true, you should issue a request for the player asset notification endpoint no earlier than 5 minutes after registering the session.

    The check_deactivation_notifications is for letting users know that one of their assets have been deactivated since they last logged in, and can't be used. See Player Asset Deactivation Notifications.

    If your game uses constant DLC migrations, you will get ID's back of the DLC's you should check with Steam to see if the player owns them. If you own any of them, issue a call to the Initiate DLC Migration endpoint.

    Ending A Session

    curl -X DELETE "https://api.lootlocker.io/game/v1/session" \
      -H "x-session-token: your_token_here"
    

    For each API request your game makes, LootLocker tracks how long time the player has been playing for. To make this information more accurate, we have a call to indicate that the session is ending.

    This endpoint will terminate the session on the LootLocker servers, and any further requests with this token will be rejected with an 401 Unauthroized error.

    Example resoponse

    {
      "success": true
    }
    

    Sending Subsequent Requests

    Sending along a session token in a POST request

    curl -X POST "https://api.lootlocker.io/game/v1/some_endpoint_here" \
      -d "other_parameter=other_value" \
      -H "x-session-token: your_token_here"
    

    For brevity this is not mentioned in the rest of the calls in the documentation.

    The session token is sent as a HTTP header, with the name x-session-token. If this is not sent with a request, an authentication error will be returned.

    Player

    Get Player Info

    curl -X GET "https://api.lootlocker.io/game/v1/player/info"
    

    This endpoint lets you get general information about the player, such as the XP, Level information and their account balance.

    If your game does not have currencies enabled, account_balance will be null.

    If your game does not have progression enabled, all other values will be null. level_thresholds will be null instead of an object.

    Example response

    {
        "success": true,
        "account_balance": 0,
        "xp": 0,
        "level": 0,
        "level_thresholds": {
            "current": 0,
            "current_is_prestige": false,
            "next": 1000,
            "next_is_prestige": true
        }
    }
    

    Get Player Name

    curl -X GET "https://api.lootlocker.io/game/player/name" \
        -H "LL-Version: 2021-03-01"
    

    This endpoint will return the name the player has set. If no name is set, an empty property will be returned.

    Example Response

    {
        "name": "Player Name"
    }
    

    Set Player Name

    curl -X PATCH "https://api.lootlocker.io/game/player/name" \
        -H "LL-Version: 2021-03-01" \
        -H "Content-Type: application/json" \
        -d "{\"name\": \"Player Name\"}"
    

    This endpoint will let the player set a name, and return that name on success.

    The max length of a name is 255 characters.

    Example Response

    {
        "name": "Player Name"
    }
    

    Get Inventory List

    curl -X GET "https://api.lootlocker.io/game/v1/player/inventory/list"
    

    See the Get Inventory Stream endpoint for explanations of the properties in the response objects.

    This call offers a paginated list of the players inventory. There are two URL parameters you can use to affect the offset of asset instances returned. after is the highest instance_id returned from the previous call, and it's used to fetch the next page. count is an optional parameter which is the max number of items returned. It defaults to 50, but can be set as high as 200. Anything above 200 will be ignored and the default value used instead.

    When using this endpoint, universal assets are not returned as part of the players inventory, and as such you also need to implement the Get Universal Assets endpoint. If you use the streaming inventory endpoint, this is not necessary as universal assets are returned.

    Example response object

    {
        "success": true,
        "inventory": [
            {
                "instance_id": 538,
                "variation_id": 45,
                "rental_option_id": null,
                "acquisition_source": "grant_default_loadout",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Get Inventory Stream

    curl -X GET "https://api.lootlocker.io/game/v1/player/inventory"
    

    Example response object

    {
        "instance_id": 538,
        "variation_id": 45,
        "rental_option_id": null,
        "acquisition_source": "grant_default_loadout",
        "asset": {...},
        "rental": {
            "is_rental": false,
            "time_left": null,
            "duration": null,
            "is_active": null
        }
    }
    

    This endpoint will return to you all the assets that the player currently owns, as a streaming response, similar to the assets call. The root object will however contain 2 properties, one being instance_id and the other being asset. The asset will be holding the asset object exactly the same way as any other asset - Referenced as "asset": {...} in the example.

    If a player owns multiple of the same asset, it will be there multiple times.

    If this endpoint is used instead of the (Get Inventory List)[#get-inventory-list] call, you do not need to implement the (Get Universal Assets)[#get-universal-assets] call as those assets are already returned in this response.

    Note the rental object. This contains information regarding rental assets. The is_rental property will let you know if the asset is a rental or not, if it isn't you can safely ignore the other parameters in the object. time_left and duration are denoted in seconds, and active lets you know if the rental has been activated and is thus currently active, or if it is waiting to be activated. Expired rentals are not returned. Beware that the time_left property can be negative if you request the inventory after the instance is expired, but it has not yet been expired by LootLocker.

    The acquisition_source property will let you know how a player got to own the current instance of the asset. See the below table for all the different ways players can acquire asset instances.

    SourceMeaning
    grant_default_loadoutThis was part of the games default loadout when the player got it
    grant_universal_assetThis was a universal asset that the player used, and thus got an instance of
    grant_dlcThis was granted by using the dlc migration functionality
    reward_eventThis was rewarded as a reward for getting a medal in an event
    reward_triggerThis was rewarded by the trigger functionality
    reward_level_upThis was rewarded because the player levelled up
    purchase_packageThis was part of a package the player purchased
    purchase_unitThis was a single asset the player purchased
    steam_commandThis was a command sent from steam, creating the asset
    rent_unitThis is a rented asset
    reward_collectableThis was rewarded through completing a collectable criteria
    grant_loot_boxThis asset was granted from opening a Loot Box

    Get Universal Assets

    curl -X GET "https://api.lootlocker.io/game/v1/player/inventory/universal"
    

    You only need to implement this endpoint if you use the (List inventory call)[#get-inventory-list]. If you have implemented the streaming inventory call, you can ignore this.

    This call offers a paginated list of the games universal assets. There are two URL parameters you can use to affect the offset of assets returned. after is the highest universal_id returned from the previous call, and it's used to fetch the next page. For the first call you can either set this parameter to 0 or skip it. count is an optional parameter which is the max number of items returned. It defaults to 50, but can be set as high as 200. Anything above 200 will be ignored and the default value used instead.

    Example response

    {
        "success": true,
        "global_assets": [
            {
                "universal_id": 323,
                "variation_id": null,
                "rental_option_id": null,
                "acquisition_source": "grant_universal_asset",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Get Currency Balance

    curl -X GET "https://api.lootlocker.io/game/v1/player/balance"
    

    This endpoint will return the amount of credits the current player have on their account.

    Example response

    {
        "success": true,
        "balance": 0
    }
    

    Submit XP

    curl -X POST "https://api.lootlocker.io/game/v1/player/xp" \
     -d "{\"points\": 100}" \
     -H "Content-Type: application/json"
    

    This endpoint will receive xp, and award it to the player. The response will hold information about the players current xp and level.

    Example response

    {
            "success": true,
            "xp": {
                    "previous": 0,
                    "current": 50
            },
            "levels": [
                    {
                            "level": 0,
                            "xp_threshold": 0
                    },
                    {
                            "level": 1,
                            "xp_threshold": 100
                    },
                    {
                            "level": 2,
                            "xp_threshold": 200
                    }
            ],
            "check_grant_notifications": false
    }
    

    The levels array in the response holds level information about the current level (the first object), and the at least the two next, for displaying progress on the client side. In case of a user skipping all the way from level 0 to level 3, you would see 3 additional levels returned in the response.

    Example response where assets have been granted

    {
            "success": true,
            "xp": {
                    "before": 0,
                    "current": 50
            },
            "levels": [
                    {
                            "level": 0,
                            "xp_threshold": 0
                    },
                    {
                            "level": 1,
                            "xp_threshold": 100
                    },
                    {
                            "level": 2,
                            "xp_threshold": 200
                    }
            ],
            "check_grant_notifications": true
    }
    

    The check_grant_notifications option means that the player has been granted assets with this score submission. In this case you should issue a request to the Player Asset Notifications call immediately, unlike the Session Registration call where you have to wait.

    Example error because the game does not use XP

    {
            "success": false,
            "error": "Game does not use XP"
    }
    

    Get Other Players XP And Level

    curl -X GET "https://api.lootlocker.io/game/v1/player/score/76561198023004363?platform=steam"
    

    Example response

    {
            "success": true,
            "xp": 57185,
            "level": 8
    }
    

    The platform parameter is optional. If you do not supply one, the backend is gonna default to the same one as the current player is on.

    If the player does not exists, you will get a faulty response with the error field set to "Unknown player".

    Player Asset Notifications

    curl -X GET "https://api.lootlocker.io/game/v1/player/notification/assets"
    

    Example response

    {
        "success": true,
        "objects": [
            {
                "instance_id": 5713,
                "variation_id": 28,
                "acquisition_source": "reward_level_up",
                "asset": {
                    "id": 16,
                    "name": "Founder Gloves",
                    "active": true,
                    "price": 0,
                    "sales_price": null,
                    "display_price": "0",
                    "shop_thumbnail": "CharacterAttachments/Item Thumbnails/Hands/poppermost/thumb_poppermost-founder.tif",
                    "context": "Arms",
                    "detachable": true,
                    "updated": "Fri, 20 Feb 2015 21:53:36 +0000",
                    "default_variation_id": 28,
                    "default_loadouts": {
                        "skier": true,
                        "snowboarder": false
                    },
                    "unique_instance": false,
                    "external_identifiers": {
                        "psn": {
                            "entitlement_id": "CRED01",
                            "service_label": 1
                        }
                    },
                    "description": "",
                    "variations": [
                        {
                            "id": 28,
                            "name": "poppermost-founder",
                            "properties": [
                                {
                                    "material_path": "CharacterAttachments/Hands/poppermost/poppermost-founder/poppermost-founder.mtl",
                                    "binding_path": "CharacterAttachments/hands/shared-meshes/gloves-a/gloves-a.skin",
                                    "bone_id": 12,
                                    "bone_overrides": {}
                                }
                            ]
                        }
                    ],
                    "filters": [
                        {
                            "value": "Poppermost",
                            "name": "Brand",
                            "url": null
                        },
                        {
                            "value": "13/14",
                            "name": "Season",
                            "url": null
                        }
                    ],
                    "package_contents": null,
                    "storage": [
                        {
                            "key": "dog",
                            "value": "yes"
                        }
                    ],
                    "files": [
                        "https://cdn.lootlocker.io/141/5f230b1e14614.txt"
                    ],
                    "data_entities": [
                        "Your games custom data for this asset"
                    ]
                }
            }
        ]
    }
    

    This endpoint can be called to get assets that have been granted (given to) the player since the last time this endpoint was called. The backend will automatically keep track of when it was last called and thus only return valid information. In case no assets has been granted, the array will be empty.

    For information on the acquisition_source parameter, see Get Inventory.

    Player Asset Deactivation Notifications

    curl -X GET "https://api.lootlocker.io/game/v1/player/notification/deactivations"
    

    This endpoint will return deactivations since the last time it's been checked. Do not expect both replacement_asset_id and reason to have values at the same time. They can have, but it is not required.

    Example response

    {
        "success": true,
        "objects": [
            {
                "deactivated_asset_id": 4,
                "replacement_asset_id": 5,
                "reason": "Here is a good reason for deactivating this asset."
            }
        ]
    }
    

    Initiate DLC Migration

    curl -X POST "https://api.lootlocker.io/game/v1/player/dlcs"
    

    This endpoint will initiate a DLC migration for the current player. 5 minutes after calling this endpoint you should issue a call to the Player Asset Notifications call, to get the results of the migration, if any.

    Example response

    {
        "success": true
    }
    

    Get DLCs Migrated

    curl -X GET "https://api.lootlocker.io/game/v1/player/dlcs"
    

    This endpoint will return a list of DLC's migrated for the player. The DLC identifiers returned will be the ones of the platform the DLC belongs to. The identifier will always be a string, even if the identifier is numeric.

    Example response

    {
        "success": true,
        "dlcs": [
            "257300",
            "257301",
            "257302",
            "433770"
        ]
    }
    

    Set Profile Private

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/profile/public"
    

    This endpoint will set the players profile to private. This means that their inventory will not be displayed publicly on Steam and other places.

    Example response

    {
        "success": true
    }
    

    Set Profile Public

    curl -X POST "https://api.lootlocker.io/game/v1/player/profile/public"
    

    This endpoint will set the players profile to public. This means that their inventory will be displayed publicly on Steam and other places.

    Example response

    {
        "success": true
    }
    

    Characters

    Create Character

    curl -X POST "https://api.lootlocker.io/game/v1/player/character" \
        -d "{\"character_type_id\": 1, \"is_default\": true, \"name\": \"Crazy Monday Chimp\"}" \
        -H "Content-Type: application/json"
    

    When creating a character there is only one required field: character_type_id. See List Character Types to get your games Character Types. The other parameters are optional and are the same as for the Update Character call.

    Example Response

    {
        "success": true,
        "loadouts": [
            {
                "character": {
                    "id": 6171,
                    "type": "Heavy Vehicle",
                    "name": "Crazy Monday Chimp",
                    "is_default": true
                },
                "loadout": [
                    {
                        "variation_id": 1294,
                        "instance_id": 170657,
                        "mounted_at": "2015-07-24T12:58:08+0000",
                        "asset": {...},
                        "rental": {
                            "is_rental": false,
                            "time_left": null,
                            "duration": null,
                            "is_active": null
                        }
                    }
                ]
            }
        ]
    }
    

    Update Character

    curl -X PUT "https://api.lootlocker.io/game/v1/player/character/6171" \
    -d "{\"is_default\": true, \"name\": \"Crazy Monday Chimp\"}"
    -H "Content-Type: application/json"
    

    This endpoint lets you set a character as default, and set the name of the character. None of the parameters are required.

    Since changing the default status of a character will also change other characters on the player, the response will be identical to that from the Character Loadouts api call.

    The only restraint on the name field is that it can be no longer than 255 characters.

    List Character Types

    curl -X GET "https://api.lootlocker.io/game/v1/player/character/types
    

    Call this endpoint to list the character types configured for your game.

    Example Response

    {
        "success": true,
        "character_types": [
            {
                "id": 1,
                "is_default": true,
                "name": "Heavy Vehicle"
            }
        ]
    }
    

    Character Loadouts

    curl -X GET "https://api.lootlocker.io/game/v1/player/character/loadout"
    

    This call will return all characters loadouts for a game, and have some additional information on the characters.

    Note the rental object. This contains information regarding rental assets. The is_rental property will let you know if the asset is a rental or not, if it isn't you can safely ignore the other parameters in the object. time_left and duration are denoted in seconds, and active lets you know if the rental has been activated and is thus currently active, or if it is waiting to be activated. Expired rentals are not returned. Beware that the time_left property can be negative if you request the inventory after the instance is expired, but it has not yet been expired by LootLocker.

    Successful request (truncated for brevity)

    {
        "success": true,
        "loadouts": [
            {
                "character": {
                    "id": 6171,
                    "type": "Heavy Vehicle",
                    "name": "Crazy Monday Chimp",
                    "is_default": true
                },
                "loadout": [
                    {
                        "variation_id": 1294,
                        "instance_id": 170657,
                        "mounted_at": "2015-07-24T12:58:08+0000",
                        "asset": {...},
                        "rental": {
                            "is_rental": false,
                            "time_left": null,
                            "duration": null,
                            "is_active": null
                        }
                    }
                ]
            }
        ]
    }
    

    Get Other Players Character Loadouts By Platform Identifier

    curl -X GET "https://api.lootlocker.io/game/v1/player/character/loadout/76561198023004363?platform=steam"
    

    This call will return all characters loadouts for a game, and have some additional information on the characters.

    The response from this endpoint will be identical to the one from the Character Loadouts api call.

    Equip Asset to Default Character

    curl -X POST "https://api.lootlocker.io/game/v1/player/equip" \
    -d "{\"instance_id\": 35}" \
    -H "Content-Type: application/json"
    

    Equipping an asset lets the backend know what the current loadout of a player is, which can then be reported back to other players, used for synchronising across multiple platform, be used to create a profile page, or.. You get the picture.

    The ID in this URL is the instance_id that will be returned from the inventory and loadout calls.

    When equipping an asset, you will get the full list of equipped assets back in the response (see Get current loadout). This should be treated as the universal truth, and the loadout in the game should reflect this.

    Equipping a global asset

    curl -X POST "https://api.lootlocker.io/game/v1/player/equip" \
    -d "{\"asset_id\": 35, \"asset_variation_id\": 66}" \
    -H "Content-Type: application/json"
    

    When you want to equip a global asset, it reqiures the asset_id and an asset_variation_id, which will then create an instance that will be returned just like when equipping with an instance_id.

    If you are using the global asset equip syntax on an asset that is not global, you will get a response with success set to false, and a suiting error message.

    Equip Asset to Character By Id

    curl -X POST "https://api.lootlocker.io/game/v1/player/character/12765/equip" \
    -d "{\"instance_id\": 35}" \
    -H "Content-Type: application/json"
    

    This endpoint allows you to equip an asset to a character by id.

    Just like you can equip a global asset to the default character, you can do the same for this endpoint.

    curl -X POST "https://api.lootlocker.io/game/v1/player/character/12765/equip" \
    -d "{\"asset_id\": 35, \"asset_variation_id\": 66}" \
    -H "Content-Type: application/json"
    

    Successful request (truncated for brevity)

    {
        "success": true,
        "character": {
            "id": 6171,
            "type": "Heavy Vehicle",
            "name": "Crazy Monday Monkey",
            "is_default": true
        },
        "loadout": [
            {
                "variation_id": 1271,
                "instance_id": 170658,
                "mounted_at": "2015-07-24T12:58:08+0000",
                "asset": {
                  "Asset": "information in same format as in the asset calls."
                }
            }
        ]
    }
    

    You can obtain the character id from the Characters Loadouts call.

    Unequip Asset to Default Character

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/equip/1"
    

    Non successful request because no such instance exists. Status code: 404

    {
      "success": false,
      "error": "No such instance"
    }
    

    Unequipping does the opposite of equipping. For the same reasons. The integer at the end is also the instance_id here.

    When un-equipping an asset, you will get the full list of equipped assets back in the response (see Get current loadout). This should be treated as the universal truth, and the loadout in the game should reflect this.

    Unequip Asset To Character By Id

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/character/6171/equip/170657"
    

    This endpoint lets you unequip assets from a character. The response will return the loadout for this character.

    Successful request (truncated for brevity)

    {
        "success": true,
        "character": {
            "id": 6171,
            "type": "Heavy Vehicle",
            "name": "Crazy Monday Monkey",
            "is_default": true
        },
        "loadout": [
            {
                "variation_id": 1271,
                "instance_id": 170658,
                "mounted_at": "2015-07-24T12:58:08+0000",
                "asset": {...}
            }
        ]
    }
    

    Get Current Loadout to Default Character

    curl -X GET "https://api.lootlocker.io/game/v1/player/loadout"
    

    A successful response will look similar to this

    {
      "success": true,
      "loadout": [
        {
          "variation_id": 2,
          "instance_id": 538,
          "mounted_at": "2014-07-25T11:53:17+0000",
          "asset": {...}
        },
        {
          "variation_id": 9,
          "instance_id": 217,
          "mounted_at": "2014-07-25T11:53:17+0000",
          "asset": {...}
        }
      ]
    }
    

    Getting the current loadout will return an array of assets that the user currently have equipped.

    The three fields returned in the call are:

    Field nameDescription
    item_idThe id of the instance of the asset. This is the unique version of the asset that the player owns
    mounted_atThe date of equippal in ISO8601 format
    assetThe asset information needed to represent the asset in-game

    Get Other Players Loadout to Default Character

    curl -X GET "https://api.lootlocker.io/game/v1/player/loadout/76561198023004363?platform=steam"
    

    This method will return the exact same response as the Get current loadout one, except that it will be for another player.

    The platform parameter is optional. If you do not supply one, the backend is gonna default to the same one as the current player is on.

    If the player does not exists, you will get a faulty response with the error field set to "Unknown player".

    Get Equippable Contexts to Default Character

    curl -X GET "https://api.lootlocker.io/game/v1/player/character/contexts"
    

    This endpoint returns the contexts that the players default character can equip. The response format is the same as Getting Contexts, but only includes the equippable contexts for the character.

    Get Equippable Contexts by Character ID

    curl -X GET "https://api.lootlocker.io/game/v1/player/character/1234/contexts"
    

    This endpoint returns the contexts that the requested player character can equip. The response format is the same as Getting Contexts, but only includes the equippable contexts for the character.

    Heroes

    In LootLocker, Heroes are an extension of Characters, which can have their own Default Loadouts, and have exceptions (either on an Asset or Context level) to what they can equip.

    Get Game Heroes

    curl -X GET "https://api.lootlocker.io/game/v1/heroes"
    

    The first thing you will want to do is list the Heroes configured for your game, to get the information needed to create your Hero. This endpoint will list the Heroes with names and character information.

    Example Response

    {
        "success": true,
        "heroes": [
            {
                "hero_id": 2,
                "character_type_id": 1234,
                "character_type_name": "Heavy",
                "name": "Rick Astley",
                "player_has_hero": false,
                "asset": {...}
            }
        ]
    }
    

    List Player Heroes

    curl -X GET "https://api.lootlocker.io/game/v1/player/heroes"
    

    This endpoint will return any Heroes the player owns.

    The id on the Hero property is the id of the instance of the Hero that the player owns, while the hero_id references the id of the Hero in your game. See how Get Game Heroes does not have an id property, but only a hero_id.

    Example Response

    {
        "success": true,
        "heroes": [
            {
                "id": 1,
                "hero_id": 2,
                "instance_id": 3,
                "hero_name": "Rick Astley",
                "character_name": "My First Hero",
                "class_name": "Heavy",
                "is_default": true,
                "asset": {...}
            }
        ]
    }
    

    The character_name property is the name that can be given to a Hero (and the underlaying Character) by a player. You can safely ignore this if you do not want to use it.

    The instance_id references an instance of the asset, that can be used like any other asset instance in LootLocker, for example, to store specific abilities or play time for a specific hero.

    List Other Players Heroes by SteamID64

    curl -X GET "https://api.lootlocker.io/game/v1/heroes/list/76000000000000000"
    

    This endpoint will return any Heroes the player with the related SteamID64 owns.

    The response form this endpoint is identical to listing heroes for the current players own Heroes. See List Player Heroes.

    Example Response

    {
        "success": true,
        "heroes": [
            {
                "id": 1,
                "hero_id": 2,
                "hero_name": "Rick Astley",
                "character_name": "My First Hero",
                "class_name": "Heavy",
                "is_default": true,
                "asset": {...}
            }
        ]
    }
    

    Creating a Hero

    curl -X POST "https://api.lootlocker.io/game/v1/player/heroes" \
        -d "{\"hero_id\": 2, \"name\": \"My First Hero\"}"
    

    When creating a player owned hero, you need to supply the id of the game's hero, and can optionally supply a player set name. In the example we've named a "Rick Astley" Hero "My First Hero".

    Example Response

    {
        "success": true,
        "hero": {
            "id": 1,
            "hero_id": 2,
            "instance_id": 3,
            "hero_name": "Rick Astley",
            "character_name": "My First Hero",
            "class_name": "Heavy",
            "is_default": true,
            "asset": {...}
        }
    }
    

    Getting a Hero

    curl -X GET "https://api.lootlocker.io/game/v1/player/heroes/1"
    

    Calling this endpoint will return the information about a players hero.

    Example Response

    {
        "success": true,
        "hero": {
            "id": 1,
            "hero_id": 2,
            "instance_id": 3,
            "hero_name": "Rick Astley",
            "character_name": "My First Hero",
            "class_name": "Heavy",
            "is_default": true,
            "asset": {...}
        }
    }
    

    Get Other Players Default Hero By SteamID64

    curl -X GET "https://api.lootlocker.io/game/v1/heroes/default/76000000000000000
    

    Use this endpoint to obtain the default hero for another player. This can be used when presenting heroes in a lobby before starting a game session etc.

    The response is identical to the one of the Getting a Hero endpoint.

    Example Response

    {
        "success": true,
        "hero": {
            "id": 1,
            "hero_id": 2,
            "hero_name": "Rick Astley",
            "character_name": "My First Hero",
            "class_name": "Heavy",
            "is_default": true,
            "asset": {...}
        }
    }
    

    Updating a Hero

    curl -X PUT "https://api.lootlocker.io/game/v1/player/heroes/1"
        -d "{\"name\": \"Renamed Hero\", \"is_default\": false}"
    

    Updating a hero allows you to change the player supplied name of the hero, and setting the default hero for the current player. Setting the default hero to true for one hero will automatically remove it from any other default hero the player might have.

    Example Response

    {
        "success": true,
        "hero": {
            "id": 1,
            "hero_id": 2,
            "instance_id": 3,
            "hero_name": "Rick Astley",
            "character_name": "Renamed Hero",
            "class_name": "Heavy",
            "is_default": false,
            "asset": {...}
        }
    }
    

    Deleting a Hero

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/heroes/1"
    

    Deleting a hero will remove it from the players list of heroes. This action is currently unreversible, so you should make sure the player meant to perform the action.

    When deleting a hero, the heroes inventory is returned to the player, and their loadout is reset.

    Example Response

    {"success": true}
    

    Get Hero Inventory

    curl -X GET "https://api.lootlocker.io/game/v1/player/heroes/1/inventory"
    

    This endpoint allows you to list asset instances owned by a hero. This is very similar to the player inventory, except that it just returns what is in a heroes inventory.

    Note that this endpoint is paginated, and defaults to returning 50 entries. Using the count URL parameter you can set that up to 200.

    To retrieve the next page, supply the after URL parameter, with the value of the highest instance_id from your last call.

    Example Response

    {
        "success": true,
        "inventory": [
            {
                "instance_id": 1,
                "variation_id": 1,
                "rental_option_id": null,
                "acquisition_source": "grant_default_loadout",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Get Hero Loadout

    curl -X GET "https://api.lootlocker.io/game/v1/player/heroes/1/loadout"
    

    To list a heros loadout, that is what is currently equipped in the hero, call this endpoint. This same data can also be obtained by getting the character that this hero inherits froms inventory using the Character Loadouts endpoint.

    Example Response

    {
        "success": true,
        "loadout": [
            {
                "variation_id": 2,
                "instance_id": 538,
                "mounted_at": "2014-07-25T11:53:17+0000",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Get Other Players Hero Loadout

    curl -X GET "https://api.lootlocker.io/game/v1/heroes/1/loadout"
    

    When listing another player owned heros loadout, you will need to supply the Hero ID in the URL, in this example 1. This ID can be obtained using the Get Other Players Default Hero By SteamID64 endpoint.

    Example Response

    {
        "success": true,
        "loadout": [
            {
                "variation_id": 2,
                "instance_id": 538,
                "mounted_at": "2014-07-25T11:53:17+0000",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Add Asset to Hero Loadout

    curl -X POST "https://api.lootlocker.io/game/v1/player/heroes/1/loadout"
    

    To equip an asset instance, or a global asset, to a heros loadout, you can call this endpoint. This endpoint works exactly like the Characters Equip endpoints, but lets you do the same operations on a hero directly instead of having to look up the character.

    Example Response

    {
        "success": true,
        "loadout": [
            {
                "variation_id": 2,
                "instance_id": 538,
                "mounted_at": "2014-07-25T11:53:17+0000",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Remove Asset From Hero Loadout

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/heroes/3/loadout/537"
    

    To unequip or remove an asset instance, or a global asset, from a heros loadout, you can call this endpoint. This endpoint works exactly like the Characters Unequip endpoints, but lets you do the same operations on a hero directly instead of having to look up the character.

    In the example request, we unequip an asset with the instance_id of 537.

    If you have automatic removal of global assets enabled, there will be an extra property on the root of the response, called removed_asset (boolean), letting you know if the asset was removed from the player or not.

    Example Response

    {
        "success": true,
        "loadout": [
            {
                "variation_id": 2,
                "instance_id": 538,
                "mounted_at": "2014-07-25T11:53:17+0000",
                "asset": {...},
                "rental": {
                    "is_rental": false,
                    "time_left": null,
                    "duration": null,
                    "is_active": null
                }
            }
        ]
    }
    

    Leaderboards

    In the context of the game API leaderboards can be used to view and submit scores for members. To read more about leaderboards in general you can read our Leaderboard Product Documentation.

    An entry on a leaderboard is called a member. Since it's possible to have leaderboards for all kinds of cases it doesn't make sense to use players here. Becuase of that member_id can be whatever you want as long as it makes sense in your game. For lots of cases using the players ID will make good sense, but you can imagine a case where you would rank different clans/guilds against eachother for example. In that case you would use clan/guild ID as member_id.

    When using a leaderboard ID in any url it's possible to replace this with the key set on the leaderboard instead.

    Leaderboard Types

    Generic leaderboards

    Use this if you want do not want the extended player details from the player type leaderboard. This type allows you to create leaderboards not meant for players (guild/clan for example), or if your player data is not stored in LootLocker.

    Player leaderboards

    Meant for LootLocker players leaderboards. When submitting scores, you can omit the member_id as the currently authenticated player will always be used by default.When retrieving data LootLocker will automatically attach player data such as name.

    Get Member Rank

    Get rank for single member for a leaderboard. If leaderboard is of type player a player will also be in the response.

    curl -X GET "https://api.lootlocker.io/game/leaderboards/1/member/1"
    

    Example Response

    {
      "member_id": "1",
      "rank": 3,
      "score": 3004,
      "player": {
        "id": 1,
        "public_uid": "TSEYDXD8",
        "name": "Player Name"
      }
    }
    

    URL Structure

    /game/leaderboards/<leaderboard_id|leaderboard_key>/member/<member_id>

    URL Parts

    PartDescription
    leaderboard_idID of the leaderboard
    leaderboard_keykey of the leaderboard
    member_idplayer_id if player type leaderboard, otherwise id used when submitting the score

    Get By List of Members

    Get ranks for list of members for a leaderboard. This can be helpful when getting a players friends on leaderboard. If leaderboard is of type player a player will also be in the response.

    curl -X POST "https://api.lootlocker.io/game/leaderboards/1/members" \
    -d "{\"members\": [\"1\", \"2\"]}" \
    -H "Content-Type: application/json"
    

    Example Response

    {
      "members": [
        {
          "member_id": "1",
          "rank": 1,
          "score": 10000,
          "player": {
            "id": 1,
            "public_uid": "TSEYDXD8",
            "name": "Player Name"
          }
        },
        {
          "member_id": "2",
          "rank": 10,
          "score": 5000,
          "player": {...}
        }
      ]
    }
    

    Get Score List

    curl -X GET "https://api.lootlocker.io/game/leaderboards/1/list?count=10"
    

    Example Response

    {
      "pagination": {
        "total": 10132,
        "next_cursor": 3,
        "previous_cursor": null
      },
      "items": [
        {
          "member_id": "test_id",
          "rank": 1,
          "score": 10000,
          "player": {
            "id": 123,
            "public_uid": "TSEYDXD8",
            "name": "Player Name"
          }
        },
        {
          "member_id": "test_id2",
          "rank": 2,
          "score": 9999,
          "player": {...}
        },
        {
          "member_id": "test_id3",
          "rank": 3,
          "score": 7500,
          "player": {...}
        }
      ]
    }
    

    Get list of members in rank range. Result is sorted by rank ascending. Maximum allowed members to query for at a time is currently 2000. If leaderboard is of type player a player will also be in the response.

    URL Structure

    /game/leaderboards/<leaderboard_id|leaderboard_key>/list?count=10&after=0

    URL Parts

    PartDescription
    leaderboard_idID of the leaderboard
    leaderboard_keykey of the leaderboard

    Query Parameters

    FieldDescription
    afterCurser for pagination, a cursor will be returned in the response
    countNumber of members returned per page

    Submit Score

    curl -X POST "https://api.lootlocker.io/game/leaderboards/1/submit" \
    -d "{\"score\": 1000}" \
    -H "Content-Type: application/json"
    

    Example Response

    {
      "member_id": "2",
      "rank": 4,
      "score": 1000
    }
    

    URL Structure

    /game/leaderboards/<leaderboard_id|leaderboard_key>/submit

    URL Parts

    PartDescription
    leaderboard_idID of the leaderboard
    leaderboard_keykey of the leaderboard

    Available input fields

    All fields are optional.

    FieldDescription
    member_idoptional player_id if player type leaderboard, otherwise id used when submitting the score
    scoreThe score for the entry

    Submit scores for member on leaderboard. The member_id in the Game API is automatically filled with the currently authenticated players id.

    Persistent Player Storage

    Get Entire Persistent Storage

    curl -X GET "https://api.lootlocker.io/game/v1/player/storage"
    

    Sample success response

    {
        "success": true,
        "payload": [
            {
                "key": "user.answer",
                "value": "42",
                "is_public": false
            }
        ]
    }
    

    The persistent storage lets you save key/value pairs for each player for, syncing settings on different computers or other needs.

    This call returns all key/value pairs on record for this player, and can thus be slow if you create many.

    Get a Single Key From Persistent Storage

    curl -X GET "https://api.lootlocker.io/game/v1/player/storage?key=user.something"
    

    Sample success response

    {
        "success": true,
        "payload": {
            "key": "user.answer",
            "value": "42",
            "is_public": false
        }
    }
    

    Very much like the above, except this call only returns one key/value set.

    Updating / Creating Key/Value Pairs

    curl -X POST "https://api.lootlocker.io/game/v1/player/storage" \
        -d "[{\"key\":\"totalDeaths\",\"value\":\"124\", \"is_public\": true, \"order\":1},{\"key\":\"animal\", \"value\": \"Sheep\", \"order\":2}]"
        -H "Content-Type: application/json"
    

    The response from this request will be that of Get Entire Persistent Storage.

    For the key, the following rules apply:

    RuleRestriction
    Max length60 characters

    For the value, the following rules apply:

    RuleRestriction
    Max length260 characters

    Note that you can mark a key/value pair as public by including a boolean in the object, named is_public set to true. If you do not want the key/value pair to be public, either send it with the value set to false or omit the key.

    For the order you must supply an incrementing integer for each pair. This integer does not have to be continuously increasing, 12, 34, 71 is a perfectly valid sequence.

    Deleting a Key/Value Pair

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/storage?key=fruit"
    

    When successfully deleting a key/value pair, you will get a response that equals that from Get Entire Persistent Storage. If an error occurs, you will get a 500 Internal Error response, and you should simply try again (for a limited number of times).

    Getting Other Players Public Key/Value Pairs

    Get by Player ID

    curl -X GET "https://api.lootlocker.io/game/v1/player/1234/storage"
    

    Get by Player Public UID

    curl -X GET "https://api.lootlocker.io/game/v1/player/A1B2C3D4/storage"
    

    When you need to read another players public key/value storage, you can either use the players id or their public UID.

    The response will have the same format as any other player storage API call.

    Sample success response

    {
        "success": true,
        "payload": [
            {
                "key": "user.answer",
                "value": "42",
                "is_public": true
            }
        ]
    }
    

    Asset

    Getting Contexts

    curl -X GET "https://api.lootlocker.io/game/v1/contexts"
    

    This endpoint will return all the contexts the game has. This includes if a context is locked by an asset or not, for easy handling game side.

    Example Response

    
    {
      "success": true,
      "contexts": [
        {
          "id": 3,
          "name": "Credits",
          "friendly_name": null,
          "detachable": false,
          "user_facing": false,
          "dependent_asset_id": null
        },
        {
          "id": 4,
          "name": "Arms",
          "friendly_name": "Hands",
          "detachable": false,
          "user_facing": true,
          "dependent_asset_id": null
        },
        {
          "id": 5,
          "name": "Bindings",
          "friendly_name": null,
          "detachable": false,
          "user_facing": true,
          "dependent_asset_id": null
        },
        {
          "id": 6,
          "name": "Goggles",
          "friendly_name": "Eyes",
          "detachable": true,
          "user_facing": true,
          "dependent_asset_id": null
        }
      ]
    }
    

    Getting Asset List

    First call

    curl -X GET "https://api.lootlocker.io/game/v1/assets/list?count=10&filter=purchasable"
    

    This call is a non-streamed version of the Getting All Assets. It will require multiple calls to LootLocker with a parameter for every call except the first to step forward in the results.

    Up to 200 (the default limit is 50 though) assets are returned at a time, and to fetch the next page you have to use the largest ID you've gotten returned in the previous response, in the parameter ?after in the URL. Once you get no assets returned you have gotten them all.

    You can set a custom limit, up to 200 items that will be returned, using the query variable count=200. If a non-numeric value is supplied or it's bigger than 200, it will be ignored and a default limit of 50 will be applied.

    Next call

    curl -X GET "https://api.lootlocker.io/game/v1/assets/list?after=1927&count=10&filter=purchasable
    

    This endpoint also supports filtering assets, using a ?filter URL parameter. Currently the following filters exist:

    Filter valueEffect
    purchasableOnly return purchasable assets
    !purchasableOnly return non-purchasable assets
    rentableOnly return rentable assets
    !rentableOnly return non-rentable assets
    popularOnly return popular assets
    !popularOnly return non-popular assets

    Filters can also be combined by seperating them with a comma. To only get purchasable and popular assets, use the following: purchasable,popular.

    If you want to only get assets from a specific context, you can pass along a context_id property with the ID of the context you want to get assets from. Eg. ?after=1927&context_id=192

    The objects returned in the array, are the same as returned and documented in the Getting All Assets call. Please reference the text there for detailed information about the properties.

    Example Response

    {
        "success": true,
        "assets": [
            {
                "id": 1928,
                "name": "Jester Pro",
                "active": true,
                "purchasable": false,
                "price": 259,
                "sales_price": null,
                "display_price": "259",
                "context": "Bindings",
                "character_classes": [1,2,3],
                "unlocks_context": null,
                "detachable": false,
                "updated": "Sun, 07 Jan 2018 08:35:34 +0000",
                "marked_new": null,
                "default_variation_id": 2579,
                "default_loadouts": {
                    "skier": false,
                    "snowboarder": false
                },
                "description": "",
                "links": {
                    "thumbnail": "CharacterAttachments/Item Thumbnails/bindings/marker/thumb_marker-14-jesterpro.tif"
                },
                "storage": [
                    {
                        "key": "a key",
                        "value": "the value"
                    }
                ],
                "rarity": {
                    "name": "Legend",
                    "short_name": "",
                    "color": "BA8BFD"
                },
                "popular": false,
                "popularity_score": 0,
                "package_contents": null,
                "unique_instance": false,
                "external_identifiers": null,
                "rental_options": null,
                "filters": [
                    {
                        "value": "Marker",
                        "name": "Brand"
                    },
                    {
                        "value": "14/15",
                        "name": "Season"
                    }
                ],
                "variations": [
                    {
                        "id": 2579,
                        "name": "marker-14-jesterpro",
                        "primary_color": "98372B",
                        "secondary_color": "AE2C1C",
                        "links": {
                            "thumbnail": "CharacterAttachments/Item Thumbnails/bindings/marker/thumb_marker-14-jesterpro.tif"
                        },
                        "properties": [
                            {
                                "material_path": "CharacterAttachments/Bindings/Marker/marker-14-jesterpro/marker-14-jesterpro.mtl",
                                "binding_path": "CharacterAttachments/bindings/marker/marker-13-jester18pro/marker-13-jester18pro.cgf",
                                "bone_id": 75,
                                "bone_overrides": {}
                            },
                            {
                                "material_path": "CharacterAttachments/Bindings/Marker/marker-14-jesterpro/marker-14-jesterpro.mtl",
                                "binding_path": "CharacterAttachments/bindings/marker/marker-13-jester18pro/marker-13-jester18pro.cgf",
                                "bone_id": 74,
                                "bone_overrides": {}
                            }
                        ]
                    }
                ],
                "featured": false,
                "context_locked": false,
                "initially_purchasable": false,
                "files": [
                    {
                        "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
                        "tags": [
                            "never",
                            "gonna",
                            "give",
                            "you",
                            "up"]
                    }
                ],
                "data_entities": [
                    "Your games custom",
                    "data for this asset"
                ],
                "asset_candidate": {
                    "created_by_player_id": 1234,
                    "created_by_player_uid": "A1B2C3D4"
                },
                "drop_table_max_picks": null
            }
        ]
    }
    

    If your game has UGC enabled, you can send a GET style url parameter along to have UGC Assets returned: ?include_ugc=true.

    If you only want a subset of the assets your game owns, you can use the filters to include only the ones you want, by adding a GET style parameter to the url like so: ?asset_filters=key1=value1;key2=value2 etc. Any filters supplied need to be present on all assets for them to be returned. A maximum of 5 filters can be applied, any additional filters will be ignored.

    Getting Assets By IDs

    curl -X GET "https://api.lootlocker.io/game/v1/assets/by/id?asset_ids=1,2,3,4"
    

    This endpoint lets you retrieve only specific Assets by their ID's. The response is identical to the one from Getting Asset List.

    Getting All Assets

    Get all

    curl -X GET "https://api.lootlocker.io/game/v1/assets"
    

    Get since a date

    curl -X GET "https://api.lootlocker.io/game/v1/assets?since=2014-10-15 19:11:53"
    

    Example of the first object you will receive

    {"success":true}
    

    Example of the asset objects you will receive

    {
        "id": 4,
        "name": "Sven",
        "active": true,
        "price": 0,
        "sales_price": null,
        "display_price": "0",
        "shop_thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif",
        "context": "Arms",
        "character_classes": [1,2,3],
        "detachable": true,
        "purchasable": true,
        "initially_purchasable": true,
        "updated": "Wed, 04 Feb 2015 15:17:00 +0000",
        "marked_new": "Tue, 20 Oct 2015 21:53:45 +0000",
        "default_variation_id": 3,
        "default_loadouts": {
            "skier": true,
            "snowboarder": false
        },
        "description": "Asset description",
        "featured": false,
        "context_locked": false,
        "unlocks_context": null,
        "rarity": {
          "name": "Legendary",
          "short_name": "L",
          "color": "336699"
        },
        "popular": true,
        "popularity_score": 11618,
        "unique_instance": false,
        "external_identifiers": {
            "psn": {
                "entitlement_id": "CRED01",
                "service_label": 1
            },
            "apple_app_store": {
                "product_id": "CRED01"
            },
            "google_play": {
                "product_id": "CRED01"
            }
        },
        "variations": [
            {
                "id": 3,
                "name": "lo2-gloves-13-sven",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": {
    
                        }
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 4,
                "name": "lo2-gloves-13-sven_white",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven_white.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": {
    
                        }
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 5,
                "name": "lo2-gloves-13-sven_green",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven_green.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": {
    
                        }
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            }
        ],
        "filters": [
            {
                "value": "lo2",
                "name": "Brand"
            },
            {
                "value": "13\/14",
                "name": "Season"
            }
        ],
        "rental_options": [
            {
                "id": 1,
                "name": "3 Day Ski Pass",
                "duration": 259200,
                "price": 49,
                "sales_price": null,
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven-rental-3-days.tif"
                }
            }
        ],
        "files": [
            {
                "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
                "tags": [
                    "never",
                    "gonna",
                    "give",
                    "you",
                    "up"]
            }
        ],
        "data_entities": [
            "Your games custom data for this asset"
        ],
        "asset_candidate": {
            "created_by_player_id": 1234,
            "created_by_player_uid": "A1B2C3D4"
        },
        "drop_table_max_picks": null
    }
    

    The end of the request is marked by a small object indicating how many assets were sent

    {"streamedObjectCount":7}
    

    This call is a little special as it will stream you multiple JSON objects, which you will need to be able to handle on your end.

    The first JSON object you will receive is a success status.

    After that object you will start receiving the asset objects. See example object to the right. These objects will be valid JSON in their own entities, and they will arrive one at a time. You should parse and handle them as they come in.

    The end of the request is marked by JSON object with just one key; streamedObjectCount. This will hold an integer of how many assets were sent. Once this is received you can safely close the connection.

    The price and sales_price fields is for displaying a price in the store. If the asset is currently discounted, the sales_price will be set to a non-null value, and you should display that instead of the price field. You can use the difference between the two prices to calculate percentage or discount amount if you wish to do so. display_price is a formatted value sent by the backend, as a string. For virtual currencies it will hold just a number, but for real world currencies it will show the correct price in local currency (Only Play Station currently. Steam will just show the USD price set on the backend). This is useful when listing credits for sale, or if your game does not use virtual currencies.

    The type field references types you can arbitrarily set in the management interface. These are to help you differentiate between what different kinds of assets you might have, such as "clothing", "currency", "equipment" etc.

    The featured field lets you know if this asset is featured or not. Do with that information what you want. If the asset is an asset for sale, take the player to the store. If it's an event that everyone can participate in, take them to it etc.

    The marked_new field lets you annotate your assets with a new badge or similar. This date is in the format RFC-2822, but it can also contain a null value in case it's never been set.

    The detachable field lets you know if this is an asset that can be detached, such that the player can choose to not use it in their loadout. If an asset if is a type that does not have a context, the detachable flag will be null.

    The context_locked field lets you know if this asset is currently locked because the player does not own the necessary asset to grant access to it's context.

    The unlocks_context field is a string with the name of the context that it unlocks. If the asset does not unlock any context, the value will be null.

    To handle rental, have a look at rental_options, which specifies the price for rental tiers, a name for each of them and so forth. The duration field is the duration of the rental in seconds.

    Under each binding you will see a bone_id, which refers to bones returned from the asset bone call. If there are any deviations from a standard bone, it will be sent along with the binding information. See the example.

    You will also see filters if any are defined in the backend. In this example there is one called Brand and one called Season. Do with these what you please.

    Under the storage property you will see the keys and values set in the LootLocker Management Console.

    The character_classes property contains a list of the ID's of the character classes that can equip this asset.

    Example of the asset object with bone variations

    {
        "id": 4,
        "name": "Sven",
        "active": true,
        "price": 0,
        "sales_price": null,
        "display_price": "0",
        "shop_thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif",
        "context": "Arms",
        "character_classes": [1,2,3],
        "detachable": true,
        "updated": "Wed, 04 Feb 2015 15:17:00 +0000",
        "marked_new": "Tue, 20 Oct 2015 21:53:45 +0000",
        "default_variation_id": 3,
        "default_loadouts": {
            "skier": true,
            "snowboarder": false
        },
        "description": "",
        "featured": false,
        "rarity": {
          "name": "Legendary",
          "short_name": "L",
          "color": "336699"
        },
        "popular": true,
        "popularity_score": 11618,
        "unique_instance": false,
        "external_identifiers": {
            "psn": {
                "entitlement_id": "CRED01",
                "service_label": 1
            },
            "apple_app_store": {
                "product_id": "CRED01"
            },
            "google_play": {
                "product_id": "CRED01"
            }
        },
        "variations": [
            {
                "id": 3,
                "name": "lo2-gloves-13-sven",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": [
                            {
                                "name": "Position",
                                "value": "0,0.24771199,0.8292712"
                            }
                        ]
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 4,
                "name": "lo2-gloves-13-sven_white",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven_white.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": [
                            {
                                "name": "Position",
                                "value": "0,0.24771199,0.8292712"
                            }
                        ]
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 5,
                "name": "lo2-gloves-13-sven_green",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments\/hands\/lo2\/lo2-gloves-13-sven\/lo2-gloves-13-sven_green.mtl",
                        "binding_path": "CharacterAttachments\/hands\/shared-meshes\/gloves-a\/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": {
    
                        }
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            }
        ],
        "filters": [
            {
                "value": "lo2",
                "name": "Brand",
            },
            {
                "value": "13\/14",
                "name": "Season",
            }
        ],
        "rental_options": [
            {
                "id": 1,
                "name": "3 Day Ski Pass",
                "duration": 259200,
                "price": 49,
                "sales_price": null,
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven-rental-3-days.tif"
                }
            }
        ],
        "storage": [
            {
                "key": "dog",
                "value": "yes"
            }
        ],
        "files": [
            {
                "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
                "tags": [
                    "never",
                    "gonna",
                    "give",
                    "you",
                    "up"]
            }
        ],
        "data_entities": [
            "Your games custom data for this asset"
        ],
        "asset_candidate": {
            "created_by_player_id": 1234,
            "created_by_player_uid": "A1B2C3D4"
        },
        "drop_table_max_picks": null
    }
    {
        "id": 1,
        "name": "Sven",
        "active": true,
        "price": 0,
        "sales_price": null,
        "display_price": "0",
        "shop_thumbnail": "CharacterAttachments/Item Thumbnails/hands/lo2/thumb_lo2-gloves-13-sven.tif",
        "context": "Arms",
        "character_classes": [1,2,3],
        "detachable": true,
        "updated": "Tue, 13 Jan 2015 14:14:28 +0000",
        "marked_new": "Tue, 20 Oct 2015 21:53:45 +0000",
        "default_variation_id": 1,
        "default_loadouts": {
            "skier": true,
            "snowboarder": false
        },
        "description": "",
        "popularity_score": 11618,
        "unique_instance": false,
        "external_identifiers": {
            "psn": {
                "entitlement_id": "CRED01",
                "service_label": 1
            },
            "apple_app_store": {
                "product_id": "CRED01"
            },
            "google_play": {
                "product_id": "CRED01"
            }
        },
        "variations": [
            {
                "id": 1,
                "name": "lo2-gloves-13-sven",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments/hands/lo2/lo2-gloves-13-sven/lo2-gloves-13-sven.mtl",
                        "binding_path": "CharacterAttachments/hands/shared-meshes/gloves-a/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": [
                            {
                                "name": "Position",
                                "value": "0,0.24771199,0.8292712"
                            }
                        ]
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 2,
                "name": "lo2-gloves-13-sven_white",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments/hands/lo2/lo2-gloves-13-sven/lo2-gloves-13-sven_white.mtl",
                        "binding_path": "CharacterAttachments/hands/shared-meshes/gloves-a/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": [
                            {
                                "name": "Position",
                                "value": "0,0.24771199,0.8292712"
                            }
                        ]
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            },
            {
                "id": 3,
                "name": "lo2-gloves-13-sven_green",
                "primary_color": "FFFFFF",
                "secondary_color": null,
                "properties": [
                    {
                        "material_path": "CharacterAttachments/hands/lo2/lo2-gloves-13-sven/lo2-gloves-13-sven_green.mtl",
                        "binding_path": "CharacterAttachments/hands/shared-meshes/gloves-a/gloves-a.skin",
                        "bone_id": 12,
                        "bone_overrides": {}
                    }
                ],
                "links": {
                    "thumbnail": "CharacterAttachments\/Item Thumbnails\/hands\/lo2\/thumb_lo2-gloves-13-sven.tif"
                }
            }
        ],
        "filters": [
            {
                "value": "lo2",
                "name": "Brand",
                "url": "url/to/file.tif"
            },
            {
                "value": "13/14",
                "name": "Season",
                "url": null
            }
        ],
        "rental_options": null,
        "storage": [
            {
                "key": "dog",
                "value": "yes"
            }
        ],
        "files": [
            {
                "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
                "tags": [
                    "never",
                    "gonna",
                    "give",
                    "you",
                    "up"]
            }
        ],
        "data_entities": [
            "Your games custom data for this asset"
        ],
        "asset_candidate": {
            "created_by_player_id": 1234,
            "created_by_player_uid": "A1B2C3D4"
        },
        "drop_table_max_picks": null
    }
    

    Getting Asset Bone Information

    curl -X GET "https://api.lootlocker.io/game/v1/asset/bones"
    

    Sample success response

    {
        "success": true,
        "bones": [
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "-0.16281861,0.007631816,-0.93363667",
                    "BoneName": "Bip01 L Foot",
                    "Flags": "0",
                    "Mass": "1.4",
                    "Binding": "CharacterAttachments/bindings/lo2/lo2-bindings-13-pilen/lo2-bindings-13-pilen.cgf"
                },
                "id": "7",
                "name": "bindings_left"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "0.16281861,0.007631816,-0.93363667",
                    "BoneName": "Bip01 R Foot",
                    "Flags": "0",
                    "Mass": "1.4",
                    "Binding": "CharacterAttachments/bindings/lo2/lo2-bindings-13-pilen/lo2-bindings-13-pilen.cgf"
                },
                "id": "8",
                "name": "bindings_right"
            },
            {
                "parameters": {
                    "Rotation": "0.70006877,0.0077114832,0.0037791394,0.71402371",
                    "BoneName": "Bip01 Head",
                    "Position": "0,0.24771199,0.8292712",
                    "Flags": "0"
                },
                "id": "1",
                "name": "flashlight"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "BoneName": "Bip01 Head",
                    "Position": "0,0,0",
                    "Flags": "0",
                    "Mass": "0.1"
                },
                "id": "3",
                "name": "goggles"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "BoneName": "Bip01 Head",
                    "Position": "0,0,0",
                    "Flags": "0"
                },
                "id": "4",
                "name": "gogglestrap"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "0,0,0",
                    "BoneName": "Bip01 Head",
                    "Flags": "0",
                    "Mass": "0.5",
                    "Binding": "CharacterAttachments/hats/lo2/lo2-hats-13-bovall/lo2-hats-13-bovall.cgf"
                },
                "id": "2",
                "name": "headwear"
            },
            {
                "parameters": {
                    "Rotation": "0.80885416,-0.57089424,0.032788098,0.13696483",
                    "Position": "-0.53078705,0.15658157,0.030430784",
                    "BoneName": "Bip01 L Hand",
                    "Flags": "0",
                    "Mass": "0.2",
                    "Binding": "CharacterAttachments/poles/lo2/lo2-pole-13-spara/lo2-pole-13-spara.cgf"
                },
                "id": "5",
                "name": "pole_left"
            },
            {
                "parameters": {
                    "Rotation": "-0.80885416,0.57089424,0.032788098,0.13696483",
                    "Position": "0.53078705,0.15658157,0.030430784",
                    "BoneName": "Bip01 R Hand",
                    "Flags": "0",
                    "Mass": "0.2",
                    "Binding": "CharacterAttachments/poles/lo2/lo2-pole-13-spara/lo2-pole-13-spara.cgf"
                },
                "id": "6",
                "name": "pole_right"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "-0.16281861,-0.023641124,-0.93918115",
                    "BoneName": "Bip01 L Foot",
                    "Flags": "0",
                    "Mass": "2.5",
                    "Binding": "CharacterAttachments/skis/lo2/lo2-skis-13-Spara/lo2-skis-13-Spara.cgf"
                },
                "id": "9",
                "name": "ski_left"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "0.16281861,-0.023641124,-0.93918115",
                    "BoneName": "Bip01 R Foot",
                    "Flags": "0",
                    "Mass": "2.5",
                    "Binding": "CharacterAttachments/skis/lo2/lo2-skis-13-Spara/lo2-skis-13-Spara.cgf"
                },
                "id": "10",
                "name": "ski_right"
            },
            {
                "parameters": {
                    "Rotation": "1,0,0,0",
                    "Position": "0.0015605614,-0.023641124,-0.93918115",
                    "BoneName": "Bip01 L Foot",
                    "Flags": "0",
                    "Mass": "5",
                    "Binding": "CharacterAttachments/Snowboards/snowboard_prototype.cgf"
                },
                "id": "11",
                "name": "snowboard"
            }
        ]
    }
    

    This call will return you all the default bones. If a binding overrides anything on a bone, it will be returned along with the binding.

    Getting Asset Information For One or More Assets

    The id can also be a comma separated string for getting multiple assets: 16,17.

    curl -X GET "https://api.lootlocker.io/game/v1/asset/16"
    

    Sample success response

    {
      "success": true
    }
    
    {
      "id": 916,
      "name": "Sialia",
      "active": true,
      "price": 0,
      "sales_price": null,
      "shop_thumbnail": "",
      "context": "Map",
      "character_classes": [],
      "detachable": false,
      "updated": "Tue, 16 Jun 2015 08:38:19 +0000",
      "default_variation_id": 0,
      "default_loadouts": {
          "skier": true,
          "snowboarder": false
      },
      "description": "",
      "links": null,
      "storage": [
          {
              "key": "a key",
              "value": "the value"
          }
      ],
      "package_contents": null,
      "featured": false,
      "success": true
    }
    
    {
      "id": 917,
      "name": "Spawn_Event_ShrineTT6",
      "active": true,
      "price": 0,
      "sales_price": null,
      "shop_thumbnail": "",
      "context": "Spawn Point",
      "character_classes": [],
      "detachable": false,
      "updated": "Mon, 15 Jun 2015 16:19:05 +0000",
      "default_variation_id": 0,
      "default_loadouts": {
          "skier": true,
          "snowboarder": false
      },
      "description": "",
      "links": null,
      "storage": [
          {
              "key": "a key",
              "value": "the value"
          }
      ],
      "files": [
        {
            "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
            "tags": [
                "never",
                "gonna",
                "give",
                "you",
                "up"]
        }
      ],
      "package_contents": null,
      "featured": false,
      "data_entities": [
          "Your games custom data for this asset"
      ],
      "success": true
    }
    

    Sample failed request

    {
        "success": true
    }
    
    {
        "success": false,
        "error": "No such asset",
        "asset_id": 916
    }
    
    {
        "id": 917,
        "name": "Spawn_Event_ShrineTT6",
        "active": true,
        "price": 0,
        "sales_price": null,
        "shop_thumbnail": "",
        "context": "Spawn Point",
        "character_classes": [],
        "detachable": false,
        "updated": "Mon, 15 Jun 2015 16:19:05 +0000",
        "default_variation_id": 0,
        "default_loadouts": {
            "skier": true,
            "snowboarder": false
        },
        "description": "",
        "links": null,
        "storage": [
            {
              "key": "a key",
              "value": "the value"
            }
        ],
        "files": [
            {
                "url": "https://cdn.lootlocker.io/141/5f230b1e14614.txt",
                "tags": [
                    "never",
                    "gonna",
                    "give",
                    "you",
                    "up"]
            }
        ],
        "data_entities": [
            "Your games custom data for this asset"
        ],
        "package_contents": null,
        "featured": false,
        "success": true
    }
    

    This endpoint returns data describing assets for game purposes, and it's a streamed response, just like when you call the Get All Assets endpoint.

    Each returned asset has it own success status. It can be true or false, and if it's false, an error explaining what went wrong will also be returned, this object will also hold the ID of the asset you requested.

    Listing Favourite Assets

    curl -X GET "https://api.lootlocker.io/game/v1/asset/favourites"
    

    This call will simply list the current players favourite assets.

    Example response

    {
        "success": true,
        "favourites": [
            1,2,3,4,5
        ]
    }
    

    Adding Favourite Assets

    curl -X POST "https://api.lootlocker.io/game/v1/asset/258/favourite"
    

    This will favourite the asset id that is placed in the url between asset and favourite. The response will be the same as from Listing Favourite Assets.

    Removing Favourite Assets

    curl -X DELETE "https://api.lootlocker.io/game/v1/asset/258/favourite"
    

    This will remove the asset id that is placed in the url between asset and favourite from the favourite list. The response will be the same as from Listing Favourite Assets.

    Asset Instances

    Asset instances is what you will be working with when you have a player owned asset. A few actions can be taken on these instances, such as using the key/value storage to track distance traveled or deaths (etc) with one specific asset instance (also referred to as an item).

    To call these endpoints, you will need to know the id of the instance you wish to interact with. You will find the instances you will have access to by calling the Get Inventory endpoint.

    Getting All Key Value Pairs

    curl -X GET "https://f2p.poppemrost.se/game/v1/asset/instance/storage"
    

    This endpoint will return a streamed response with individual objects for each key/value pair.

    Example Response

    {
        "success": true,
    }{
        "instance_id": 1234,
        "storage": {
            "id": 123,
            "key": "fruit",
            "value": "banana"
        }
    }{
        "streamedObjectCount": 1
    }
    

    Getting All Key Value Pairs to an Instance

    curl -X GET "https://api.lootlocker.io/game/v1/asset/instance/57613/storage"
    

    When getting all key value pairs to an instance, you will receive an object with a success property. If this property holds a true value, you will also find a storage property, which will hold an array of key value pairs. In case of an error, the success property will hold a false value, and there will be an error property holding a string explaining what went wrong.

    Example Response

    {
        "success": true,
        "storage": [
            {
                "id": 1,
                "key": "distanceTraveled",
                "value": "118581"
            },
            {
                "id": 2,
                "key": "deaths",
                "value": "19"
            }
        ]
    }
    

    Getting A Key Value Pair By Id

    curl -X GET "https://api.lootlocker.io/game/v1/asset/instance/57613/storage/1"
    

    You can get a single key value pair by it's id by tacking the id of a pair on the url you used to get all key value pairs for an instance.

    Example Response

    {
        "success": true,
        "storage": [
            {
                "id": 1,
                "key": "distanceTraveled",
                "value": "45678"
            }
        ]
    }
    

    Creating A Key Value Pair

    curl -X POST "https://api.lootlocker.io/game/v1/asset/instance/57613/storage"
      -H "Content-Type: application/json"
      -d "{\"key\": \"distanceTraveled\", \"value\": \"1233\"}"
    

    Creating a key value pair is done by sending a POST request to the same endpoint as you get the list from. There is currently no support for bulk creation of keys. You will have to send multiple requests.

    Example Response

    {
        "success": true,
        "storage": [
            {
                "id": 1,
                "key": "distanceTraveled",
                "value": "1233"
            }
        ]
    }
    

    Updating One Or More Key Value Pairs

    curl -X PUT "https://api.lootlocker.io/game/v1/asset/instance/57613/storage"
      -H "Content-Type: application/json"
      -d "{\"storage\": [{\"key\": \"distanceTraveled\", \"value\": \"45678\"}]}"
    

    When you want to update the value of one or more keys, you can simply send a PUT request to the same endpoint as you would for creating a key value pair. The biggest difference is that this endpoint supports bulk requests, meaning the data format is a bit different in that it requires a main property (storage), which is an array holding objects of key value pairs.

    Example Response

    {
        "success": true,
        "storage": [
            {
                "id": 1,
                "key": "distanceTraveled",
                "value": "1233"
            }
        ]
    }
    

    Updating A Key Value Pair By Id

    curl -X PUT "https://api.lootlocker.io/game/v1/asset/instance/57613/storage/1"
      -H "Content-Type: application/json"
      -d "{\"key\": \"distanceTraveled\", \"value\": \"45678\"}"
    

    When updating by id, both key and value are optional, but you must supply at least one of them. When updating by id, you can change the key, and keep the value if you wish. The response from this call will only return the affected key value pair.

    Example Response

    {
        "success": true,
        "storage": [
            {
                "id": 1,
                "key": "distanceTraveled",
                "value": "45678"
            }
        ]
    }
    

    Delete A Key Value Pair

    curl -X DELETE "https://api.lootlocker.io/game/v1/asset/instance/57613/storage/1"
    

    Deleting a key value pair is done by sending a DELETE request with the id of the pair you want to delete. The response will be the same as calling Getting All Key Value Pairs To An Instance.

    Example response

    {
        "success": true,
        "storage": [
            {
                "id": 2,
                "key": "deaths",
                "value": "19"
            }
        ]
    }
    

    Inspect a Loot Box

    curl -X GET "https://api.lootlocker.io/game/v1/asset/instance/57613/inspect"
    

    Asset instances with the type set to loot box can be inspected, to see what assets the player might possibly get when opening them.

    You are supplied with the weight of the assets in this call. You can use that to display the chance that a player will get an asset, or to simulate it in a carousel. Sum the weights to know the total lots, and then you have a weight in sum(weights) chance of getting a specific asset. For more information see the article by Peter Kelly on weighted random selection.

    Example response

    {
        "success": true,
        "contents": [
            {
                "asset_id": 4,
                "asset_variation_id": null,
                "asset_rental_option_id": 11,
                "weight": 200
            },
            {
                "asset_id": 7,
                "asset_variation_id": 5,
                "asset_rental_option_id": null,
                "weight": 2
            },
            {
                "asset_id": 7,
                "asset_variation_id": null,
                "asset_rental_option_id": null,
                "weight": 40
            }
        ]
    }
    

    Open a Loot Box

    curl -X PUT "https://api.lootlocker.io/game/v1/asset/instance/57613/open"
    

    Asset instances with the type set to loot box can be opened, using this endpoint. Once you call this endpoint, the Loot Box will be removed from the players inventory, and a new asset will be added to the inventory, with the acquisition_source set to grant_loot_box. You will be asked to check the grant notifications to see which asset was granted.

    Example response

    {
        "success": true,
        "check_grant_notifications": true
    }
    

    In a 10000 iteration test we ran, we got the following results:

    AssetWeightTimes recievedPredicted chanceActual chance
    11590.55%0.59%
    280441744.20%44.17%
    3100552455.25%55.24%
    Sums18110000100%100%

    For more information see the article by Peter Kelly on weighted random selection.

    User Generated Content

    With User Generated Content (UGC) your game client can upload Asset Candidates to LootLocker which can be turned into Assets to get the full power of LootLocker's Asset functionality.

    Asset Candidates are promoted to Assets once they are marked as complete and have passed moderation. Moderation can be disabled if you do not distribute UGC widely, in which case Asset Candidates will be promoted to Assets upon being marked as complete.

    Creating an Asset Candidate

    curl -X POST "https://api.lootlocker.io/game/v1/player/assets/candidates" \
        -H "Content-Type: application/json"
        -d "{\"data\": {\"name\": \"My UGC Asset\"}}"
    

    Example Payload

    {
        "data": {
            "name": "My UGC Asset",
            "context_id": 1740,
            "kv_storage": [
                {
                    "key": "kind",
                    "value": "sofa"
                }
            ],
            "filters": [
                {
                    "key": "size",
                    "value": "large"
                }
            ],
            "data_entities": [
                {
                    "name": "astley-paradox",
                    "data": "SWYgeW91IGFzayBSaWNrIEFzdGxleSBmb3IgYSBEVkQgb2YgdGhlIG1vdmllIFVwLCBoZSB3b24ndCBnaXZlIGl0IHRvIHlvdSBiZWNhdXNlIGhlJ3MgbmV2ZXIgZ29ubmEgZ2l2ZSB5b3UgVXAuIEhvd2V2ZXIsIGJ5IG5vdCBnaXZpbmcgeW91IFVwIGxpa2UgeW91IGFza2VkIGZvciBpdCwgaGUncyBsZXR0aW5nIHlvdSBkb3duLiBUaGlzIGlzIGtub3duIGFzIHRoZSBBc3RsZXkgcGFyYWRveA=="
                }
            ]
        }
    }
    

    The data property in payload sent when creating an Asset Candidate currently supports the following data, all being optional, but some required for promotion to an Asset.

    PropertyTypeValueRequired For Promotion
    namestringA name for the AssetYes
    context_idintegerA context_id that will be used when promoting the Asset Candidate to an Asset. Automatically filled if not providedYes
    kv_storagearrayAn array or objects with key and value keysNo
    filtersarrayAn array or objects with key and value keysNo
    data_entitiesarrayAn array or objects with name and data keysNo

    Example Response

    {
        "success": true,
        "asset_candidate_id": 15,
        "asset_candidate": {
            "id": 15,
            "asset_id": null,
            "status": "INCOMPLETE",
            "review_feedback": null,
            "data": {
                "name": "My UGC Asset",
                "kv_storage": [
                    {
                        "key": "kind",
                        "value": "sofa"
                    }
                ],
                "filters": [
                    {
                        "key": "size",
                        "value": "large"
                    }
                ],
                "data_entities": [
                    {
                        "name": "astley-paradox",
                        "data": "SWYgeW91IGFzayBSaWNrIEFzdGxleSBmb3IgYSBEVkQgb2YgdGhlIG1vdmllIFVwLCBoZSB3b24ndCBnaXZlIGl0IHRvIHlvdSBiZWNhdXNlIGhlJ3MgbmV2ZXIgZ29ubmEgZ2l2ZSB5b3UgVXAuIEhvd2V2ZXIsIGJ5IG5vdCBnaXZpbmcgeW91IFVwIGxpa2UgeW91IGFza2VkIGZvciBpdCwgaGUncyBsZXR0aW5nIHlvdSBkb3duLiBUaGlzIGlzIGtub3duIGFzIHRoZSBBc3RsZXkgcGFyYWRveA=="
                    }
                ],
                "context_id": 1740
            },
            "files": [],
            "created_at": "Tue, 17 Nov 2020 12:56:58 +0000",
            "updated_at": "Tue, 17 Nov 2020 12:56:58 +0000"
        }
    }
    

    The context_id in the above table will be set automatically by LootLocker if you provide none. We suggest you use the context functionality to organize your Asset Candidates if that makes sense in the context of your game.

    Updating an Asset Candidate

    curl -X PUT "https://api.lootlocker.io/game/v1/player/assets/candidates/1234" \
        -H "Content-Type: application/json"
        -d "{\"completed\": true, \"data\": {\"name\": \"My Renamed Asset Candidate\"}}"
    

    When updating an Asset Candidate, you can update all data that you can also set when creating one. Additionally you use this call to mark the Asset Candidate as completed, by sending a property called completed with the value set to boolean true.

    Any data property sent along will replace the entirety of that property on the Asset Candidate, so make sure that you send everything you want to store, and not just what's changed.

    Example Response

    {
        "success": true,
        "asset_candidate": {
            "id": 15,
            "asset_id": 6763,
            "status": "APPROVED",
            "review_feedback": null,
            "data": {
                "name": "My UGC Asset",
                "kv_storage": [
                    {
                        "key": "kv-test",
                        "value": "great success"
                    }
                ],
                "filters": [
                    {
                        "key": "filter-test",
                        "value": "great success"
                    }
                ],
                "data_entities": [
                    {
                        "name": "Entity test",
                        "data": "flergen dergen hergen"
                    }
                ],
                "context_id": 1740
            },
            "files": [],
            "created_at": "Tue, 17 Nov 2020 12:56:58 +0000",
            "updated_at": "Tue, 17 Nov 2020 12:58:25 +0000"
        }
    }
    

    Once an Asset Candidate has been marked as completed, it will enter the moderation queue or be directly promoted to an Asset if moderation is disabled for your game. Once this has happened you can no longer update it.

    Deleting an Asset Candidate

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/assets/candidates/1234"
    

    Deleting Asset Candidates can be done by ID, and only while the Asset Candidate haven't yet been promoted to an Asset.

    Example Response

    {"success": true}
    

    Listing Asset Candidates

    curl -X GET "https://api.lootlocker.io/game/v1/player/assets/candidates"
    

    You can retrieve all Asset Candidates belonging to the current player, by issuing a call to this endpoint. If an Asset Candidate have been promoted to an Asset, the Asset's ID will be set in the property asset_id.

    Example Response

    {
        "success": true,
        "asset_candidates": [
            {
                "id": 3876,
                "asset_id": 6737,
                "status": "APPROVED",
                "review_feedback": null,
                "data": {
                    "name": "My UGC Asset",
                    "kv_storage": [
                        {
                            "key": "kind",
                            "value": "sofa"
                        }
                    ],
                    "filters": [
                        {
                            "key": "size",
                            "value": "large"
                        }
                    ],
                    "data_entities": [
                        {
                            "name": "astley-paradox",
                            "data": "SWYgeW91IGFzayBSaWNrIEFzdGxleSBmb3IgYSBEVkQgb2YgdGhlIG1vdmllIFVwLCBoZSB3b24ndCBnaXZlIGl0IHRvIHlvdSBiZWNhdXNlIGhlJ3MgbmV2ZXIgZ29ubmEgZ2l2ZSB5b3UgVXAuIEhvd2V2ZXIsIGJ5IG5vdCBnaXZpbmcgeW91IFVwIGxpa2UgeW91IGFza2VkIGZvciBpdCwgaGUncyBsZXR0aW5nIHlvdSBkb3duLiBUaGlzIGlzIGtub3duIGFzIHRoZSBBc3RsZXkgcGFyYWRveA=="
                        }
                    ],
                    "context_id": 1740
                },
                "files": [
                    {
                        "id": 5,
                        "url": "https://cdn.lootlocker.io/......",
                        "size": 69919,
                        "name": "my-ugc-asset-thumbnail.png",
                        "purpose": "PRIMARY_THUMBNAIL"
                    }
                ],
                "created_at": "Mon, 26 Oct 2020 08:48:34 +0000",
                "updated_at": "Mon, 26 Oct 2020 10:28:03 +0000"
            }
        ]
    }
    

    You will notice a context_id in the Asset Candidate data. You can assign contexts to your Asset Candidates, but if you do not, LootLocker will automatically create a User Generated Content context and put the context in that context.

    The status property can be used to know what the current status of an Asset Candidate is. The table below lists the possible statuses:

    StatusMeaning
    INCOMPLETEThe Asset Candidate has not yet been marked as complete
    DECLINEDThe Asset Candidate was rejected in moderation (see potential feedback in review_feedback)
    PENDINGThe Asset Candidate is awaiting moderation
    APPROVEDThe Asset Candidate is approved and useable by players in the game (asset_id references the derived Asset, and is null for any other status)

    Getting a single Asset Candidate

    curl -X GET "https://api.lootlocker.io/game/v1/player/assets/candidates/1234"
    

    You can also fetch just a single asset candidate by it's ID. The response will be a single object, but otherwise identical to listing Asset Candidates.

    Example Response

    {
        "success": true,
        "asset_candidate": {
            "id": 15,
            "asset_id": 6763,
            "status": "APPROVED",
            "review_feedback": null,
            "data": {
                "name": "My UGC Asset",
                "kv_storage": [
                    {
                        "key": "kv-test",
                        "value": "great success"
                    }
                ],
                "filters": [
                    {
                        "key": "filter-test",
                        "value": "great success"
                    }
                ],
                "data_entities": [
                    {
                        "name": "Entity test",
                        "data": "flergen dergen hergen"
                    }
                ],
                "context_id": 1740
            },
            "files": [],
            "created_at": "Tue, 17 Nov 2020 12:56:58 +0000",
            "updated_at": "Tue, 17 Nov 2020 12:58:25 +0000"
        }
    }
    

    Adding Files to Asset Candidates

    curl -L -X POST 'https://api.lootlocker.io/game/v1/player/assets/candidates/1234/file' \
    -H 'x-session-token: 17a76ed97be5224978c325m329bd4ccf1ee8b753' \
    -F 'file=@/path/to/file.ext' \
    -F 'purpose=PRIMARY_THUMBNAIL'
    

    When adding a file to an Asset Candidate you need to supply the file in a property called file along with a purpose to let LootLocker know what to do with the file.

    Example Response

    {"success": true}
    

    File Purposes

    PurposeUsed For
    PRIMARY_THUMBNAILThe Primary Thumbnail shown in the LootLocker interface for moderation and curation purposes
    THUMBNAILAny extra images you want to expose to the LootLocker interface
    FILEAny file you need to represent the content in your game client

    Removing Files from an Asset Candidate

    curl -X DELETE "https://api.lootlocker.io/game/v1/player/assets/candidates/1234/file/1234"
    

    Deleting a file is done by referencing the Asset Candidate and the File by their respective ID's in the URL.

    Example Response

    {"success": true}
    

    Missions

    Getting All Missions

    curl -X GET "https://api.lootlocker.io/game/v1/missions"
    

    When getting all missions, you will receive data to set up the missions in the map too. You only get this data (checkpoints), if the player has access to this mission. You can check if a player has access to a mission by looking at the boolean player_access. The segment_time field that will be returned with each checkpoint is the time-between-checkpoint, which you can use to let the player know how they're doing compared to their last run. As you can see in the example, the segment_time property is not guaranteed to be there. It will however most likely be there for all checkpoints in one mission, unless the mission has been updated since the player last played it.

    The best_goal property will hold a string with the name of the best goal the player have attained. If they have never played this mission or never reached a goal, it will be null.

    As you can see in the example JSON, goals have an assets attribute. This is an array containing objects of assets that will be rewarded the first time the player reaches this goal. See example structure under the gold goal.

    {
        "success": true,
        "missions": [
            {
                "mission_id": 1,
                "asset_id": 912,
                "rounds": 0,
                "round_length": "0",
                "difficulty_name": null,
                "difficulty_multiplier": null,
                "difficulty_color": "336699",
                "difficulty_id": 1,
                "goals": {
                    "gold": {
                        "goal": "00:20:00",
                        "points": "400",
                        "assets": [
                            {
                                "variation_id": 1,
                                "asset": {...}
                            }
                        ]
                    },
                    "silver": {
                        "goal": "00:30:00",
                        "points": "200",
                        "assets": []
                    },
                    "bronze": {
                        "goal": "00:35:00",
                        "points": "100",
                        "assets": []
                    }
                },
                "checkpoints": [
                  {
                    "index": 1,
                    "time": 18510,
                    "your_key": "your value",
                    "your_second_key": "your second value"
                  },{
                    "index": 2,
                    "your_key": "your value",
                    "your_second_key": "your second value"
                  }
                ],
                "player_access": true,
                "best_goal": "bronze"
            }
        ]
    }
    

    Getting A Single Mission

    curl -X GET "https://api.lootlocker.io/game/v1/mission/42"
    

    This endpoint is very similar to the Getting All Missions endpoint, in that it returns the same mission structure, but instead of a property called missions holding an array of missions, there is a property called mission, holding just one mission.

    {
        "success": true,
        "mission": {
            "mission_id": 1,
            "asset_id": 912,
            "rounds": 0,
            "round_length": "0",
            "difficulty_name": null,
            "difficulty_multiplier": null,
            "difficulty_color": "336699",
            "difficulty_id": 1,
            "goals": {
                "gold": {
                    "goal": "00:20:00",
                    "points": "400",
                    "assets": [
                        {
                            "variation_id": 1,
                            "asset": "Full asset representation, as returned everywhere else."
                        }
                    ]
                },
                "silver": {
                    "goal": "00:30:00",
                    "points": "200",
                    "assets": []
                },
                "bronze": {
                    "goal": "00:35:00",
                    "points": "100",
                    "assets": []
                }
            },
            "checkpoints": [
              {
                "index": 1,
                "time": 18510,
                "your_key": "your value",
                "your_second_key": "your second value"
              },{
                "index": 2,
                "your_key": "your value",
                "your_second_key": "your second value"
              }
            ],
            "player_access": true,
            "best_goal": "bronze"
        }
    }
    

    Starting Mission

    curl -X POST "https://api.lootlocker.io/game/v1/mission/1/start"
    

    When starting a mission, you need to call this endpoint. From this endpoint you will get a signature back, which you need to use to sign the mission end call.

    {
      "success": true,
      "signature": "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"
    }
    

    Finishing Mission

    curl -X POST "https://api.lootlocker.io/game/v1/mission/1/end" \
    -H "Content-Type: application/json" \
    -d "{\"signature\": \"eee411109a229046154bc9d75265a9ccb23a3a9c\", \"payload\": {\"finish_time\": \"02:23:255\", \"finish_score\": \"125\", \"checkpoint_times\": [{\"index\": 1, \"time\": 571613}]}}"
    
    {
      "success": true,
      "score": 450,
      "check_grant_notifications": true
    }
    

    When finishing the mission, you send a POST request to this endpoint. Your payload will hold data that's needed to calculate the score. You should calculate the score on your end, but you should correct your result to what you get from the response of this request, as that is what will be used in the backend.

    If your mission is time based, you can send along checkpoint times, referenced as times. These are reported in milliseconds, and as a difference between two checkpoints only, summing these up should equal the total time of the mission. The backend will automatically store these for returning when loading missions. The data will only be updated if the total time is better than what's on file.

    The check_grant_notifications field serves the same function as in the authentication call, meaning that if it's true, you should check the player asset notification endpoint for new notifications. You can do so immediately in this case, unlike the authentication call.

    You do not have to send both finish_time and finish_score in calls, if you instead prefer to keep track of which type of mission is using what kind of goal, but you can simply just send both.

    Signing Your Mission

    Signing has to be done by concatenating the JSON string, the signature and the players backend id, and then hash it using SHA1.

    # Assuming the three parts are
    # 1: JSON = {"finish_time": "02:23:255", "finish_score": "125"}
    # 2: Signature = 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
    # 3: player_id = 66c18e45974889b4d0ecf3e92f6036ee9d2d50ee
    
    sha1({"finish_time": "02:23:255", "finish_score": "125"}86f7e437faa5a7fce15d1ddcb9eaeaea377667b866c18e45974889b4d0ecf3e92f6036ee9d2d50ee) = 5d23383d582868ded525ee73d455d4d4b6d9592d
    

    The order should be JSON string signature player_id.

    The first part of the concatenated string is the JSON bit. That should only contain the object inside the payload property.

    The second part is the signature you obtained from the Starting Mission endpoint.

    The third part should be the player_id that you get when starting the session.

    Once you've concatenated the three parts and hashed the resulting string, you should put it in a JSON object with the key signature, along side the payload property.

    Drop Tables

    Compute and Lock Drop Table

    curl -X POST "https://api.lootlocker.io/game/v1/player/droptables/2/compute"
    

    When you wish to evaluate a drop table and lock the drops from it in place, you call this endpoint. The response will hold information on the assets that are dropped, and can be picked up using the Pick endpoint.

    The response is kept light to minimise resource usage, but if you need the full representation of the asset, you can include a GET style parameter in the url ?asset_details=true, and an additional asset property will be returned, with the full asset representation.

    If you use tags with your drop tables, you can include a tag to only include groups and drops tagged with this tag in the caluclation. The tag is included by adding it as a GET style parameter: ?tag=skeleton.

    Example Response

    {
        "success": true,
        "items": [
            {
                "asset_id": 520,
                "asset_variation_id": null,
                "asset_rental_option_id": null,
                "id": 3
            }
        ]
    }
    

    The ID in the URL is the instance_id of the drop table asset from the players inventory.

    Once a drop table has been computed and locked, there is a 24 hour guarantee that the pick endpoint will work. After this period, the drop table asset instance and it's locked drops may will be removed from the players inventory.

    Pick Drops from Drop Table

    curl -X POST "https://api.lootlocker.io/game/v1/player/droptables/2/pick" \
        -H "Content-Type: application/json" \
        -d "{\"picks\": [3]}"
    

    When picking the drops to claim from a locked drop table, you send a payload along with the request, containing the ID's of the drops from the Compute endpoint. This payload has the key picks which contain an array of the ID's you want to pick. If you want to pick up nothing, you can send an empty array.

    The response from this request contains the full asset of all the picked drops. See Getting Asset List for the full structure.

    Example Response

    {
        "success": true,
        "items": [
            {
                "instance_id": 487,
                "variation_id": null,
                "rental_option_id": null,
                "quantity": 1,
                "asset": {...}
            }
        ]
    }
    

    Maps

    Getting All Maps

    curl -X GET "https://api.lootlocker.io/game/v1/maps"
    

    Getting all maps will return the simplest representation of a map, simply providing you with an asset_id to get the name, thumbnail etc. Maps also contain the spawn points.

    Example response

    {
        "success": true,
        "maps": [
            {
                "map_id": 1,
                "asset_id": 938,
                "spawn_points": [
                    {
                        "asset_id": 966,
                        "position": null,
                        "rotation": null,
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": false
                    },{
                        "asset_id": 967,
                        "position": "9157757101045",
                        "rotation": "958176717818238",
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": true
                    }
                ],
                "player_access": false
            },
            {
                "map_id": 2,
                "asset_id": 950,
                "spawn_points": [
                    {
                        "asset_id": 966,
                        "position": null,
                        "rotation": null,
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": false
                    },{
                        "asset_id": 967,
                        "position": "9157757101045",
                        "rotation": "958176717818238",
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": true
                    }
                ],
                "player_access": false
            },
            {
                "map_id": 3,
                "asset_id": 965,
                "spawn_points": [
                    {
                        "asset_id": 966,
                        "position": null,
                        "rotation": null,
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": false
                    },{
                        "asset_id": 967,
                        "position": "9157757101045",
                        "rotation": "958176717818238",
                        "cameras": [
                            {
                                "position": "12958181",
                                "rotation": "9591885818"
                            }
                        ],
                        "player_access": true
                    }
                ],
                "player_access": true
            }
        ]
    }
    

    Purchasing

    Only some platforms support purchasing with hard currency. The below table provides an overview

    PlatformSupports Hard Currency Purchasing
    SteamYes
    PSNYes
    RobloxNo
    iOSYes
    AndroidYes

    Purchase Call

    Normal purchase example

    curl -X POST "https://api.lootlocker.io/game/v1/purchase" \
        -H "Content-Type: application/json" \
        -d "[{\"asset_id\": 56, \"variation_id\": 130},{\"asset_id\": 380, \"variation_id\": 616}]"
    

    Rental example

    curl -X POST "https://api.lootlocker.io/game/v1/purchase" \
        -H "Content-Type: application/json" \
        -d "[{\"asset_id\": 56, \"variation_id\": 130, \"rental_option_id\": 47}]"
    

    Sending a request to this endpoint with asset information, will facilitate a purchase. If your game uses soft currency, it will check the players account balance and grant the assets to the player if there is coverage. If there is not coverage, an error will be returned.

    There are two different kinds of purchases you can perform. A rental and a standard purchase. When doing a standard purchase, you only need the asset_id and potentially the variation_id properties. When buying a rental asset, you will be required to send at least the asset_id and rental_option_id parameters. The rental_option_id value is obtained from the assets call, just like the asset_id and the variation_id. To activate a rental, see Activating A Rental Asset

    If your game does not use soft currency, or the assets you are buying are soft currency, the purchase will behave a few different ways depending on what platform the user is on:

    PlatformAction
    SteamAn overlay will be opened, asking the player to pay with their Steam Wallet.
    PSNFor PSN you will have had to initialize the purchase with the SDK for the PS4 first, and then call this endpoint to tell LootLocker to consume the entitlemnt on PSN.
    iOSYou have to complete an iOS In-App Purchase before calling the purchase endpoint in LootLocker. See iOS In-App Purchases for more information.
    AndroidSimilar to iOS, you have to complete an In-App Pruchase before calling the purchase endpoint in LootLocker. See Android In-App Purchases for more information.

    You will get an order_id in the response. This ID should be used to poll the order status until you get a final answer from it. See the polling order status endpoint

    The response will let you know if any form of overlay have been opened. Keep in mind, only if you have success = true and overlay = false can you safely assume that the purchase has been successful. If overlay is true, you should check the order status to know the status of the order. Once you know the purchase was successful you should issue a call to the player inventory endpoint to update the client inventory data.

    The external_identifiers field in the asset responses, is either null or an object, letting you know how to identify this same asset on other platforms. In the given examples PSN is used, and CRED01 is the entitlementLabel/entitlementId on Sony's side. Use this to know what credit package a player has bought through their servers when selecting which asset to purchase.

    Example response, with no overlay opened

    {
        "success": true,
        "overlay": false,
        "order_id": 583,
    }
    

    iOS In-App Purchases

    iOS In-App Purchase verification example

    curl -X POST "https://api.lootlocker.io/game/v1/purchase" \
        -H "Content-Type: application/json" \
        -d "[{\"receipt_data\": \"base64 encoded app store receipt\"}]"
    

    In-App Purchases on iOS are different from other purchases in LootLocker in the way that they don't take asset information, but instead requires a receipt from Apple that LootLocker will then verify and map to the correct asset information. This receipt is returned when reading Bundle.main.appStoreReceiptURL from your application.

    For any assets that should be purchasable multiple times, you should use consumable IAP's on Apples side, and once you have a successful purchase from LootLocker, call finishTransaction on the transaction in the client, to let Apple know to consume the purchase.

    Once the request returns successfully you should issue a call to the player inventory endpoint and/or the currency balance endpoint to update the client inventory and balance data.

    Example response for iOS In-App Purchase

    {
        "success": true,
        "overlay": false,
        "order_id": 583,
    }
    

    Android In-App Purchases

    Android In-App Purchase verification example

    curl -X POST "https://api.lootlocker.io/game/v1/purchase" \
        -H "Content-Type: application/json" \
        -d "[{\"asset_id\": 1234, \"purchase_token\": \"purchase_token_supplied_by_google_play_store\"}]"
    

    Purchases on Android are slightly different from other purchases, in that they take a purchase_token property besides the asset information. In the example here, we are buying in-game currency, which only requires an asset_id and the token. The purchase_token is obtained through the Google Play store, when performing an In-App Purchase.

    Once the request returns successfully you should issue a call to the player inventory endpoint and/or the currency balance endpoint to update the client inventory and balance data.

    Polling Order Status

    curl -X GET "https://api.lootlocker.io/game/v1/purchase/23"
    

    This call will let you know the current status of an order. If you get a response that is considered final, you should issue a call to the player inventory endpoint if you're in a context where the inventory might change.

    Example response

    {
        "success": true,
        "status": "closed"
    }
    

    The following statuses can currently be returned:

    StatusFinalDescription
    openNoThe order is being processed
    closedYesThe order have been processed successfully
    refundedYesThe order has been refunded
    canceledYesThe order has been canceled
    failedYesThe order failed

    Get Order Details

    curl -X GET "https://api.lootlocker.io/game/v1/purchase/23/details"
    

    This endpoint lets you inspect an order and see what products is contained, as well as the order status. For a description of order statuses, please see the table under Polling Order Status.

    If you do not want to return the products, you can add a flag to the url that removes them: ?no_products=true, in which case the products property will be null.

    Example Response

    {
        "success": true,
        "order_status": "succeeded",
        "products": [
            {
                "instance_id": 458,
                "variation_id": null,
                "rental_option_id": null,
                "acquisition_source": "purchase_unit",
                "asset": {...}
            }
        ]
    }
    

    Get Order Details By Platform Transaction ID

    curl -X GET "https://api.lootlocker.io/game/v1/purchase/transaction/1000000673097863/details"
    

    This endpoint is identical to Get Order Details, except that instead of the order id, you can use the First Party Platforms Transaction ID.

    The response is identical as well.

    Activating A Rental Asset

    curl -X POST "https://api.lootlocker.io/game/v1/asset/instance/57613/activate"
    

    Once you have purchased a rental asset, you need to activate the rental for it to become available for the player. This endpoint achieves that.

    The successful response from this endpoint, will contain just one property, time_left, which is seconds left until the rental expires. You should keep a timer running to deactivate the asset for the player once it runs out.

    Example response

    {
        "success": true,
        "time_left": 86400
    }
    

    Trigger Events

    Triggering an Event

    curl -X POST "https://api.lootlocker.io/game/v1/player/trigger"
      -H "Content-Type: application/json"
      -d "{\"name\": \"your trigger name here\"}"
    

    Trigger events can be configured through the Admin API, or in the LootLocker Management Console. There you can set rewards for triggering an event and so forth.

    Rewards can be either XP or assets (It can also be both). If assets have been granted, the endpoint will return the granted assets in the granted_assets property, in the standard full asset object format.

    As you can see in the example response, XP is a little more complicated, as it will return in the same format as the Submit Score endpoint.

    All of the properties will always be present

    Example response

    {
        "success": true,
        "check_grant_notifications": true,
        "xp": {
            "previous": 1234,
            "current": 2468
        },
        "levels": [
            {
                "level": 1,
                "xp_threshold": 1000
            },
            {
                "level": 2,
                "xp_threshold": 3000
            },
            {
                "level": 3,
                "xp_threshold": 6000
            }
        ],
        "granted_assets": [
            {...}
        ]
    }
    

    Listing Triggered Trigger Events

    curl -X GET "https://api.lootlocker.io/game/v1/player/triggers"
    

    This endpoint lists the triggers that a player have already completed.

    Use this list to know which triggers to not call from the game client.

    Example Response

    {
        "success": true,
        "triggers": [
            "enterArea.area_east_sub_1",
            "enterArea.area_east_sub_10",
            "enterArea.area_east_sub_11",
            "enterArea.area_east_sub_2"
        ]
    }
    

    Collectables

    Collectables and triggers are very similar functionalities. The difference is that collectables are nested in 3 layers (Collectable, Groups and Items). Each entity in can have a reward that's triggered when all nested entities are completed (for items this is when the item is collected).

    Getting Collectables

    curl -X GET "https://api.lootlocker.io/game/v1/collectable
    

    This endpoint will return all the collectables a game has set up. It will hold a set of Collectables, with Groups inside which in turn contain Items. Items are what you collect as a player. The Groups and the Collectable are containers, that serve to give a segmented completion percentage and to give rewards to the player at differet completion stages.

    Each level (Collectables, Groups and Items) can contain rewards for the player. These rewards are contained in rewards for each item. An empty array means no rewards. There is a flag grants_all_rewards, which signifies if the rewards will be all granted to the player, or if one of the rewards will be randomly selected for the reward. Each reward contains a full representation of an asset, along with the asset_variation_id or asset_rental_option_id that will be granted to the player.

    Even collected Items are returned, with a boolean collected set to true. This is done to make it easier to remove them from your world, give them a different look, or make sure you do not collect them again.

    Additionally there is a boolean just_collected to let you know if this collectable item was collected in a call issued to the Collecting an Item endpoint. It will always be false when requesting the list of collectables, and only be true if the call was successful in collecting an item.

    Example response

    {
        "success": true,
        "collectables": [
            {
                "name": "CarsDriven",
                "groups": [
                    {
                        "name": "SUVs",
                        "completion_percentage": 50,
                        "items": [
                            {
                                "name": "Sporty",
                                "collected": true,
                                "rewards": [],
                                "grants_all_rewards": false,
                                "just_collected": false
                            },
                            {
                                "name": "Practical",
                                "collected": false,
                                "rewards": [],
                                "grants_all_rewards": false,
                                "just_collected": false
                            }
                        ],
                        "rewards": [],
                        "grants_all_rewards": false
                    },
                    {
                        "name": "Bugs",
                        "completion_percentage": 0,
                        "items": [
                            {
                                "name": "Dune",
                                "collected": false,
                                "rewards": [
                                    {
                                        "asset": {...},
                                        "asset_variation_id": 7010,
                                        "asset_rental_option_id": null
                                    }
                                ],
                                "grants_all_rewards": true,
                                "just_collected": false
                            }
                        ],
                        "rewards": [],
                        "grants_all_rewards": false
                    }
                ],
                "completion_percentage": 33,
                "rewards": [],
                "grants_all_rewards": false
            }
        ]
    }
    

    Collecting an Item

    curl -X POST "https://api.lootlocker.io/game/v1/collectable" \
        -H "Content-Type: application/json" \
        -d "{\"slug\": \"CarsDriven.Bugs.Dune\"}"
    

    Collecting an Item is done by calling this endpoint with a payload equal to the slug of the Item.

    The slug is a combination of the name of the Collectable, the Group and the Item. Simply concatenate them with a . as a seperator. In the example we're collecting the Item Dune in the Group Bugs that belongs to the Collectable CarsDriven.

    Once an Item is collected, you will get a response back identical to the one you get from Getting Collectables, with the addition of a field at the root level called check_grant_notifications. If this field is true, you should check the players player asset grant notifications.

    Messages

    Get Messages

    curl -X GET "https://api.lootlocker.io/game/v1/messages"
    

    The messages Game System allows you to send messages to your players, such as news and promotions.

    Messages are somewhat personalized for the player, in that they has a new property that tells if the message is new since the players last session.

    Example Response

    {
        "success": true,
        "messages": [
          {
            "title": "Whiteridge has opened!",
            "published_at": "2017-09-08 09:36:25",
            "body": "Welcome to Whiteridge! The small mountain town with lots of stuff for your skiing pleasure...",
            "summary": "Today we're releasing a new level called Whiteridge.\r\n\r\nWhiteridge is an urban level with lots of jumps and features to hit.",
            "category": "levels",
            "alert": true,
            "new": true,
            "action": "",
            "image": "https://url/to/file.dds"
          }
        ]
    }
    

    Crashes

    Submitting a Crash Log

    # Uploading a crash log with bash
    curl -X -i -F log=@path/to/your/log/file.zip "https://api.lootlocker.io/game/v1/crash" \
      -d "version=game_version" \
      -H "x-session-token=your_session_token"
    

    Submitting a crash works much like most other requests do. There are two exceptions, a file upload, and the request does not take a JSON body, but instead uses POST fields.

    The parameters for this call is as follows:

    ParameterRequiredDescription
    logYesYour log file
    game_versionnoThe version of the game at crash time
    type_identifiernoA crash identifier you create
    local_crash_timenoThe time the crash happened on the users computer

    The type_identifier property is special. You should compute a string between 1 and 255 characters, that uniquely identifies this type of crash. Using this LootLocker will alert you when too many crashes of the same type happen in a short span.

    If you are able to submit the crash in a crashed state, you can do that, but the general idea behind this is to submit it on the next launch of your game.

    Errors

    Errors are hinted with HTTP Status codes. 200 is OK, the rest that we're using is listed below here. You should be able to handle all of these in your integration.

    Error CodeMeaning
    400Bad Request -- Your request has an error
    402Payment Required -- Payment failed. Insufficient funds, etc.
    401Unauthroized -- Your session_token is invalid
    403Forbidden -- You do not have access
    404Not Found
    405Method Not Allowed
    406Not Acceptable -- Purchasing is disabled
    409Conflict -- Your state is most likely not aligned with the servers.
    429Too Many Requests -- You're being limited for sending too many requests too quickly.
    500Internal Server Error -- We had a problem with our server. Try again later.
    503Service Unavailable -- We're either offline for maintenance, or an error that should be solvable by calling again later was triggered.

    Deprecations

    When the API changes and an endpoints reaches the end of it's life, it will send a X-Endpoint-Deprecated: true header with each response, until it's taken out of service. A list of currently deprecated endpoints will also be maintained here, along with their EOL date, which is 6 months after they have been deprecated.

    If the below table is empty, there aren't currently any deprecations.

    EndpointRequest TypeEOLReplaced By