ClanOfTheCloud is a Mobile Gaming Backend as a Service (Baas) Company. You can create an account on our website, and try us with your next social game! We’re scalable, multiplateform and we offer a full API.
The Sandbox servers are:
And the production servers are:
Each of these servers are load balancers… But if one of them goes down, you can failover to another load balancer.
Once you’ve created an account, you can provision a Game in the FrontOffice application in either sandbox or production mode. We’re using a classic APIKEY / APISECRET couple to authenticate all requests.
Every request should have two headers set with your game credentials :
| Header | Value |
|---|---|
| x-apikey | Your API key |
| x-apisecret | Your API secret |
After login has been called, HTTP Basic Authentication will be used to authenticate every request.
The 3 authentication headers will look like :
| Header | Value |
|---|---|
| x-apikey | Your API key |
| x-apisecret | Your API secret |
| Authorization | Basic gamer_id:gamer_secret (base64 encoded) |
Both gamer_id and gamer_secret are returned by /v1/gamer/login.
Note: It is your responsibility to store these to help the user log in later (in RAW mode).
In addition to the App Authentication above, gamers are authenticated too. Before playing, the gamer needs an identity… Login provides such an identity.
The login route is used to authenticate a gamer, and get basic profile information about him.
Note: If an existing gamer can’t be found, a new one is created and returned.
Login for authenticated gamers will use one of these authentication methods :
Facebook Connect: use the ID and the oauth token from Facebook
Google+ Sign-in: use the ID and the oauth token from Google+
anonymous: use the gamer_id and the gamer_secret from a previous login
A JSON object must be sent in the request body with the following structure.
| Field | Description | Value |
|---|---|---|
| network | string, required | can be one of ["anonymous", "facebook", “google”] |
| id | string, required | the user ID for this network |
| secret | string, required | the user secret/token for this network |
Note: If a new gamer was created, the response code is 201, 200 otherwise.
The response is a JSON object.
| Field | Description | Value |
|---|---|---|
| gamer_id | string | user_id used in basic authentication for gamer authenticated requests |
| gamer_secret | string | secret used in basic authentication for gamer authenticated requests |
| profile | json | gamer’s profile, including "name", "email", "nickname", … |
| vfs | json | list of key/value associated to the app/game |
| gamervfs | json | list of key/value associated to the gamer |
| matches | json | array of match currently in open state of the gamer |
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
{
"network": "facebook",
"id" : "1000001010",
"secret" : "CAAIoRjU6xxYBAAy5Ymu...7XAehrcVQBUOG7oBVNatEUZD"
}
200ShowHideContent-Type: application/json; charset=utf-8
{
"gamer_id" : "dfg54g2dfg54sqdf32wfds54fqdf",
"gamer_secret" : "dsfg5dgfs654ezrt321ds31gdfs654ert",
"profile" : {},
"vfs" : {},
"gamervfs" : {}
}
Content-Type: application/json
x-apikey: INVALID KEY
x-apisecret: INVALID SECRET
{
"network": "facebook",
"id" : "1000001010",
"secret" : "CAAIoRjU6xxYBAAy5Ymu...7XAehrcVQBUOG7oBVNatEUZD"
}
401ShowHideContent-Type: application/json; charset=utf-8
{
"code" : "Unauthorized",
"message" : "Invalid App Credentials"
}
The login/anonymous route is used to create a new gamer without any informations.
Note: same response as for login route.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
200ShowHideContent-Type: application/json; charset=utf-8
{
"gamer_id" : "dfg54g2dfg54sqdf32wfds54fqdf",
"gamer_secret" : "dsfg5dgfs654ezrt321ds31gdfs654ert",
"profile" : {},
"vfs" : {},
"gamervfs" : {}
}
Content-Type: application/json
x-apikey: INVALID KEY
x-apisecret: INVALID SECRET
401ShowHideContent-Type: application/json; charset=utf-8
{
"code" : "Unauthorized",
"message" : "Invalid App Credentials"
}
Log a gamer out
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json; charset=utf-8
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic INVALID GAMER IDENTITY
401ShowHideContent-Type: application/json; charset=utf-8
{
"code" : "Unauthorized",
"message" : "Invalid Gamer Credentials"
}
Content-Type: application/json
x-apikey: INVALID API KEY
x-apisecret: INVALID API SECRET
Authorization: Basic gamer_id:gamer_secret
401ShowHideContent-Type: application/json; charset=utf-8
{
"code" : "Unauthorized",
"message" : "Invalid App Credentials"
}
Used to unlink a user account from Facebook or Google+ credentials.
Profile are data related to the user (globally)
Fields can be added one be one, data are merged. The following fields can be set : ["displayName", "lang", "firstName", "lastName", "addr1", "addr2", "addr3", “avatar”]
note : avatar must be an URL, lang is the ISO-639-1 country code (http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
i.e when executing POST /v1/gamer/profile {"displayName": "Wonder Mike"} if the current profile is “profile” : { “email” : “michael@cotc.com” } then the result will be “profile” : { "displayName": "Wonder Mike", “email” : “michael@cotc.com” }
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"displayName": "Wonder Mike"
}
200ShowHideContent-Type: application/json; charset=utf-8
{
"profile" : {
"displayName": "Wonder Mike",
"email" : "michael@cotc.com"
},
"updated" : true
}
string (required) the value to match with
number (optional) Default: 10 number of desired responses
number (optional) Default: 0 skip the skip firsts responses
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"count" : 10,
"result" : [
{
"gamer_id" : "dfg54g2dfg54sqdf32wfds54fqdf",
"profile" : {}
}
]
}
string (required) the id to check
string (required) the network on which to search "facebook", “google”
string (required) the id in the network referential to check
Gamer VFS is a key-value store you can use to associate data with a user.
Use it to store state, preferences… any data your user would like to share among devices.
Because you might want to share Gamer VFS data between games you (or other companies) wrote, you can define so called “domains” which protect your data and let use share it securely.
A Domain is a namespace, but you must know the Domain-Key for this domain to have access to it. So to share data stored in a domain, you just have to share the Domain-Key.
Your game has its own private Domain (see in FrontOffice dashboard) which you probably don’t want to share but you can create other domains to share data between apps, or even between app-developers.
Key not found … the specified key doesn’t exist
Domain not found … the specified domain doesn’t exist
string (required) Example: privatethe domain where to retreive the key/value
string (optional) the desired key, if omited all keys and values of the domains will be returned
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"key" : "data which could be a json"
}
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"key1" : "any json value, object, array for key1",
"key2" : "any json value, object, array for key2",
"key3" : "any json value, object, array for key3",
"key4" : "any json value, object, array for key4"
}
401ShowHideContent-Type: application/json
{
"code" : "Unauthorized",
"message" : "the gamer token is no longer available, call login again!",
"data" : "optional error data"
}
404ShowHideContent-Type: application/json
{
"code" : "Key not found",
"message" : "the specified key is not found"
"data" : "optional error data"
}
You can store data easily. Simply send the data to be stored, as a JSON object, in the body of the request. Note that simple strings are not allowed. Arrays and objects are.
if the key doesn’t exist, it’s dynamically created
You can opt to store your data in Amazon S3 storage. It’s the recommended option for values weighting more than 100ko.
With the binary option, the API will reply with two URLs: one to upload the file to, and the other with the URL to access the value on the internet.
So uploading a binary value becomes a two steps process:
first call PUT to pre-authorize storage,
then upload the contents directly to Amazon S3’s preauthorized URL.
calling GET will then return the URL of the value on Amazon S3.
string (required) Example: privatethe domain where to store the key/value
string (required) the desired key
string (optional) use S3 storage
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{"whatever": "your JSON value"}
200ShowHideContent-Type: application/json
{"done": 1}
401ShowHideContent-Type: application/json
{
"code" : "Unauthorized",
"message" : "the gamer token is no longer available, call signin!",
"data" : "optional error data"
}
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"done": 1,
"getURL": url,
"putURL": url
}
NOTE : we can't yet distinguish a missing key from an incorrect domain...
Key not found … the specified key doesn’t exist
Domain not found … the specified domain doesn’t exist
string (required) Example: privatethe domain from where to get the key/value
string (optional) the key to be removed (all if not specified)
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
1
401ShowHideContent-Type: application/json
{
"code" : "Unauthorized",
"message" : "the gamer token is no longer available, call signin!",
"data" : "optional error data"
}
404ShowHideContent-Type: application/json
{
"code" : "Key not found",
"message" : "the specified key is not found"
"data" : "optional error data"
}
Game VFS is a key-value store you can use to associate data with a game.
Use it to store level, booard… any data your game would like to share among users.
Key not found … the specified key doesn’t exist
Domain not found … the specified domain doesn’t exist
string (required) Example: privatethe domain where to retreive the key/value
string (optional) the desired key, if omited all keys and values of the domains will be returned
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
200ShowHideContent-Type: application/json
{
"key" : "data which could be a json"
}
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
200ShowHideContent-Type: application/json
{
"key1" : "any json value, object, array for key1",
"key2" : "any json value, object, array for key2",
"key3" : "any json value, object, array for key3",
"key4" : "any json value, object, array for key4"
}
404ShowHideContent-Type: application/json
{
"code" : "Key not found",
"message" : "the specified key is not found"
"data" : "optional error data"
}
Transactions are used to keep track of any inventory or portfolio or wallet… It’s basic functionality can be used in various contexts.
In the case of an inventory, transactions will add or remove units from it. When used as a portfolio (for virtual currency), transactions add or remove units too. And feel free to invent new uses!
Transactions/portfolios/inventories can be shared between games with domains. The private domain is private to the game but you can create other domains shared between games.
This feature can be used to share a virtual currency between all your games, or to team up with other game developers to implement cross-marketing or any incentive…
A transaction is a Hash where the key is the unit, and the value is a positive (credit) or negative (debit) amount. So a single transaction can both credit and debit different units.
string (required) Example: privateThe domain used in the transaction
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
transaction: {
"Gold": 100,
"Silver": -2.5,
"Arrows": 20
},
description: "This is an example transaction"
}
200ShowHide{
"balance": {
"Gold": 130,
"Silver": 0,
"Arrows": 20
},
"achievements": {
"achievementName": {
"type": "limit",
"config": {
"maxValue": 1000,
"unit": "score"
},
"gameData": {
"hidden": true
},
"progress": 1
}
}
}
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"transaction": { "Gold": -1000000},
"description": "Excessive transaction"
}
549Use this API to list the transactions of the current gamer. You can specify an optional
?unit=xxx parameter where xxx is the unit (Silver, Gold or Arrows in our example). If
unit is specified, the result will only contain transactions about this unit.
Use ?skip and ?limit to page through transactions.
Note: the count returned is the total number of transactions (useful whith paging)
string (required) Example: privateThe domain used in the transaction
string (optional) Example: GoldTo restrict the history to a single Unit
number (optional) Example: 30The number of rows to skip
number (optional) Example: 10The number of rows to return
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json; charset=utf-8
{ "history" : [
{ "ts": "2014-08-27T16:44:17.796Z", "tx": { "Gold": 100 }, "desc": "jsclient test" },
{ "ts": "2014-08-27T16:02:22.645Z", "tx": { "Gold": -100, "Silver": 1 }, "desc": "jsclient test" },
{ "ts": "2014-08-27T16:02:22.371Z", "tx": { "Gold": 100 }, "desc": "jsclient test" }
],
"count": 3
}
Use this API to get the current balance. It will return a Hash of each unit and the amount held by the gamer. The balance is also returned each time you create a new transaction
string (required) Example: privateThe domain used in the transaction
Properties are basic type (number, stringn boolean) json
string (required) the domain
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"Board": "river",
"Level": 20
"Expert": false
}
200ShowHideContent-Type: application/json
{
"properties" : {
"Board": "river",
"Level": 20
"Expert": false
},
"updated": true
}
string (required) the domain
string (required) the domain
Properties are used to allow match making… They are related to a game.
Properties are basic type (number, string, boolean) or array of basic type
string (required) the domain
string (required) name of the property
string (required) the domain
string (required) name of the property
string (required) the domain
string (required) name of the property
Obtains a code for sponsoring. The code is different for each game
string (required) Example: privatethe domain handling relations
Set the godfather of the current user and give a reward to the godfather.
string (required) Example: privatethe domain handling relations
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"godfather": "wSde2dF",
"maturity" : 100,
"reward" : {
transaction : { "gold" : 10},
description : "this is a reward tx",
domain : "private"
}
}
200ShowHideContent-Type: application/json
{
"done" : 1,
"balance" : {},
"achievements : {}
}
438ShowHideContent-Type: application/json
{
"code" : "alreadyGodchild"
}
Retreive the godfather of the current user.
string (required) Example: privatethe domain handling relations
Get every godchildren for the current user.
string (required) Example: privatethe domain handling relations
This is not necessarily the highest score, but only the highest is stored.
string (required) the domain used for this leaderboard
string (required) the board where the gamer score in
string (optional) Default: hightolow the order to sort the board hightolow or lowtohigh
string (optional) Default: false if true, override any previous score
string (required) the domain used for this leaderboard
string (required) the board where the gamer score in
string (optional) Default: hightolow deprecated, defaults to leaderboard’s ordering
string (optional) Default: highscore one of ["highscore", “friendscore”]
number (optional) Default: 1 th epage number or a special “me” for centered scores
number (optional) Default: 10 the max returned rows
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"<leaderboard>" : {
"page" : 2,
"maxpage" : 100,
"rankOfFirst" : 10,
scores : [
{ "gamer_id_1":
{ score : 100, info: "whatever", , timestamp : "", profile: {} }
}
{ "gamer_id_2":
{ score : 90, info: "whatever", , timestamp : "", profile: {} }
}
]
}
}
404ShowHideContent-Type: application/json
{
"code" : "LeaderboardNotFound",
}
402ShowHideContent-Type: application/json
{
"code" : "NoScoreYet",
"message" : "Asked for centered scores on a gamer who never scores"
}
string (required) the domain used for this leaderboard
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"easy" : { score:100, info : "desc" , timestamp : ""}
"meduim" : { score:20, info : "desc", timestamp : "" }
"hard" : { score:10, info : "desc", timestamp : "" }
}
Clan of the Cloud let’s you send and receive messages between gamers.
You can use this feature for inter-application messaging too, and use it to send any kind of json message.
Ordered delivery is guaranteed, and acknowledgement (or auto-acknowledgement) of each message is required.
Use this API to send a message to another user from your game. Messages are sent to a specific user, in a specific domain.
You can use domains to send messages accross games (or use private for messages sent to your game only).
Messages are always JSON objects (not strings nor binary data).
The response body will contain a copy of the message just sent, with an added id field.
string (required) Example: privateThe domain
string (required) Example: 5402cf700530df4fa7ed3629The recepient for the message
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"key": "value",
"anotherKey" : "another value",
"data" : [{
"any": "data"
}]
}
200ShowHideContent-Type: application/json
{
"id" : "5cf3baf5-742c-4c3c-ad88-d12d84b01574",
"key": "value",
"anotherKey" : "another value",
"data" : [{
"any": "data"
}]
}
This route uses long polling to deliver messages, one at a time. If more than one message was queued, you will have to call receive more than once.
Normally, you’d setup a loop to call receive and deliver messages to your game asynchronously.
Receive will block for a specified amount of time (with ?timeout=ms) or 50 seconds (the default), and will be unblocked if a message is received, or if the call times out.
When a message is received, the HTTP status code is 200. If it returns because of the timeout, the response code is 204.
To guarantee delivery, acknowledgement is necessary, but you can use automatic acknowledgement (?ack=auto).
If you want to ack messages, pass ?ack=<messageId> where messageID is the ID of the latest received message.
If you don’t specify an ?ack parameter, the message is received with no ackowledgement (to bootstrap the loop).
Choose if you want auto or acknowlegement as it can get hairy to mix both.
string (required) Example: privateThe domain
string (optional) Default: auto Example: 5cf3baf5-742c-4c3c-ad88-d12d84b01574The message ID to acknowledge
integer (optional) Default: 50000 The long polling timeout, in milliseconds
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"id" : "5cf3baf5-742c-4c3c-ad88-d12d84b01574",
"key": "value",
"anotherKey" : "another value",
"data" : [{
"any": "data"
}]
}
204Clan of the Cloud provides functionality allowing to save the progress of the player and triggering Achievements, like on most popular platforms. This system is device independent and provides the tools required to notify Clan of the Cloud from progress and querying the status of achievements.
Achievements share functionality with the Transaction system. This is because the key/value storage affected by transactions are used to trigger achievements.
Use this API to list the achievements available for your game, along with, for each of them, the progress of the gamer logged in.
string (required) Example: privateThe domain, use private to return the default achievemens created for your game in the Front Office
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"achievements": {
"highScore": {
"type": "limit",
"config": {
"maxValue": 1000,
"unit": "score"
},
"gameData": {
"initiallyHidden": true
},
"gamerData": {
"unhidden": true
},
"progress": 0.06
}
}
}
Use this API to set the custom data associated with a gamer for a given achievement. This data is associated between a gamer and an achievement, so you might for instance store data on how the achievement was performed. The whole achievement, as modified is returned.
string (required) Example: privateThe domain, use private to return the default achievemens created for your game in the Front Office
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"unhidden": true
}
200ShowHideContent-Type: application/json
{
"achievement": {
"type": "limit",
"config": {
"maxValue": 1000,
"unit": "score"
},
"gameData": {
"initiallyHidden": true
},
"gamerData": {
"unhidden": true
},
"progress": 0.06
}
}
Use this API to fetch the custom data associated with a gamer for a given achievement.
string (required) Example: privateThe domain, use private to return the default achievemens created for your game in the Front Office
Clan of the Cloud provides a simple way to run matches between a set of gamers using on the network. The match system is designed around a centralized game state stored on Clan of the Cloud servers, with gamers participating to the match making a move, updating the global game state and notifying the other players on an asynchronous basis.
This means that this match system is better suited to turn by turn game, rather than real time game such as an MMORPG, which may require a more sophisticated system handled on your servers.
As with other functionality, matches are scoped by domain, allowing to share data amongst multiple games. For more information, please take a look at the section Key-Value Store.
Creates a new match, automatically attached to your gamer ID. Only the maxPlayers node is required.
| Field | Description | Value |
|---|---|---|
| _id | string | ID of the match, keep it safe to allow for joining it or fetching it later (read only) |
| creator | string | ID of the gamer who created the game (read only) |
| customProperties | json | JSON containing the user properties of the match (only one level, with numbers or strings as values) |
| domain | string | domain to which the match belongs; used for scoping purposes (read only) |
| description | string | description of the game (non localized) |
| globalState | json | global state of the match, which may be used to reconstruct the game locally (read only) |
| lastEventId | string | ID of the last event, which must be passed by any player who wishes to make a move (read only) |
| maxPlayers | number | maximum number of players who can join this game |
| events | json | list of pending events, cleared whenever a globalState is posted along with a move by one of the players (read only) |
| players | array | list of IDs of players participating to the match (read only) |
| seed | 31-bit integer | a random number generated upon match creation, to be used by players |
| shoe | array | an array of objects that are shuffled when the match starts. You can put anything you want inside and use it as values for your next game. |
| status | string | either “running” (meaning that the match is running), either “finished” (meaning that nobody can join the match anymore) (read only) |
The response of most calls only include basic properties. To get all properties, including the global state and event list, you must either create, join or fetch a single match.
string (required) the domain on which to place the match (use private by default for a domain that is scoped for your game)
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"description": "Sample match for testing",
"maxPlayers": 3
"customProperties": {
"type": "coop"
},
"globalState": {
"startup": "globalState"
},
"shoe": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "54919c51f8d8690000fe5f6c",
"creator": {
"gamer_id": "54919c510bfa2100001bd548",
"profile": {
"displayName": "Guest",
"lang": "en"
}
},
"customProperties": {
"other": "property",
"type": "coop"
},
"description": "Sample match for testing",
"domain": "private",
"events": [],
"globalState": {},
"lastEventId": "54919c51f8d8690000fe5f6b",
"maxPlayers": 3,
"players": [
{
"gamer_id": "54919c510bfa2100001bd548",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
],
"seed": 1089745184,
"shoe":[2,3,4,1,10,9,7,6,5,8],
"status": "running"
}
}
Lists the matches available for join, using a query to filter the results.
Matches contain an user defined field named customProperties, which can be used by developers to store and fetch additional details about a game. In the example of a card-based game, one of these properties could store the minimum bet. This information could also be used to help players to join games best suited to their willing. A filter is specified as an URL-encoded JSON containing attributes and the corresponding expected value. No comparison operators are available for now, now is it possible to customize the implementation : when there are more than one attributes, all conditions specified must be met in order for the match to qualify.
The following will return the matches which have a property named type with value being "coop".
GET /v1/gamer/matches?domain=private&properties={"type": "coop"}
string (required) the domain on which to look for matches (use private by default for a domain that is scoped for your game)
string (required) a JSON string specifying the properties that need to be present in order to return a match. The JSON uses the filtering syntax as documented above.
(optional) pass this parameter to only list matches to which you are participating.
(optional) pass this to include finished matches in the result. Not recommended but can be used with the participating filter to gather info about your past games.
(optional) pass this to filter by matches to which you are currently invited. You are only marked as invited to a match until you join it.
number (optional) the maximum number of matches to return. Used for pagination. Defaults to 30.
number (optional) the index of the first item to return. Used for pagination. Zero-based, defaults to 0.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"count": 1,
"matches": [
{
"_id": "548721c15b06a5fec3315a97",
"creator": {
"gamer_id": "548721c15b06a5fec3315a95",
"profile": {
"displayName": "Guest",
"lang": "en"
}
},
"customProperties": {
"other": "property",
"type": "coop"
},
"description": "Sample match for testing",
"domain": "private",
"maxPlayers": 3,
"status": "running"
},
]
}
Fetches a given match. The response looks slightly different from that of a list of matches, but the data reported for the match is the same.
string (required) the ID of the match as previously returned.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"match": {
"_id": "548724abfe4ce589c6f81d22",
"creator": {
"gamer_id": "548724abfe4ce589c6f81d20",
"profile": {
"displayName": "Guest",
"lang": "en"
}
},
"customProperties": {
"other": "property",
"type": "coop"
},
"description": "Sample match for testing",
"domain": "private",
"events": [],
"globalState": {},
"lastEventId": "548724ab612bff89c680e179",
"maxPlayers": 3,
"players": [
{
"gamer_id": "548724abfe4ce589c6f81d20",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
],
"status": "running"
}
}
404ShowHideContent-Type: application/json
{
"name": "InvalidMatch",
"message": "The match does not exist",
"status": 404
}
Deletes a match, erasing it along with its history. You need to be the creator of the match to perform this operation.
string (required) the ID of the match to delete.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"done": 1
}
431ShowHideContent-Type: application/json
{
"name": "MatchNotFinished",
"message": "This match needs to be finished in order to perform this operation"
}
Join an existing match.
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Any player who has joined the match will automatically receive events indicating changes made to the match. These events happen when a player joins the match, leaves it or posts a move.
These events must be processed by each player prior to issuing additional commands. To do so, there is a parameter, called lastEventId that is required on some resources and must be set to the ID of the last event from the match. Among other things, this allows to detect race conditions and guarantee the integrity of the game.
This last event comes in two forms: either as a result of a match operation (in which case you can simply pick the lastEventId field within the server response) if you were the one initating it, or as the event._id field of the last received event.
In case a player joins the match, the following event will be received by other players:
{
"type": "match.join",
"event": {
"_id": "548866edba0ec600005e1941",
"match_id": "548866ed74c2e0000098db95",
"playersJoined": [
{
"gamer_id": "548866ed74c2e0000098db94",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
]
},
"id": "9155987d-6322-46d4-9403-e90ab4ba5fa3"
}
In case a player leaves the match, similarly the following event will be received by others:
{
"type": "match.leave",
"event": {
"_id": "548866eeba0ec600005e1948",
"match_id": "548866ed74c2e0000098db95",
"playersLeft": [
{
"gamer_id": "548866ed74c2e0000098db94",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
]
},
"id": "5007fd0a-1365-4e87-aba8-5d916731e684"
}
In case the match is marked as finished, the following event will be broadcasted to all players except the one who initiated it.
{
"type": "match.finish",
"event": {
"_id": "54784d07a0fcf2000086457d",
"finished": 1,
"match_id": "54784d07f10c190000cb96e3"
},
"id": "d2f908d1-40d8-4f73-802e-fe0086bb6cd5"
}
In case an element was drawn from the shoe, an event like this is fired:
{
"type": "match.shoedraw",
"event": {
"_id": "5492a7c7a6725f0000b59e4f",
"count": 2,
"match_id": "5492a7c6a6725f0000b59e46"
},
"id": "5e4e82c1-d728-4a4b-be40-e4abec320440"
}
Events are broadcasted in other situations, such as moves, but they are described within the related call documentation.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"osn": {"en": "I just joined!", "ja": "tadaima!"}
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "5487260cf45e5f84c7cd7225",
"creator": {
"gamer_id": "5487260cf45e5f84c7cd7223",
"profile": {
"displayName": "Guest",
"lang": "en"
}
},
"customProperties": {
"other": "property",
"type": "coop"
},
"description": "Sample match for testing",
"domain": "private",
"events": [
{
"event": {
"_id": "5487260c1d449b84c728d956",
"playersJoined": [
"5487260cf45e5f84c7cd7224"
]
},
"type": "match.join"
}
],
"globalState": {},
"lastEventId": "5487260c1d449b84c728d956",
"maxPlayers": 3,
"players": [
{
"gamer_id": "5487260cf45e5f84c7cd7223",
"profile": {
"displayName": "Guest",
"lang": "en"
}
},
{
"gamer_id": "5487260cf45e5f84c7cd7224",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
],
"seed": 1089745184,
"shoe":[2,3,4,1,10,9,7,6,5,8],
"status": "running"
}
}
404ShowHideContent-Type: application/json
{
"name": "InvalidMatch",
"message": "The match does not exist",
"status": 404
}
431ShowHideContent-Type: application/json
{
"name": "AlreadyJoinedMatch",
"message": "You are already being part of this match"
}
431ShowHideContent-Type: application/json
{
"name": "MaximumNumberOfPlayersReached",
"message": "This match can not accept any additional player"
}
433ShowHideContent-Type: application/json
{
"name": "BadMatchID",
"message": "This match does not exist or is not active"
}
Leave a match. This only works if you are currently part of the match, or you will get an HTTP 433.
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"osn": {"en": "Bye bye!", "fi": "Näkemiin!"}
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "548726461c4158b4c73d43fa",
"lastEventId": "5487264710de0db4c71fe752",
"status": "finished"
}
}
404ShowHideContent-Type: application/json
{
"name": "InvalidMatch",
"message": "The match does not exist",
"status": 404
}
433ShowHideContent-Type: application/json
{
"name": "BadMatchID",
"message": "This match does not exist or is not active"
}
Allows to invite another person to a match. Should be used with private matches. Matches can be made private by using a filter when listing matches. For instance, you may require a property to be present in the match, such as customProperties: {"public": 1} and filter out by ?properties={"public": 1} when listing the matches available. In that case, if you want to play against a given set of opponents, you may simply limit the maximum number of players, and invite each of your opponents.
When someone is invited, a message as follows will be received:
{
"type": "match.invite",
"event": {
"_id": "54784d07a0fcf2000086457d",
"match_id": "54784d07f10c190000cb96e3"
"inviter": {
"gamer_id": "5487260cf45e5f84c7cd7223",
"profile": {
"displayName": "Guest",
"lang": "en"
}
}
},
"id": "d2f908d1-40d8-4f73-802e-fe0086bb6cd9"
}
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"osn": {"en": "Please join my super duper game!", "it": "Sei invitato!"}
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "5488121cebc67955fb8f42e2",
"lastEventId": "5488121c4d95f055fbadde9a",
"status": "running"
}
}
431ShowHideContent-Type: application/json
{
"message": "The player is already invited to the match",
"name": "AlreadyInvitedToMatch"
}
433ShowHideContent-Type: application/json
{
"message": "A passed gamer ID is invalid",
"name": "BadGamerID"
}
433ShowHideContent-Type: application/json
{
"name": "BadMatchID",
"message": "This match does not exist or is not active"
}
Allows to dismiss an invitation to a match. Works for the authenticated gamer and only if the gamer has been invited previously.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideContent-Type: application/json
{
"match": {
"_id": "5488121cebc67955fb8f42e2",
"lastEventId": "5488121c4d95f055fbadde9a",
"status": "running"
}
}
433ShowHideContent-Type: application/json
{
"name": "BadMatchID",
"message": "This match does not exist or is not active"
}
Posts a move. This will notify a progress in the match. Note that the globalState is updated incrementally, according to the passed attributes. This means that attributes not passed do not get modified or deleted from the globalState stored for this game.
This only works if you are currently part of the match, or you will get an HTTP 433.
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Once a match has been started, any player currently belonging to the game is allowed to make moves. It is up to the game itself to determine which players may play and when.
However, one is only allowed to post a move if he is synchronized with the current state of the game. This is done with a parameter named lastEventId. Every move made by one of the players, this value changes and is returned in the message posted to the other players. The next player must post this value along with his next move, else he will receive an error indicating that he needs to be resynchronized.
A move is made of a move object (which is basically freeform, and represents a message that will be sent to other players indicating what changed) and an optional game state labelled globalState. A global game state sould be enough for any player who joins the game to restore the game locally. Thus, when a global state is posted, the list of moves is cleared on the server: only the moves made since the last global state are kept and posted to people who join the game. As such, one can reconstruct the current game by starting from the global state and applying the pending moves.
When a move is posted, all players get notified in the form of an event, looking as follows:
{
"type": "match.move",
"event": {
"_id": "54784176a8df72000049340e",
"player_id": "547841755e4cfe0000bf6907",
"move": {
"what": "changed"
}
},
"id": "d0fb71c1-3cd0-4bbd-a9ec-29cb46cf9203"
}
Important thing: the globalState node only includes what has changed, not the whole global state of the match.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"move": {
"what": "changed"
},
"globalState": {
"full": "game_state"
},
"osn": {"en": "It is now your turn!", "de": "Spielen Sie jetzt!"}
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "548726461c4158b4c73d43fa",
"lastEventId": "5487264710de0db4c71fe752",
"status": "finished"
}
}
400ShowHideContent-Type: application/json
{
"name": "MissingParameter",
"message": "The parameter is invalid or absent: lastEventId",
"status": 400
}
431ShowHideContent-Type: application/json
{
"name": "InvalidLastMoveId",
"message": "This move ID is invalid, please resynchronize"
}
Draws an element from the shoe. Works if an array has been posted as shoe when creating the match.
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Along with the seed element that is returned with the detailed version of the match (i.e. when joining or fetching it), the shoe is another element that helps building random generator-based games.
A shoe, as in Casino, is basically a container of possible values that are returned in a random order as they are poked. It could represent the values of the cards for instance. It is possible to have more than once the same element in the shoe (as when having two card sets). The shoe is posted by the person who creates the game and then shuffled. The shoe will remain hidden, with no one having access to it, until the match is finished.
Players can draw one or more elements off the shoe by posting a request to this resource. The shoe is shared with all players, meaning that any element from the shoe is returned only once to a player having requested it.
When all items have been drawn from the shoe and more items are requested, the existing serie is duplicated, shuffled and appended to the current shoe, meaning an endless play can be considered.
Drawing items from the shoe will trigger one event of type match.shoedraw per request, sent to players except the caller. When the match finishes, fetching detailed info about the match will return the shoe. It can be used by all players to check that the game has been fair: should one player have hacked the game, it is possible to detect it by comparing the shoe to the actual moves.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"osn": {"en": "I just drew something from the shoe!", "fr": "J'ai récupéré un objet du sabot!"}
}
200ShowHideContent-Type: application/json
{
"drawnItems": [
{
"prop4": "value4"
},
{
"prop3": "value3"
}
],
"match": {
"_id": "5492a7c6a6725f0000b59e46",
"lastEventId": "5492a7c7a6725f0000b59e4f",
"status": "running"
}
}
400ShowHideContent-Type: application/json
{
"name": "MissingParameter",
"message": "The parameter is invalid or absent: count",
"status": 400
}
431ShowHideContent-Type: application/json
{
"name": "InvalidLastMoveId",
"message": "This move ID is invalid, please resynchronize"
}
Marks a match as finished, meaning that no other player will be able to join, post moves or even leave the match: consider it frozen and “archived” after this operation. This only works if you are currently part of the match, or you will get an HTTP 433.
A field named osn can be passed as shown in the sample request to send a push notification to the users who are not active at the moment.
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
{
"osn": {"en": "The match is finished.", "es": "El partido ha terminado."}
}
200ShowHideContent-Type: application/json
{
"match": {
"_id": "548726461c4158b4c73d43fa",
"lastEventId": "5487264710de0db4c71fe752",
"status": "finished"
}
}
404ShowHideContent-Type: application/json
{
"name": "InvalidMatch",
"message": "The match does not exist",
"status": 404
}
433ShowHideContent-Type: application/json
{
"name": "BadMatchID",
"message": "This match does not exist or is not active"
}
If you want to search for something, you probably want to use the indexing API. You can use it to index gamers (for match making), or matches, or anything. It’s free-form, so it can apply to every use case.
It works in parallel to other APIs. For instance, you could create a match, then index it to allow searching matches. Or you could index gamer’s properties for fast retrieval.
So the API is very simple and quite generic.
*Note: * the indexing API is an unauthenticated API: you don’t have to be logged in as a user to use it. You don’t need an
Authorization HTTP header.
Use this API to add or update an object in an index. You can have as many indexes as you need: one for gamers’ properties, one for matches, one for finished matches… It only depends on what you want to search.
The Request body must have three mandatory attribues: id, properties and payload.
id is the id of the object you’re indexing. It can be a MatchId, a GamerId, or anyother unique Id.
properties is an object. It’s attributes will be indexed and searchable. These are the “indexed fields” of the object. These
properties are typed! So if age is an int, it must always be an int, or an error will be thrown upon insertion.
payload is also an object. It’s not indexed, but its contents are returned in searches.
string (required) Example: privateThe domain
string (required) Example: matchIndexThe index Name
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
{
"_id": '55706319d11b8125d58c8abe',
"properties": {
"rank": "captain",
"age": 28,
"world": "utopia"
},
"payload": {
"name": "Captain America",
"lastPlayed": 1433428652427
}
}
200ShowHideContent-Type: application/json
{ _index: 'com.clanofthecloud.cloudbuilder.m3nsd85gnqd3',
_type: 'matchIndex',
_id: '55706319d11b8125d58c8abe',
_version: 1,
created: true
}
You can search documents in the index with this API. It allows you to make complex queries.
See the Elastic documentation
to learn the full syntax for the q parameter. It’s easy and quite powerful.
You can also use the full Elastic search capabilities with full query DSL search. In this case, you’ll send a json document instead of
using the q and sort parameters. Please refer to the Elastic full-body search documentation.
string (required) Example: privateThe domain
string (required) Example: matchIndexThe index Name
string (optional) Example: rank:captainThe query string
string (optional) Example: ["age"]a JSON array of properties names for sorting
int (optional) Example: 0The first result index
int (optional) Example: 10The number of results to return
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
200ShowHideContent-Type: application/json
{ total: 1,
max_score: 1,
hits:
[ { _index: 'com.clanofthecloud.cloudbuilder.m3nsd85gnqd3',
_type: 'matchIndex',
_id: '55706319d11b8125d58c8abe',
_score: 1,
_source: {
"rank": "captain",
"age": 28,
"world": "utopia",
"payload": {
"name": "Captain America",
"lastPlayed": 1433428652427
}
}
}
]
}
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
{
"query": {
"term": {
"rank": "captain"
}
}
}
200ShowHideContent-Type: application/json
{ total: 1,
max_score: 1,
hits:
[ { _index: 'com.clanofthecloud.cloudbuilder.m3nsd85gnqd3',
_type: 'matchIndex',
_id: '55706319d11b8125d58c8abe',
_score: 1,
_source: {
"rank": "captain",
"age": 28,
"world": "utopia",
"payload": {
"name": "Captain America",
"lastPlayed": 1433428652427
}
}
}
]
}
Use this API if you want to GET a single index entry, by id. Of course, you should use the search API instead if you want to find more than one element.
string (required) Example: privateThe domain
string (required) Example: matchIndexThe index Name
string (required) Example: 55706319d11b8125d58c8abeThe object Id you’re looking for
(required) x-apikey : testgame-key
x-apisecret : testgame-secret
(required) 200ShowHideContent-Type: application/json
{ _index: 'com.clanofthecloud.cloudbuilder.m3nsd85gnqd3',
_type: 'matchIndex',
_id: '55706319d11b8125d58c8abe',
_version: 1,
found: true,
_source:
{
"rank": "captain",
"age": 28,
"world": "utopia",
"payload": {
"name": "Captain America",
"lastPlayed": 1433428652427
}
}
}
}
When you want to remove an index entry, use this API. If you just want to update an entry, just use POST instead.
string (required) Example: privateThe domain
string (required) Example: matchIndexThe index Name
string (required) Example: 55706319d11b8125d58c8abeThe object Id you’re looking for
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Generated by aglio on 28 Jun 2015
/v2.6/gamer/friends/{domain}/{?status}string(required) Example: privatethe domain handling relations
string(optional)“blacklist” to retrieve the blacklisted gamer’s
Headers
Content-Type: application/json
x-apikey: testgame-key
x-apisecret: testgame-secret
Authorization: Basic gamer_id:gamer_secret
200ShowHideHeaders
Content-Type: application/json
Body
{ "friends|blacklisted" : [ { "<gamer_id_1>" : { displayName : "gamer1", lang : "en" } }, {"<gamer_id_2>" : { displayName : "gamer2", lang : "fr" } } ] }