Admin Panel

Authentication

The SCILL API uses API Keys to authenticate requests. API keys can be generated in the SCILL Admin Panel and are linked to a specific product that you also create in the Admin Panel.

The API-Keys carry many privileges and are directly linked to your account, so make sure that you keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.

Authentication to the API is implemented via bearer auth by using this header:
Authorization: Bearer [API-KEY/Access-Token]

Base URL

https://us.scill.4players.io

Your API-Key

A sample key is included in all examples to get you started quickly.

To test requests with your own product account, replace the API-Key with your own key you received after creating a product in the SCILL Admin Panel.

User IDs

Within this document we often refer to “User IDs”. As this platform does not know anything (personal) about your users we need to make sure that events you send for a user to drive our services can be linked to the same user using your application.

We also need to make sure that nobody can hack the system to query data for other users. If you have users, you will have a secure system to authorize them, and you will have some sort of a unique ID to identify them. You can either send this user ID alongside events and when creating the access token (see below), or you can even create a special user ID for SCILL that you store with your user data to make things even more secure.

SCILL just stores those User IDs in access tokens.

Access Tokens

Some endpoints require an access token. This is required if your client (i.e. JavaScript in a website or a game client) directly communicates with the SCILL backend. In these unsecure areas, hackers could extract your API-Key and use it to hack or manipulate their state within your application (faking challenge progress for example). To prevent this, your client asks your backend to generate an access token which then uses an API based SCILL backend to create and sign the access token. In subsequent calls to client APIs you just send the access token instead of the API key to securely identify the user and your game.

The process looks like this:

Getting an access token

Getting an access token

This is the flow - you only have to do that once per user session and store the access token somewhere to reuse it whenever your client calls a request that requires an access token.

  1. Your app calls your own backend and sends a session token
  2. Your backend extracts a user ID from the session (at one’s own discretion) and requests SCILL backend with API-Key and user ID to generate an access token
  3. SCILL backend encodes an access token (encoding app and user) and returns it
  4. Your backend returns that access token as a response to the initial client request
  5. Your client stores the access token somewhere and uses it in the header (Authorization: Bearer [Access-Token]) or as a parameter to SCILL SDK calls.
Generate Access Token

Use this endpoint to generate the access token:

URL api/v1/auth/access-token
Method POST
Authentication API Key
Payload
{
  "user_id": "[USERID]"
}
Parameters

USERID string REQUIRED

This is the user ID you also use for sending events and which you can use to identify your user later. Instead of sending the “real” user IDs, you can also generate a special user ID (or encrypt it) for SCILL. However, as we’ll send you back this user ID in Webhooks you must be able to find the corresponding user if you receive this ID.

Generate Auth Response
{
  "token": "eyJhbGciOiJIUzI1NiIsInR59...."
}
Please note

Please note: This is the general documentation of what’s going on behind the scenes, and depending on your use case you will need to implement specific parts.

We have already prepared backend code for you for most common use cases like Steam Games and games built on PlayFab.

More info on that can be found in our Getting Started Guides.

PlayFab Cloud Function
// This function generates a SCILL access token for the current PlayFab user.
// More info can be found here: https://developers.scillgame.com/api/authentication.html
handlers.generateSCILLAccessToken = function (args, context) {
   // Set your API Key created in the SCILL Admin Panel
   var scillApiKey = "ai728S-1aSdgb9GP#R]Po[P!1Z(HSSTpdULDMUAlYX";

   var headers = {
      "Authorization": "Bearer " + scillApiKey
   };

   // Provide the current playfab id as the user_id. Please make sure to use the
   // same user_id when sending events from the backend and use the generated
   // access token on client side
   var body = {
      user_id: currentPlayerId
   };

   // Prepare request to SCILL cloud
   var url = "https://us.scill.4players.io/api/v1/auth/access-token";
   var content = JSON.stringify(body);
   var httpMethod = "post";
   var contentType = "application/json";

   // The pre-defined http object makes synchronous HTTP requests to SCILL cloud
   var response = http.request(url, httpMethod, content, contentType, headers);
   var parsedData = JSON.parse(response);

   // Return the access token as a string
   return parsedData.token;
};
No example code available for C#
Get Access Token in Client (Unity C# example)
// The default SCILLManager implementation creates access token in client - which is not recommended for production
public class MySCILLManager : SCILLManager {
   // Override SCILLManager class with custom implementation
   public override IPromise<string> GenerateAccessToken(string userId)
       // Execute cloud script created earlier and either return access token or error   
       PlayFabClientAPI.ExecuteCloudScript(new ExecuteCloudScriptRequest()
       {
           FunctionName = "generateSCILLAccessToken", // name of function created in PlayFab cloud
           GeneratePlayStreamEvent = true
       }, 
       (ExecuteCloudScriptResult result) => 
       {
            // Return the access token returned by the cloud function back to the SCILLManager to set up everything
            return Promise<string>.Resolved(result.FunctionResult);
       }, 
       (PlayFabError error) => 
       {
            return Promise<string>.Rejected(error.errorMessage);
       });
   }
}

Lifetime of Access Tokens

Access token expire after 24 hours. You may not store access tokens to any form of persistent storage. You must also make sure, that you check responses of REST-API calls for their HTTP Status Code. If status code returned is 403 the access token is not valid anymore, and you need to generate a new one before trying calling the same REST-API function again.

As you also have a rate limit alongside the event limit we’d suggest that you don’t generate a new access token with every REST-API call but rather caching them. However, in this case you need to make sure the token does not expire.

To prevent that, best place to generate/update access tokens is in either of these events:

  • App is started
  • App is activated from background
  • App/Game came back from stand-by, hibernate.

To prevent any issues for games/apps that tend to run without interruption for more than 24 hours, you can also just create an interval of 8 hours to generate new access tokens.

Setting User Data

Most functionality provided by SCILL works fine by a single user id. However, some services might require some more info about your users, especially Leaderboards as those typically contain the user’s username or name, and an avatar image.

You can use this endpoint to set these data for your users.

Warning

Don’t store any personal data listed in the GDPR rules like the real name of a user. This would require you to report this data back to your users if they request their personal data, and also requires you to delete the data using our REST-APIs whenever a user asks for his data to be deleted.

URL api/v1/auth/user-additional-info
Method PUT
Authentication Access Token
Payload
{	
	"username": "[USERNAME]",
	"avatarImage": "[AVATAR_IMAGE]"
}
Parameters

USERNAME string OPTIONAL

The username of the user provided with the access token. It should not be any personal data (GDPR definition).

AVATAR_IMAGE string OPTIONAL

This can be any string, and it’s either a string pointing to sprite assets in your game, if you have a predefined list of avatars, or it can also be a URL. Please note: Today, SCILL does not offer any Avatar storage services. Use this field to reference an avatar image in your application (usually via the URL where the avatar is stored).

Info

This payload will be added to the LeaderboardRanking object and can be used to render usernames and avatar images in leaderboard tables.

Set User Info
const scill = require('@scillgame/scill-js')
// Set the access token you generated for the user before
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.setUserInfo({
  username: 'NoName',
  avatarImage: 'Cat123'
}).then(userInfo => {
    // userInfo is the object you provided
});
// Please read Authentication documentation on how to get an access token
var scillClient = new SCILLClient(accessToken, "__YOUR_APP_ID__");

var userInfo = new UserInfo("NoName", "Cat123");
var result = scillClient.SetUserInfo(userInfo);
if (result)
{
	// Success, data is set and result is a UserInfo object with the current data stored for the user
}
The Response is the object you provided
{
   "username": "[USERNAME]",
   "avatarImage": "[AVATAR_IMAGE]"
}

Getting User Data

Most functionality provided by SCILL works fine by a single user ID. However, some services might require some more info about your users, especially Leaderboards as those typically contain the users username or name, and an avatar image.

You can use this endpoint to get these data for your user.

Warning

Don’t store any personal data listed in the GDPR rules like the real name of a user. This would require you to report this data back to your users if they request their personal data and also requires you to delete the data using our REST-APIs whenever a user asks for his deleted to be deleted.

URL api/v1/auth/user-additional-info
Method GET
Authentication Access Token
Get User Info
const scill = require('@scillgame/scill-js')
// Set the access token you generated for the user before
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserInfo().then(userInfo => {
  // userInfo is the object you provided
  if (avatarImage) {
    document.getElementByClassName('avatar-image').setAttribute('src', userInfo.avatarImage);
  }
});
// Please read Authentication documentation on how to get an access token
var scillClient = new SCILLClient(accessToken, "__YOUR_APP_ID__");

var userInfo = scillClient.GetUserInfo();
if (userInfo)
{
	// Success, load avatar sprite image in Unity
	var sprite = Resources.Load<Sprite>("Avatars/" + userInfo.avatarImage);
	if (sprite)
	{
	    // Set the avatar sprite to some Unity.UI.Image;
	    this.image.sprite = sprite;
	}
}
The Response is a UserInfo object
{
   "username": "[USERNAME]",
   "avatarImage": "[AVATAR_IMAGE]"
}

Realtime Challenges

Use this endpoint to generate a topic for our MQTT server. Subscribe to that topic to get realtime updates whenever a challenge changes in the backend for this user.

URL api/v1/auth/user-challenges-topic-link
Method GET
Authentication Access Token

More info on how to use the topic in our Realtime Updates section of the API reference documentation.

GET api/v1/auth/user-challenges-topic-link
const scill = require('@scillgame/scill-js')
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserChallengesNotificationTopic().then(notificationTopic => {
  // Get the notification topic and subscribe via MQTT on this to receive updates  
});
The Response
{
  "topic":"21666d85fe0e746f96bb9a..."
}

Single Realtime Challenge

Use this endpoint to generate a topic for our MQTT server. Subscribe to that topic to get realtime updates whenever this specific challenge changes in the backend for this user.

URL api/v1/auth/user-challenge-topic-link?challenge_id=CHALLENGE_ID
Method GET
Authentication Access Token
Parameters

CHALLENGE_ID string REQUIRED

This is the challenge_id of the Challenge. Use this to set the ID of the challenge to get updates for.

More info on how to use the topic in our Realtime Updates section of the API reference documentation.

GET api/v1/auth/user-challenge-topic-link
const scill = require('@scillgame/scill-js')
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserChallengeNotificationTopic(challengeID).then(notificationTopic => {
  // Get the notification topic and subscribe via MQTT on this to receive updates  
});
The Response
{
  "topic":"21666d85fe0e746f96bb9a..."
}

Realtime Battle Passes

Use this endpoint to generate a topic for our MQTT server. Subscribe to that topic to get realtime updates whenever a challenge in a battle pass changes in the backend.

URL api/v1/auth/user-battle-pass-topic-link?battle_pass_id=BATTLE_PASS_ID
Method GET
Authentication Access Token
Parameters

BATTLE_PASS_ID string REQUIRED

This is the battle_pass_id of the BattlePass. Use this to set the ID of the battle pass to get general updates for it.

More info on how to use the topic in our Realtime Updates section of the API reference documentation.

GET api/v1/auth/user-battle-pass-topic-link
const scill = require('@scillgame/scill-js')
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserBattlePassNotificationTopic(battlePassID).then(notificationTopic => {
  // Get the notification topic and subscribe via MQTT on this to receive updates  
});
The Response
{
  "topic":"21666d85fe0e746f96bb9a..."
}

Realtime User Battle Pass

Use this endpoint to generate a topic for our MQTT server. Subscribe to that topic to get realtime updates whenever a challenge in a battle pass changes in the backend for this user.

URL api/v1/auth/user-battle-pass-topic-link?battle_pass_id=BATTLE_PASS_ID
Method GET
Authentication Access Token
Parameters

BATTLE_PASS_ID string REQUIRED

This is the battle_pass_id of the BattlePass. Use this to set the ID of the battle pass to get updates for.

More info on how to use the topic in our Realtime Updates section of the API reference documentation.

GET api/v1/auth/user-battle-pass-topic-link
const scill = require('@scillgame/scill-js')
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserBattlePassNotificationTopic(battlePassID).then(notificationTopic => {
  // Get the notification topic and subscribe via MQTT on this to receive updates  
});
The Response
{
  "topic":"21666d85fe0e746f96bb9a..."
}

Realtime Leaderboard

Use this endpoint to generate a topic for our MQTT server. Subscribe to that topic to get realtime updates whenever ranking in the leaderboard changes.

URL api/v1/auth/leaderboard-topic-link?leaderboard_id=LEADERBOARD_ID
Method GET
Authentication Access Token
Parameters

LEADERBOARD_ID string REQUIRED

This is the leaderboard_id of the Leaderboard. Use this to set the ID of the leaderboard to get updates for.

More info on how to use the topic in our Realtime Updates section of the API reference documentation.

GET api/v1/auth/leaderboard-topic-link?leaderboard_id=12345678
const scill = require('@scillgame/scill-js')
const accessToken = getAccessToken();
const authApi = scill.getAuthApi(accessToken);
authApi.getUserBattlePassNotificationTopic(leaderboardID).then(notificationTopic => {
  // Get the notification topic and subscribe via MQTT on this to receive updates  
});
The Response
{
  "topic":"21666d85fe0e746f96bb9a..."
}