Sign in

Battle Passes

Battle Passes are a gamification concept which got popular in games like Fortnite and Battlefield. The idea behind a Battle Pass is to offer groups of curated challenges (levels) that are unlocked step by step. In gaming context those levels have increasing difficulty. Every level has its own reward.

In a typical Battle Pass gamers unlock the first level quickly and get the first reward - e.g. a new weapon or vanity items like character skins. The next levels' challenges are a bit harder to achieve and the reward is more valuable to the gamer than the first one. The last level is very hard to achieve and the reward is really big.

Most Battle Passes are setup in seasons, i.e. they have a start and an end date.

Base URL

https://es.scillgame.com

The BattlePass object

BattlePass objects keep all Battle Pass related data and may (optionally) contain a levels property with an array of BattlePassLevel objects. See the next section to learn more about the BattlePassLevel object.

All endpoints return an object with at least these parameters. Depending on the context, some additional parameters might be provided that are listed below (see Additional paramaters).

Parameters

battle_pass_id string

The unique id of this battle pass.

app_id string

The unique id of the app

battle_pass_name string

The name of the battle bass. You can set that in the Admin Panel. The language is set with the query parameter language. See documentation for more info on that.

battle_pass_description string

The description of the battle bass. You can set that in the Admin Panel and it can also be HTML. The language is set with the query parameter language. See documentation for more info on that.

battle_pass_short_description string

A short description of the battle bass. You can set that in the Admin Panel and it can also be HTML. The language is set with the query parameter language. See documentation for more info on that.

battle_pass_disclaimer string

Use this to provide some terms and conditions following along this battle passes purchase.

battle_pass_priority integer

The priority of the battle pass. I.e. if multiple are available you can use this field to sort them.

package_sku_ios string

If you want to sell Battle Passes you can use this field to trigger in-app purchase products within your mobile app. You can set this value in the Admin Panel. This one is for iOS.

package_sku_android string

If you want to sell Battle Passes you can use this field to trigger in-app purchase products within your mobile app. You can set this value in the Admin Panel. Use this to set the package string for Android.

image string

The mobile sized image name. For example you can use image and image_desktop to build a srcset in HTML or use them and size manually where you need them.

image_desktop string

The desktop sized image name or URL

start_date string

The date (in iso format) when the Battle Pass starts. Tracking begins once this date is passed.

end_date string

The date (in iso format) when the Battle Pass ends. Tracking stops once the end is reached and users will not be able to progress further than what they have achieved up to that point.

read_more_link string

If the Battle Pass costs “money” you may want to route the user to a web site/page, where they can learn more about this battle pass. You can also use this field to route the user inside your application by providing a path or whatever works for you.

is_unlocked_incrementally boolean

Indicates if one level after the other must be activated or if users can activate whichever level they want. Typically battle passes are unlocked level by level, but if battle passes are used for other applications (like user referal programs) it can be useful to set this to false.

is_active boolean

Indicated if this battle pass is active.

unlocked_at string

The date in iso format when the user unlocked this Battle Pass.

can_purchase_with_money boolean

Indicates that this Battle Pass can be purchased via in-app purchase. This can be set in the Admin Panel.

can_purchase_with_coins boolean

Indicates that this Battle Pass can be purchased with SCILL Coins. This can be set in the Admin Panel.

BattlePass Object
{
  "battle_pass_id": "603693723277918210",
  "app_id": "597737952688570369",
  "battle_pass_name": "My Battlepass",
  "battle_pass_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_short_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_disclaimer": "Use at your own risk",
  "battle_pass_priority": 1,
  "package_sku_ios": "com.example.bp.season1",
  "package_sku_android": "com.example.bp.season1",
  "image": "season1.png",
  "image_desktop": "season1_hd.png",
  "start_date": "2020-08-17T00:00:00Z",
  "end_date": "2020-08-17T00:00:00Z",
  "read_more_link": "https://www.example.com/battle-passes/season1.html",
  "is_unlocked_incrementally": true,
  "is_active": false,
  "unlocked_at": "2020-08-26T08:51:09Z",
  "can_purchase_with_money": true,
  "can_purchase_with_coins": false
}

The BattlePassLevel object

BattlePassLevel objects allow you to quickly build Battle Passes in your game or application.

Parameters

level_id string

Unique id of this BattlePassLevel object.

app_id string

The app id

battle_pass_id string

The id of the battle pass this level belongs to

reward_amount string

In the Admin Panel you can set different types of rewards. You can also set an identifier of an in-game-item or anything you like. Use this to include the reward into your own business logic.

reward_type_name string

There are different types of rewards available. Possible values are Coins, Voucher, Money and Experience.

level_completed boolean

Indicates if this level is completed, i.e. all challenges have been completed.

level_priority number

Indicates the position of the level.

reward_claimed boolean

Indicates if this level has already be claimed.

activated_at string

The date when this level has been activated or null if it’s not activated.

challenges array

An array of BattlePassLevelChallenge objects. Please note, not all values are available from the challenge object, as battle passes handle the lifecycle of challenges.

BattlePass Object
{
  "level_id": "563006391671062538",
  "app_id": "597737952688570369",
  "battle_pass_id": "603693723277918210",
  "reward_amount": "100",
  "reward_type_name": "Coins",
  "level_completed": false,
  "level_priority": 1,
  "reward_claimed": true,
  "activated_at": "2020-11-26T08:51:09Z",
  "challenges": [
      {
      "challenge_id": "505538946732425217",
      "challenge_name": "Survive 5 battles",
      "challenge_goal": 5,
      "user_challenge_current_score": 0,
      "challenge_icon": "black-arrow",
      "challenge_icon_hd": "black-arrow-hd",
      "type": "unlock"
    }
  ]
}

The BattlepassLevelChallenge object

BattlePassLevelChallenge objects encode a single challenge within the battle pass and is derived from the Challenge object. In fact, they share the same backend, but as Battle Passes handle the livetime of the challenges, some fields are not available. BattlePassLevel has an array of these objects named challenges.

Parameters

challenge_id string

The unique id of this challenge. Every challenge is linked to a product.

challenge_name string

The name of the challenge in the language set by the language parameter.

challenge_goal integer

Indicates how many “tasks” must be completed or done to complete this challenge.

user_challenge_current_score integer

Indicates how many tasks the user already has completed. Use this in combination with challenge_goal to render a nice progress bar.

challenge_icon string

In the admin panel you can set a string representing an image. This can be a URL, but it can also be an image or texture that you have in your games asset database.

challenge_icon_hd string

This is the HD variant of the challenge icon image. If you have a game, that runs on multiple platforms that could come in handy. Otherwise just leave blank.

type string

Indicates the status of the challenge. This can be one of the following unlock: Challenge does not track anything. in-progress: Challenge is active and tracking. overtime: User did not manage to finish the challenge in time. unclaimed: The challenge has been completed but the reward has not yet been claimed. finished: The challenge has been successfully be completed and the reward has been claimed

BattlePassLevelChallenge object
{
  "challenge_id": "505538946732425217",
  "challenge_name": "Survive 5 battles",
  "challenge_goal": 5,
  "user_challenge_current_score": 0,
  "challenge_icon": "black-arrow",
  "challenge_icon_hd": "black-arrow-hd",
  "type": "unlock"
}

Retrieve available BPs

Using this endpoint you can query all available Battle Passes for the given product id. Typically this query is used to show Battle Passes the user can purchase. You can use the package_sku field to trigger the corresponding in-app purchase.

URL v1/api/battle-passes/:appId
Method GET
Authentication Access Token
Parameters

appId integer REQUIRED

The unique id of the product. The App ID is listed in the Admin Panel.

GET v1/api/battle-passes/:appId
const scill = new SCILL('12345HAHAH');
const battlePasses = await scill.getActiveBattlePasses('example-product');
The BattlePass object

The levels are not shown here to keep things readable. It’s an array of BattlePassLevel objects as shown above.

[
  {
    "battle_pass_id": "603693723277918210",
    "app_id": "597737952688570369",
    "battle_pass_name": "My Battlepass",
    "battle_pass_description": "This battle pass gives you great fun and awesome rewards.",
    "battle_pass_short_description": "This battle pass gives you great fun and awesome rewards.",
    "battle_pass_disclaimer": "Use at your own risk",
    "battle_pass_priority": 1,
    "package_sku_ios": "com.example.bp.season1",
    "package_sku_android": "com.example.bp.season1",
    "image": "season1.png",
    "image_desktop": "season1_hd.png",
    "start_date": "2020-08-17T00:00:00Z",
    "end_date": "2020-08-17T00:00:00Z",
    "read_more_link": "https://www.example.com/battle-passes/season1.html",
    "is_unlocked_incrementally": true,
    "is_active": false,
    "unlocked_at": "2020-08-26T08:51:09Z",
    "can_purchase_with_money": true,
    "can_purchase_with_coins": false
  }
]

Retrieve unlocked BPs

Using this endpoint you can query all unlocked Battle Passes for the given app id and user. Typically this query is used to show Battle Passes the user has purchased or to show the active battle passes.

URL v1/api/battle-passes/:appId/unlocked
Method GET
Authentication Access Token
Parameters

appId integer REQUIRED

The unique id of the product. The App ID is listed in the Admin Panel.

GET v1/api/battle-passes/:appId/unlocked
const scill = new SCILL('12345HAHAH');
const battlePasses = await scill.getUnlockedBattlePasses('example-product');
The BattlePass object

The levels are not shown here to keep things readable. It’s an array of BattlePassLevel objects as shown above.

[
  {
    "battle_pass_id": "603693723277918210",
    "app_id": "597737952688570369",
    "battle_pass_name": "My Battlepass",
    "battle_pass_description": "This battle pass gives you great fun and awesome rewards.",
    "battle_pass_short_description": "This battle pass gives you great fun and awesome rewards.",
    "battle_pass_disclaimer": "Use at your own risk",
    "battle_pass_priority": 1,
    "package_sku_ios": "com.example.bp.season1",
    "package_sku_android": "com.example.bp.season1",
    "image": "season1.png",
    "image_desktop": "season1_hd.png",
    "start_date": "2020-08-17T00:00:00Z",
    "end_date": "2020-08-17T00:00:00Z",
    "read_more_link": "https://www.example.com/battle-passes/season1.html",
    "is_unlocked_incrementally": true,
    "is_active": false,
    "unlocked_at": "2020-08-26T08:51:09Z",
    "can_purchase_with_money": true,
    "can_purchase_with_coins": false
  }
]

Retrieve Battle Pass

Use this endpoint to retrieve a specific battle pass. By using the access token this object is enriched with user specific additions and current status.

URL v1/battle-passes/:appId/:battlePassId
Method GET
Authentication Access Token
Parameters

appId integer REQUIRED

The unique id of the product. The product ID is listed in the Admin Panel.

battlePassId integer REQUIRED

The id of the battle pass. It’s the same as in battle_pass_id you received in earlier requests (i.e. getting all active battle passes for a product).

GET v1/api/battle-passes/:appId
const scill = new SCILL('12345HAHAH');
const battlePass = await scill.getBattlePass('example-product', '563006391554179082');
The BattlePass object
{
  "battle_pass_id": "603693723277918210",
  "app_id": "597737952688570369",
  "battle_pass_name": "My Battlepass",
  "battle_pass_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_short_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_disclaimer": "Use at your own risk",
  "battle_pass_priority": 1,
  "package_sku_ios": "com.example.bp.season1",
  "package_sku_android": "com.example.bp.season1",
  "image": "season1.png",
  "image_desktop": "season1_hd.png",
  "start_date": "2020-08-17T00:00:00Z",
  "end_date": "2020-08-17T00:00:00Z",
  "read_more_link": "https://www.example.com/battle-passes/season1.html",
  "is_unlocked_incrementally": true,
  "is_active": false,
  "unlocked_at": "2020-08-26T08:51:09Z",
  "can_purchase_with_money": true,
  "can_purchase_with_coins": false
}

Retrieve Battle Pass Levels

Use this endpoint to retrieve the battle pass levels for the specific battle pass. Battle Passes are built from levels with a specified priority (indicates the order of the levels) and contain challenges that have to be achieved before this levels reward can be claimed and the next level is unlocked

URL v1/battle-pass-levels/:appId/:battlePassId
Method GET
Authentication Access Token
Parameters

appId integer REQUIRED

The unique id of the product. The product ID is listed in the Admin Panel.

battlePassId integer REQUIRED

The id of the battle pass. It’s the same as in battle_pass_id you received in earlier requests (i.e. getting all active battle passes for a product).

Here is an example of a user interface implementing a Battle Pass (this is from the SCILL Play Desktop App):

Battle Pass implementation of SCILL Play Desktop App

Battle Pass implementation of SCILL Play Desktop App

GET v1/api/battle-pass-levels/:appId/:battlePassId
const scill = new SCILL('12345HAHAH');
const battlePassLevels = await scill.getBattlePassLevels('example-product', '563006391554179082');
The Get Battle Pass Levels Response
[
  {
    "level_id": "563006391671062538",
    "app_id": "597737952688570369",
    "battle_pass_id": "603693723277918210",
    "reward_amount": "100",
    "reward_type_name": "Coins",
    "level_completed": false,
    "level_priority": 1,
    "reward_claimed": true,
    "activated_at": "2020-11-26T08:51:09Z",
    "challenges": [
          {
        "challenge_id": "505538946732425217",
        "challenge_name": "Survive 5 battles",
        "challenge_goal": 5,
        "user_challenge_current_score": 0,
        "challenge_icon": "black-arrow",
        "challenge_icon_hd": "black-arrow-hd",
        "type": "unlock"
      }
    ]
  }
]

Unlock Battle Pass

Battle Passes are locked per default. Many games implement Battle Passes as a monetization tool. Users need to purchase the Battle Pass via In-App purchase. Use this route to unlock a specified Battle Pass for a specific user.

Please note: Selling Battle Passes and implementing payment logic is up to you. Please contact support if you need any assistance here. However, we urge you to send purchase info in the payload as this allows us to provide analytics services to you in the future.

URL v1/battle-pass/:appId/unlock/:battlePassId
Method POST
Authentication Access Token
Payload
{
  "purchase_price": 5.99,
  "purchase_currency": "EUR"
}
Parameters

appId integer REQUIRED

The unique id of the product. The product ID is listed in the Admin Panel.

battlePassId integer REQUIRED

The id of the battle pass. It’s the same as in battle_pass_id you received in earlier requests (i.e. getting all active battle passes for a product).

Payload Parameters

purchase_price number

The purchase price. Set to 0 if this was free. The idea behind this is to provide information via an Admin Panel on average purchase price and to also allow showing users purchase info in their user account.

purchase_currency string

The currency (EUR, USD, etc) of the purchase price

GET v1/api/battle-passes/:appId
const scill = new SCILL('12345HAHAH');
const response = await scill.unlockBattlePass('example-product', '563006391554179082');
The BattlePass object
{
  "battle_pass_id": "603693723277918210",
  "app_id": "597737952688570369",
  "battle_pass_name": "My Battlepass",
  "battle_pass_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_short_description": "This battle pass gives you great fun and awesome rewards.",
  "battle_pass_disclaimer": "Use at your own risk",
  "battle_pass_priority": 1,
  "package_sku_ios": "com.example.bp.season1",
  "package_sku_android": "com.example.bp.season1",
  "image": "season1.png",
  "image_desktop": "season1_hd.png",
  "start_date": "2020-08-17T00:00:00Z",
  "end_date": "2020-08-17T00:00:00Z",
  "read_more_link": "https://www.example.com/battle-passes/season1.html",
  "is_unlocked_incrementally": true,
  "is_active": false,
  "unlocked_at": "2020-08-26T08:51:09Z",
  "can_purchase_with_money": true,
  "can_purchase_with_coins": false
}

Claim level reward

In the Admin Panel you can setup a reward for every level. You need to trigger the claiming of rewards using this API. For every level you can set a webhook in the Admin Panel wich is called once a level is claimed to unlock something server-side.

URL v1/api/battle-pass-levels/:appId/claim/:levelId
Method POST
Authentication Access Token
Parameters

appId integer REQUIRED

The unique id of the product. The App ID is listed in the Admin Panel.

levelId integer REQUIRED

The id of the battle pass level. It’s the same as in level_id you received in earlier requests (i.e. getting all battle pass levels).

Unlocking the reward

Please note: Calling this API just marks this level’s reward to be claimed with the SCILL database. You still need to unlock the actual reward for the user. Use the reward_type_name and reward_amount field of the BattlePassLevel object to find out what to unlock. This is a text field in which you can enter anything. It could be a product identifier, or whatever identifies an item within your application.

You can do that in two places:

Client Side

After calling this endpoint, check the result (any HTTP status code of 2xx will indicate success). If it’s successful you can unlock the item directly in your application. This is not as secure and not recommended as this allows hackers to easily write patches to unlock stuff.

Server Side

This is much more secure, as the information which is unlocked is on the server, which is much harder to hack. If you setup a webhook for the Battle Pass in the Admin Panel the webhook will be called with the BattlePassLevel object.

POST v1/api/battle-pass-levels/:appId/:battlePassId/claim-level
const scill = new SCILL('12345HAHAH');
const battlePassLevels = await scill.getBattlePassLevels('example-product', '563006391554179082');
const claimed = await scill.claimBattlePassLevelReward('example-product', '563006391554179082', battlePassLevels[0].level_id);
if (claimed) {
  // You could now unlock an item in the client and/or unlock the next level (if any)
}
Claim Level Reward Response
{
  "message":"OK",
  "status":200
}

Activate level

The first battle pass level is unlocked by default, subsequent levels are unlocked automatically if the is_unlocked_incrementally is set to true. Otherwise you must be activate levels by calling this API.

URL v1/api/battle-pass-levels/:battlePassId/activate/:levelId
Method POST
Authentication Access Token
Parameters

bpid integer REQUIRED

The id of the battle pass. It’s the same as in battle_pass_id you received in earlier requests (i.e. getting all active battle passes for a product).

levelId integer REQUIRED

The id of the battle pass level. It’s the same as in level_id you received in earlier requests (i.e. getting all battle pass levels).

POST v1/api/battle-pass-levels/:battlePassId/activate/:levelId
const scill = new SCILL('12345HAHAH');
const battlePassLevels = await scill.getBattlePassLevels('example-product', '563006391554179082');
const activated = await scill.activateBattlePassLevel('example-product', '563006391554179082', battlePassLevels[0].level_id);
if (activated) {
  // Level activated
}
Activate Level Response
{
  "message":"OK",
  "status":200
}

Webhooks

In the Admin Panel, you can setup various Webhooks that are called by our backend whenever the battle pass (for a specific user) or a challenge within the battle pass changes. This way, you can quickly add business logic on your side.

The SCILL backend will request your Webhook whenever a user activated challenge changes:

  • Webhook is called via POST
  • Your Webhook URL must be served via HTTPS and needs to have a valid certificate
  • Data is sent as application/json
  • Secret key is added to your URL via GET parameter secret_key
  • Your Webhook must return a response with HTTP status code 200.
  • If your Webhook does not return a response or with an error code (4xx, 5xx) the SCILL backend will retry sending the Webhook.
Please note

Please note: In the Admin Panel you set up a shared secret that is sent with every webhook request as GET-Parameter secret_key.

  • Check the shared secret in your web hook and return a 403 error if its not ok, otherwise return a response with HTTP code 200.
  • Keep this secret secure. It allows everyone to trigger your webhooks without permission

battlepass-challenge-changed

Use this Webhook if you want your backend to be triggered whenever a challenge within a battle pass level changes, i.e.

  • The counter changes
  • The type of the challenge changes (i.e. is finished, gets activated)

webhook_type string

The type of the notification. If you receive this payload, it’s most likely battlepass-challenge-changed

old_battle_pass_challenge BattlePassChallengeState

This object stores information about a battle pass challenge state. It is designed to update challenges loaded previously with the getBattlePassLevels API. Indices allow you to quickly update locally stored Challenge objects without iterating or reloading data.

new_battle_pass_challenge BattlePassChallengeState

This object stores information about a battle pass challenge state. It is designed to update challenges loaded previously with the getBattlePassLevels API. Indices allow you to quickly update locally stored Challenge objects without iterating or reloading data.

You can either use the new_battle_pass_challenge object to update your local instance of a challenge directly, you can use the Webhook to reload the challenges via REST-API or you can also compare the old state and the new state to figure out what has changed.

Typical usage patterns are:

  • Compare user_challenge_current_score from old and new object to learn if the challenge status progressed
  • Compare type from old and new object to learn if the challenge type changed (i.e. if it got unlocked, activated, canceled or claimed)

Please note: You should always compare the old and the new value to decide what to do in your business logic. As requests are sent asynchronously your backend might not necessarily be called in the “correct” order. I.e. This is especially true for claiming a challenge. The example below shows how to implement it correctly.

Processing data from Webhook
webSocket.onmessage = function (event) {
console.log('Received Webhook', event.data);
const data = JSON.parse(event.data);
if (data) {
  if (data.new_battle_pass_challenge.user_challenge_current_score !== data.old_battle_pass_challenge.user_challenge_current_score) {
    // The challenge made progress
  } else if (data.new_battle_pass_challenge.type !== data.old_battle_pass_challenge.type) {
    if (data.new_battle_pass_challenge.type === 'finished' && data.old_battle_pass_challenge.type !== 'finished') {
      // This challenge got claimed, give reward to user
    } else {
      // Challenge action (got unlocked, activated, claimed, etc)
    }
  }
}

Another way of handling the Webhook result is by implementing an object compare function that will diff the two objects and will return an object just containing the differences. A very good example on how to do that is provided in this blog post: Getting the differences between two objects with vanilla JS.

Data sent to Webhook
{
  "webhook_type": "battlepass-challenge-changed",
  "old_battle_pass_challenge":   {
    "app_id": "597737952688570369",
    "battle_pass_id": "603693723277918210",
    "level_id": "563006391671062538",
    "user_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "level_position_index": 0,
    "challenge_id": "505538946732425217",
    "challenge_position_index": 1,
    "challenge_goal": 5,
    "user_challenge_current_score": 0,
    "type": "unlock"
  },
  "new_battle_pass_challenge":   {
    "app_id": "597737952688570369",
    "battle_pass_id": "603693723277918210",
    "level_id": "563006391671062538",
    "user_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "level_position_index": 0,
    "challenge_id": "505538946732425217",
    "challenge_position_index": 1,
    "challenge_goal": 5,
    "user_challenge_current_score": 0,
    "type": "unlock"
  }
}

battlepass-level-reward-claimed

Use this Webhook if you want your backend to be triggered whenever a reward of a competed level is claimed by the user. You need to implement business logic to unlock that reward to the provided user.

webhook_type string

The type of the notification. If you receive this payload, it’s most likely battlepass-level-reward-claimed

battle_pass_level_reward_claimed BattlePassLevelReward

This objects holds information about a battle pass reward

Data sent to Webhook
{
  "webhook_type": "battlepass-level-reward-claimed",
  "battle_pass_level_reward_claimed":   {
    "app_id": "597737952688570369",
    "battle_pass_id": "603693723277918210",
    "level_id": "563006391671062538",
    "user_id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
    "level_position_index": 0,
    "reward_amount": "100",
    "reward_type_name": "Coins"
  }
}

battlepass-expired

Use this Webhook if you want your backend to be triggered whenever a battle pass expires. Battle passes have a start and an end. You can use that trigger to implement business logic to reward all users that have managed to complete the battle pass.

webhook_type string

The type of the notification. If you receive this payload, it’s most likely battlepass-expired

old_battle_pass BattlePassState

This object holds some basic info about lifetime of a battle pass and is used in expired notifications.

new_battle_pass BattlePassState

This object holds some basic info about lifetime of a battle pass and is used in expired notifications.

Data sent to Webhook
{
  "webhook_type": "battlepass-expired",
  "old_battle_pass":   {
    "battle_pass_id": "603693723277918210",
    "app_id": "597737952688570369",
    "battle_pass_priority": 1,
    "start_date": "2020-08-17T00:00:00Z",
    "end_date": "2020-08-17T00:00:00Z",
    "is_active": false
  },
  "new_battle_pass":   {
    "battle_pass_id": "603693723277918210",
    "app_id": "597737952688570369",
    "battle_pass_priority": 1,
    "start_date": "2020-08-17T00:00:00Z",
    "end_date": "2020-08-17T00:00:00Z",
    "is_active": false
  }
}