Rankade's API service allows all groups to enter matches, create players and retrieve rankings via API.
Several usage tiers are available.
This documentation covers all technical aspects, other info can be found in the FAQs at the end.
Using rankade's APIs requires and implies the user to agree to our terms and conditions. To use rankade's APIs, you need to:
The Dedicated tier also allows other API-based features and it is designed for users with specific needs (i.e. consumer or business users).
Success responses always return a 200
HTTP status code and contain a success object at the root of the JSON content.
GET /public/api/1/status HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "queued": 0, "waiting": 0, "added": 36, "processed": 36, "total": 36 } }
Error responses can have either 400
, 401
, 403
, 404
, 429
, or 500
as HTTP status code and always return the errors object at the root, that contains error specifications if possible.
GET /public/api/1/status HTTP/1.1 Accept: application/json Authorization: Bearer an-expired-jwt-token-here
HTTP/1.1 403 Forbidden ... { "errors": [{ "code": "A002", "message": "Authentication required" }] }
Error responses can contain one or more error specifications which consist of a code variable and a message variable, as in the example above. This can be useful for client-side error handling. The message can vary, please rely on the code to recognize errors. Messages are just a way to further specify what the problem was.
HTTP status code | Error code | Error message |
---|---|---|
500 | R001 | Generic error |
404 | R002 | Not found |
400 | R003 | Missing or invalid required parameters |
403 | A002 | Authentication required |
The access to API service has different usage limits for different subscription tiers.
The table below shows the maximum values of some parameters for each subscription tier.
The up-to-date status of your client's quotas can be checked via API (with the GET /quota
call) or via webapp.
Standard group | Plus group | Extra API group | Custom API group | Dedicated API group | |
---|---|---|---|---|---|
API calls per year | 500 | 5000 | 20000 | tbd | Contact us |
API calls per hour | 50 | 100 | 200 | tbd | |
Matches per year | 100 | 2000 | 5000 | tbd | |
Matches per day | 20 | 50 | 100 | tbd | |
Matches per hour | 10 | 20 | 50 | tbd | |
Ranking calls per year | 50 | 1000 | 5000 | tbd | |
Ranking calls per day | 20 | 50 | 200 | tbd | |
Ranking calls per hour | 10 | 25 | 50 | tbd | |
New API-created games | 2 | 10 | 20 | tbd | |
Can date API-inserted matches | No | No | No | Yes | Yes |
The type of group also affects other parameters, not directly related to APIs. Some of them are shown in the next table, you can find the complete list here.
Standard group | Plus group | Extra API group | Custom API group | Dedicated API group | |
---|---|---|---|---|---|
Registered users | Unlimited | Unlimited | Unlimited | Unlimited | Contact us |
Ghost users | 12 | 50 (*) | 50 (*) | tbd | |
Priority processing | No | Yes | Yes | Yes | Yes |
Automatic subsets | 3 | Unlimited | Unlimited | Unlimited | Unlimited |
Time based auto-subsets | No | Yes | Yes | Yes | Yes |
Custom subsets | No | 4 | 4 | tbd | tbd |
(*) this limit can be customized on request.
Upon reaching any quota limit, the API service will return a 429
HTTP status error code.
HTTP/1.1 429 Too Many Request ... { "errors": [{ "code": "Q004", "message": "Matches per hour limit has been reached" }] }
HTTP status code | Error code | Error message | What to do |
---|---|---|---|
429 | Q001 | API calls per year limit has been reached | Use webapp/app or upgrade service to higher tier. |
429 | Q002 | API calls per hour limit has been reached | Wait until the next hour or upgrade to higher tier. |
429 | Q003 | Matches per year limit has been reached | Use webapp/app or upgrade service to higher tier. |
429 | Q005 | Matches per day limit has been reached | Wait until the next day or upgrade service to higher tier. |
429 | Q004 | Matches per hour limit has been reached | Wait until the next hour or upgrade service to higher tier. |
429 | Q008 | Ranking calls per year limit has been reached | Use webapp/app or upgrade service to higher tier. |
429 | Q009 | Ranking calls per day limit has been reached | Wait until the next day or upgrade service to higher tier. |
429 | Q010 | Ranking calls per hour limit has been reached | Wait until the next hour or upgrade service to higher tier. |
429 | Q006 | API created games limit has been reached | Use webapp/app or upgrade service to higher tier. |
429 | Q007 | Ghost limit has been reached | Upgrade group and/or service to higher tier. |
Returns quota usage details in percentage for the current client.
Percentages are evaluated on the limits for your specific usage tier.
GET /public/api/1/quota HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "callsPerYear": "2%", "callsPerHour": "12%", "matchesPerYear": "3%", "matchesPerDay": "15%", "matchesPerHour": "0%", "rankingCallsPerYear": "2%", "rankingCallsPerDay": "5%", "rankingCallsPerHour": "10%", "apiCreatedGames": "1%" } }
API calls are protected by JWT tokens. Learn more about JWT in the official documentation.
Any API call must contain the Authorization
header with the JWT token.
JWT tokens expire and must be generated again by the GET /auth
API call.
... Authorization: Bearer jwt-token-here ...
Returns a valid JWT token.
Key and secret are available on the group's API page via webapp.
Name | Description | Example |
---|---|---|
key | API key | 74fa1bad104fe13306b40dde819154c99bb4e8da |
secret | API secret | D5HbfATDx8eaHATYered |
GET /public/api/1/auth?key=74fa1bad104fe13306b40dde819154c99bb4e8da&secret=D5HbfATDx8eaHATYered HTTP/1.1 Accept: application/json
HTTP/1.1 200 OK ... { "success": { "token": "jwt-token-here" } }
HTTP status code | Error code | Error message |
---|---|---|
401 | A001 | Invalid credentials or client disabled |
Returns the list of the group's players.
Name | Description | Required | Default | Example |
---|---|---|---|---|
page | Page number | No | 1 | 2 |
GET /public/api/1/players/2 HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "page": "2", "totalPages": 2, "rowsForPage": 25, "totalPlayers": 29, "data": [{ "id": "37VjKRy1a6p", "ghost": 0, "username": "Mackmansoup4585", "displayName": "Mackmansoup", "icon": "https://userscontents.rankade.com/images/256/16e4fd77ad4ead03683febd462ffe023.png" }, { "id": "zqRjGDw4gbJ", "ghost": 1, "username": "", "displayName": "*Emmephisto", "icon": "" }, { "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }, { "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" } ] } }
Create a ghost player within the group.
A ghost is a user that is not linked to an email address (see rankade FAQ for details).
Name | Description | Required | Example |
---|---|---|---|
name | Player name | Yes | Emmephisto |
POST /public/api/1/players/player HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here name=Emmephisto
HTTP/1.1 200 OK ... { "success": [{ "id": "zqRjGDw4gbJ", "ghost": 1, "username": "", "displayName": "*Emmephisto", "icon": "" }] }
HTTP status code | Error code | Error message |
---|---|---|
429 | Q007 | Ghosts limit has been reached |
Returns the list of the group's games (i.e. games with at least one match played within the group).
GET /public/api/1/games HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": [{ "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, { "id": 1335, "name": "Table Football", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_football.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_football.jpg", "bggIdGame": null } ] }
Returns the list of rankade's most popular games.
GET /public/api/1/games/popular HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": [{ "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, { "id": 1770, "name": "Foosball", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_football.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_football.jpg", "bggIdGame": null } ] }
Searches games by name.
Name | Description | Required | Example |
---|---|---|---|
name | Name of the game | Yes (2 chars min) | twilight |
GET /public/api/1/games/search?name=twilight HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": [{ "id": 962, "name": "Twilight Imperium (Third Edition)", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/thumb/img/fED6XRJVDYYOppNNmRfuU1vJr8Q=/fit-in/200x150/pic4128153.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/4bdae1da8be6ecb837d0f8567ddb100e.jpg", "bggIdGame": 12493 }, { "id": 4579, "name": "Twilight Imperium: Fourth Edition", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/thumb/img/UOV5jJadzHc6ebYd5CfZXGbOWsc=/fit-in/200x150/pic3727516.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/956d6ab81f37aef3db55d5909cf92ab8.jpg", "bggIdGame": 233078 }, { "id": 4784, "name": "Twilight Squabble", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/thumb/img/BOsJzM6uF6GdjaGd8i45xvQ_16U=/fit-in/200x150/pic2908587.png", "mediumImage": "https://userscontents.rankade.com/images/500/3f00c90fea5f03698038df48c584e799.png", "bggIdGame": 191364 }, { "id": 963, "name": "Twilight Struggle", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/thumb/img/mEmeJrI3AbGTpWyeFOZnR0s_LcY=/fit-in/200x150/pic361592.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/6f2f6d3c4ec73f443527a808a62b0261.jpg", "bggIdGame": 12333 } ] }
Creates a new game by giving its bggId (BoardGameGeek game id) or a game name.
Name | Description | Required | Example |
---|---|---|---|
bggId | BGG id of the game | Yes (either bggId or name) | 12333 |
name | Game name | Yes (either bggId or name) | A brand new game name |
POST /public/api/1/games/game HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here name=twilight struggle
HTTP/1.1 200 OK ... { "success": [{ "id": 963, "name": "Twilight Struggle", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/thumb/img/mEmeJrI3AbGTpWyeFOZnR0s_LcY=/fit-in/200x150/pic361592.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/6f2f6d3c4ec73f443527a808a62b0261.jpg", "bggIdGame": 12333 }] }
Retrieve registered and processed matches, non-processed matches will be available after processing.
Results are ordered by match number and paginated.
Name | Description | Required | Default | Example |
---|---|---|---|---|
subset | Subset id from GET /subsets |
No | main | 9dYpN0xVeR3 |
page | Page number | No | 1 | 3 |
GET /public/api/1/matches/main/1 HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "page": 2, "totalPages": 2, "rowsForPage": 25, "totalMatches": 28, "data": [{ "id": "Jowlqr5o0qA", "externalId": "", "date": "2019-12-20 10:45:00", "registrationDate": "2019-12-20 10:46:01", "number": 3, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 16, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" }, { "id": "kMAxQ8GRYOq", "externalId": "", "date": "2019-12-20 10:19:34", "registrationDate": "2019-12-20 10:20:12", "number": 2, "summary": "MackmanSoup\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "37VjKRy1a6p", "ghost": 0, "username": "Mackmansoup4585", "displayName": "Mackmansoup", "icon": "https://userscontents.rankade.com/images/256/16e4fd77ad4ead03683febd462ffe023.png" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 9, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "Weather was fine" }, { "id": "kRplW5vnYqE", "externalId": "", "date": "2019-12-20 09:34:54", "registrationDate": "2019-12-20 09:35:32", "number": 1, "summary": "Emmephisto\nMackmanSoup", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "zqRjGDw4gbJ", "ghost": 1, "username": "", "displayName": "*Emmephisto", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 19, "players": [{ "id": "37VjKRy1a6p", "ghost": 0, "username": "Mackmansoup4585", "displayName": "Mackmansoup", "icon": "https://userscontents.rankade.com/images/256/16e4fd77ad4ead03683febd462ffe023.png" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } ] } }
Retrieves API-recorded matches status.
Counts are only for matches entered via API. Matches entered via webapp/app are not included.
GET /public/api/1/matches/status HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "queued": 0, "waiting": 0, "added": 83, "processed": 83, "total": 83 } }
Status | Description |
---|---|
queued | Accepted matches, queued for insertion |
waiting | Inserted matches, waiting for their subset(s) |
added | Matches added to subset(s), both processed and not yet processed |
processed | Processed matches |
total | Total API-recorded matches |
Adds one or more matches to the group.
The request's body must contain a JSON array of objects which represent the match.
There is a hard limit of 10 matches per call; when this threshold is crossed, all matches are discarded.
Name | Description | Required | Example |
---|---|---|---|
dryrun | Use the dryrun variable to validate matches without entering them (may be useful during development). Matches will not count towards match quotas. | No | 1 |
POST /public/api/1/matches/match HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here [{ "game": 1334, "weight": "normal", "factions": [{ "rank": 2, "score": "6", "players": ["3JzgKOYgkeY"] }, { "rank": 1, "score": "9", "players": ["6qJ1AE41VZw"] }], "notes": "Weather was fine" }, { "game": 1335, "weight": "normal", "factions": [{ "rank": 1, "score": "21", "players": ["3JzgKOYgkeY"] }, { "rank": 2, "score": "18", "players": ["6qJ1AE41VZw"] }], "notes": "" }]
(when all matches are accepted)
HTTP/1.1 200 OK ... { "success": { "total": 2, "accepted": [{ "index": 0, "id": null, "name": null, "errors": [] }, { "index": 1, "id": null, "name": null, "errors": [] } ], "acceptedCount": 2, "rejected": [], "rejectedCount": 0 } }
HTTP status code | Error code | Error message |
---|---|---|
400 | M001 | Invalid JSON message in request |
Response returns a 202
HTTP status code.
HTTP/1.1 202 OK ... { "success": { "total": 2, "accepted": [{ "index": 0, "id": "wweq", "name": null, "errors": [] }], "acceptedCount": 1, "rejected": [{ "index": 1, "id": "312", "name": null, "errors": [{ "code": "M003", "message": "A match with the same external identifier was already accepted" }] }], "rejectedCount": 1 } }
The following errors will be included in the errors object of a rejected match.
Error codes never change, error messages may change.
HTTP status code | Error code | Error message |
---|---|---|
202 | M002 | JSON schema validation error |
202 | M003 | A match with the same identifier was already accepted |
202 | M004 | One or more players are not in the group |
202 | M005 | Invalid ranks |
202 | M006 | Duplicated players |
202 | M007 | Game not valid |
202 | M009 | Bot can not be in a faction with other players |
202 | M010 | Ghost player disabled (over group limit) |
202 | M011 | Date format not valid |
202 | M012 | Date range not allowed |
202 | Q003 | Matches per year limit has been reached |
202 | Q004 | Matches per hour limit has been reached |
202 | Q005 | Matches per day limit has been reached |
The JSON in the body of a POST /matches/match
request is validated against the following JSON schema.
{ "definitions": {}, "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://rankade.com/matches.json", "type": "array", "title": "Matches", "items": { "$id": "#/items", "type": "object", "title": "Match", "required": [ "game", "factions" ], "properties": { "id": { "$id": "#/items/properties/id", "type": "string", "title": "Match id", "examples": [ "24", "6a56ead1-0383-11e9-bbc1-0242ac120002", "10xyz" ] }, "name": { "$id": "#/items/properties/name", "type": "string", "title": "Match name", "examples": [ "name of the match", "default_1", "default_2" ], "pattern": "^(.*)$" }, "game": { "$id": "#/items/properties/game", "type": "integer", "title": "Match game", "examples": [ 2938 ] }, "weight": { "$id": "#/items/properties/weight", "type": "string", "title": "Match weight", "default": "normal", "examples": [ "normal" ], "pattern": "^(ultralight|light|midlight|normal|heavy|massive)$" }, "date": { "$id": "#/items/properties/date", "type": "string", "format": "date-time", "title": "Match date", "examples": [ "2019-03-21T16:44:11+01:00" ] }, "factions": { "$id": "#/items/properties/factions", "type": "array", "title": "Factions", "items": { "$id": "#/items/properties/factions/items", "type": "object", "title": "Factions item", "required": [ "rank", "players" ], "properties": { "name": { "$id": "#/items/properties/factions/items/properties/name", "type": "string", "title": "Faction name", "examples": [ "faction 1" ], "pattern": "^(.*)$" }, "rank": { "$id": "#/items/properties/factions/items/properties/rank", "type": "integer", "title": "Faction rank", "default": 1, "examples": [ 1, 2, 3 ] }, "score": { "$id": "#/items/properties/factions/items/properties/score", "type": "string", "title": "Faction score", "examples": [ 7, "42", "-12", "4.6" ] }, "players": { "$id": "#/items/properties/factions/items/properties/players", "type": "array", "title": "Players", "items": { "$id": "#/items/properties/factions/items/properties/players/items", "type": "string", "title": "Player", "default": "", "examples": [ "3JzgKOYgkeY", "nY3gzLwWa9B" ], "pattern": "^(.*)$" }, "minItems": 1, "maxItems": 50 } } }, "minItems": 2, "maxItems": 100 }, "notes": { "$id": "#/items/properties/notes", "type": "string", "title": "Notes", "examples": [ "The notes of the match" ], "pattern": "^(.*)$" } } }, "minItems": 1, "maxItems": 10 }
Name | Type | Required | Example | Description |
---|---|---|---|---|
id | string | No | 6a56ead1-0383-11e9-bbc1-0242ac120002 | Match id defined by the client. If specified, the system checks whether there's an accepted match with the same id and rejects duplicates. |
name | string | No | Alice vs Diana - semifinal | Match name. Please use default_1 to set game's name or default_2 to set faction/player name vs other faction/player name. |
game | integer | Yes | 1334 | Game id retrieved from ` GET /games/search`, `GET /games`, or `GET /games/popular` API calls. |
weight | string | Yes | normal | Match weight, chosen from this list: ultralight, light, midlight, normal, heavy, massive. A heavier game results in larger variations in ree score, a lighter game in smaller ones. We strongly suggest you to set weights in a way that most of the matches have normal weight. See FAQ for details. |
factions | array | Yes |
[{ "rank": 2, "score": "21", "players": ["3JzgKOYgkeY"] }, { "rank": 1, "score": "31", "players": ["6qJ1AE41VZw"] }] |
Factions' data. Faction object specifications are listed below. |
notes | string | No | Weather is fine, few people watching | General notes. |
date | string | No | 2019-03-21T16:44:11+01:00 | Match datetime. Available to Custom API and Dedicated API tier only. |
Factions contain players, rank, and optionally faction name and score.
A faction can contain one or more players.
Name | Type | Required | Example | Description |
---|---|---|---|---|
rank | integer | Yes | 1 | Faction rank. Please read below for more details about ranks. |
players | array | Yes | ["6qJ1aE41VZw","3JZgKOYgkeY"] |
Array of player id(s) in the faction. Players ids can be obtained from the `GET /players` API call. |
name | string | No | Red Team | Faction name. |
score | string | No | 86 | Faction score. |
The ranks of factions are expressed by positive integers between 1 (the winner faction) and the number of factions in the match (e.g. (1, 2, 3, 4) in a four-faction match).
Any tie is indicated by using the same integer for all tied factions (e.g. (1, 1, 3, 4) in a four-faction match with a two-way tie for first place).
Each faction's rank is always equal to the number of factions before it plus 1 (e.g. (1, 1, 3, 4), the third faction's rank is 3), or - in case of a tie - equal to the preceding tied faction(s) (e.g. (1, 2, 2, 4), the third faction's ranks is 2, equal to the preceding tied faction - the two factions are tied for second place).
Ranks are independent from scores (optionally) specified in the related field. Therefore, you can enter matches for games where the highest score wins, for games where the lowest score wins (e.g. golf), and for games without a numerical score.
The following table details possible inputs for different numbers of factions. Bolded sets are the most common cases.
Factions | Ranks | Details |
---|---|---|
2 | (1,2) | one faction wins, the other faction loses |
(1,1) | tie or draw | |
3 | (1,2,3) | first, second, third (ordered result) |
(1,2,2) | one winner, the other factions lose | |
(1,1,3) | tie for first place, then the third faction | |
(1,1,1) | triple tie | |
4 | (1,2,3,4) | first, second, third, fourth (ordered result) |
(1,1,1,1) | quadruple tie | |
(1,1,1,4) | triple tie for first place, then the fourth faction | |
(1,1,3,3) | tie for first place, then tie for last place | |
(1,1,3,4) | tie for first place, then the third and fourth factions | |
(1,2,2,2) | one winner, the other factions lose | |
(1,2,2,4) | one winner, tie for second place, then the fourth faction | |
(1,2,3,3) | tie for last place | |
5 | (1,2,3,4,5) | first, second, third, fourth, fifth (ordered result) |
(1,2,2,2,2) | one winner, the other factions lose | |
... | ... | |
(1,1,3,4,5) | tie for first place, then the third, fourth and fifth factions | |
(1,1,3,3,5) | ... | |
6 | ... | ... |
The bot is the 'opponent' in a game where one of the factions doesn't feature any actual players, like in patience games, co-op board games (like Pandemic or others), or many videogames (e.g. PvE). If you use this option, you won't be able to add players to one of the factions (the bot one, of course), and you won't be able to add a bot to more than one faction.
POST /public/api/1/matches/match HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here [{ "game": 1547, "weight": "normal", "factions": [{ "rank": 1, "score": "55", "players": ["bot"] }, { "rank": 2, "score": "31", "players": ["37VjlRy1a6p"] }] }]
Check if an accepted match exists by giving its external identifier.
1 is returned if the match exists (i.e. it was entered via API before the check).
0 is returned if the match doesn't exist.
Name | Description | Required | Example |
---|---|---|---|
id | Match id | Yes | 6a56ead1-0383 |
GET /public/api/1/matches/match/exists?id=6a56ead1-0383 HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": 1 }
Returns the list of the group's subsets.
Subset creation date is in UTC.
If subset is game-related ("type": "game"
), subset object includes game model.
First and last match model is included for each subset.
GET /public/api/1/subsets HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": [{ "id": "oBypZD7Vngx", "name": "Main", "type": "main", "creationDate": "2019-12-20 09:23:48", "isMain": 1, "isCustom": 0, "icon": "https://userscontents.rankade.com/images/256/game_icon_placeholder.png", "game": null, "countMatches": 47, "firstMatch": { "id": "kRplW5enYqE", "externalId": "", "date": "2019-12-20 09:25:28", "registrationDate": "2019-12-20 09:25:48", "number": 1, "summary": "LongJohn\nCaptain Nemo", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 18, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" }, "lastMatch": { "id": "Jowlqr5o0qA", "externalId": "", "date": "2019-12-20 10:16:50", "registrationDate": "2019-12-20 10:17:01", "number": 47, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 12, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } }, { "id": "PDyKv5gpG2R", "name": "Table Football", "type": "game", "creationDate": "2019-12-20 10:17:06", "isMain": 0, "isCustom": 0, "icon": "https://cf.geekdo-images.com/images/pic1107292_t.jpg", "game": { "id": 1335, "name": "Table Football", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/images/pic1107292_t.jpg", "mediumImage": "", "bggIdGame": null }, "countMatches": 22, "firstMatch": { "id": "rKb0Mpe8leE", "externalId": "", "date": "2019-12-20 09:28:03", "registrationDate": "2019-12-20 09:28:20", "number": 1, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1335, "name": "Table Football", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/images/pic1107292_t.jpg", "mediumImage": "", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 11, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 7, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" }, "lastMatch": { "id": "B3VxkNpkYoZ", "externalId": "", "date": "2019-12-20 10:14:31", "registrationDate": "2019-12-20 10:14:42", "number": 22, "summary": "MackmanSoup\nCaptain Nemo", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1335, "name": "Table Football", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://cf.geekdo-images.com/images/pic1107292_t.jpg", "mediumImage": "", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 11, "players": [{ "id": "37VjKRy1a6p", "ghost": 0, "username": "Mackmansoup4585", "displayName": "Mackmansoup", "icon": "https://userscontents.rankade.com/images/256/16e4fd77ad4ead03683febd462ffe023.png" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 9, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } }, { "id": "0lvKeQgKwRr", "name": "Table Tennis", "type": "game", "creationDate": "2019-12-20 10:17:12", "isMain": 0, "isCustom": 0, "icon": "https://cf.geekdo-images.com/images/pic1107292_t.jpg", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "countMatches": 25, "firstMatch": { "id": "kRplW5enYqE", "externalId": "", "date": "2019-12-20 09:25:28", "registrationDate": "2019-12-20 09:25:48", "number": 1, "summary": "LongJohn\nCaptain Nemo", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 18, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" }, "lastMatch": { "id": "Jowlqr5o0qA", "externalId": "", "date": "2019-12-20 10:16:50", "registrationDate": "2019-12-20 10:17:01", "number": 25, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 12, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } } ] }
Retrieve group's ranking for selected subset after the selected match number.
Results are ordered by ranking position and paginated.
Model data for requested subset and match are available in addition to ranking data.
Name | Description | Required | Default | Example |
---|---|---|---|---|
subset | Subset id from GET /subsets |
No | main | 9dYpN0xVeR3 |
match | Match number | No | last | 12 |
page | Page number | No | 1 | 3 |
GET /public/api/1/rankings/9dYpN0xVeR3/last/2 HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": { "page": 2, "totalPages": 2, "rowsForPage": 25, "data": [{ "player": { "id": "zqRjGDw4gbJ", "ghost": 1, "username": "", "displayName": "*Emmephisto", "icon": "" }, "ree": 2043, "deltaRee": 0, "position": 26, "deltaPosition": 0, "belt": 0, "beltLabel": "", "title": 4, "titleLabel": "", "status": 3, "statusLabel": "active" }, { "player": { "id": "37VjKRy1a6p", "ghost": 0, "username": "Mackmansoup4585", "displayName": "Mackmansoup", "icon": "https://userscontents.rankade.com/images/256/16e4fd77ad4ead03683febd462ffe023.png" }, "ree": 1981, "deltaRee": 0, "position": 27, "deltaPosition": 0, "belt": 0, "beltLabel": "", "title": 0, "titleLabel": "", "status": 3, "statusLabel": "active" }, { "player": { "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }, "ree": 1974, "deltaRee": 10, "position": 28, "deltaPosition": 0, "belt": 0, "beltLabel": "", "title": 0, "titleLabel": "", "status": 3, "statusLabel": "active" }, { "player": { "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }, "ree": 1900, "deltaRee": -9, "position": 29, "deltaPosition": 0, "belt": 0, "beltLabel": "", "title": 0, "titleLabel": "", "status": 3, "statusLabel": "active" } ], "subset": { "id": "oBypZD7Vngx", "name": "Main", "type": "main", "creationDate": "2019-12-20 09:23:48", "isMain": 1, "isCustom": 0, "icon": "https://userscontents.rankade.com/images/256/game_icon_placeholder.png", "game": null, "countMatches": 47, "firstMatch": { "id": "kRplW5enYqE", "externalId": "", "date": "2019-12-20 09:25:28", "registrationDate": "2019-12-20 09:25:48", "number": 1, "summary": "LongJohn\nCaptain Nemo", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 18, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" }, "lastMatch": { "id": "Jowlqr5o0qA", "externalId": "", "date": "2019-12-20 10:16:50", "registrationDate": "2019-12-20 10:17:01", "number": 47, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 12, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } }, "match": { "id": "Jowlqr5o0qA", "externalId": "", "date": "2019-12-20 10:16:50", "registrationDate": "2019-12-20 10:17:01", "number": 47, "summary": "Captain Nemo\nLongJohn", "type": "player_vs_player", "draw": 0, "weight": "normal", "weightLabel": "Normal", "game": { "id": 1334, "name": "Table Tennis", "weight": "normal", "weightLabel": "Normal", "thumbnail": "https://userscontents.rankade.com/images/256/table_tennis.jpg", "mediumImage": "https://userscontents.rankade.com/images/500/table_tennis.jpg", "bggIdGame": null }, "factions": [{ "rank": 1, "name": "", "points": 21, "players": [{ "id": "JVk1OklO1ov", "ghost": 1, "username": "", "displayName": "*Captain Nemo", "icon": "" }], "countPlayers": 1, "winner": 1, "bot": 0 }, { "rank": 2, "name": "", "points": 12, "players": [{ "id": "Dwog3w8mgAL", "ghost": 1, "username": "", "displayName": "*LongJohn", "icon": "" }], "countPlayers": 1, "winner": 0, "bot": 0 } ], "notes": "" } } }
Returns the status of the service.
1 is returned if the service is in up status.
0 is returned in case of maintenance downtime.
GET /public/api/1/status HTTP/1.1 Accept: application/json Authorization: Bearer jwt-token-here
HTTP/1.1 200 OK ... { "success": 1 }
Is rankade's API service in beta?
Rankade's API service is in beta, technically.
The system's stability is essentially guaranteed, but - and this may sound familiar - our service is in beta, technically.
Whom is this service for?
The API service is available to all rankade groups, and it allows to enter a match into an existing group, to create players and to retrieve rankings.
There are different limits for different types of usage tiers, which impact usability. More in detail, Standard groups can test the service using all available calls, but limited quotas prevent using the service systematically. On the other hand, limits for Plus groups allow a more serial usage, including match entering. To raise the limits for specific needs and/or for serial ranking retrieval, you can switch over to the Extra API tier, with a specific set of preset limits, or to the Custom API tier, where each limit can be customized. Note that all tiers, including lower, can resort to the webapp or app interface for users creation, match entering and ranking retrieval, without limits.
In all these cases, the service is designed to respond to the needs of a regular rankade group, not for commercial use. Should you need one or more of these features:
you can request access to the Dedicated API tier.
Are there limits to API calls?
Yes, both per-hour and per-year limits.
Different tiers have different limits.
Is there a limit to the number of entered matches?
Yes, there is a per-hour limit, a per-day limit, a per-year limit, and a per-single-call limit (10). Different tiers have different limits. However, the number of matches entered via webapp/app is unlimited.
Is there a limit to the number of API ranking calls?
Yes, there is a per-hour limit, a per-day limit, a per-year limit.
Different tiers have different limits.
Is there a limit to the number of different games a group can play?
No, as long as these games are featured in the rankade database and/or in the boardgamegeek.com database. There is a limit on the number of new 'custom' games, not featured in those databases and created via the related API call.
Is this a paid service?
The API service, regarding match entering and related calls, is included with a group's upgrade to Plus.
Higher tiers are available for a dedicated fee, which varies from tier to tier.
API testing, with very limited volumes but otherwise full access to the service, is free for all groups.
Can rankade change the service's technical specifications at any time?
Yes, as per our terms and conditions.
Any change will be notified as early as practical.
Can I create new groups via API?
No, but you can do that via webapp/app.
Can I create new group members via API?
Yes, if you want to create ghosts.
Via webapp you can both invite existing users and create ghosts.
Can I change the name and/or picture of group ghosts via API?
No, but you can do that via webapp.
Can I date a match when I enter it via API?
On the Custom API and Dedicated API tier, you can date matches.
On all other tiers, matches entered via API are recorded with the date and time at which they were entered. You can't enter backdated matches via API, but you can do that via webapp.
An important note: in rankade, match dates are critical for calculating rankings. Wrong dates lead to incorrect rankings; so, if you have an archive of data you need to enter, proceed via webapp before you start using the APIs to enter matches, or switch to the Custom API or Dedicated API tier.
Can I edit or delete a match via API?
No, but you can do that via webapp.
How long does processing take?
The rankings of Plus groups (and above) are usually updated in 5-10 minutes after entering a new match via API. In some cases, rankade's engine needs a little more time for processing matches and updating rankings, e.g.:
Matches from Standard groups are queued, so their processing times are about half an hour for standard entries in normal conditions.
Stats and activities are processed 3-30 minutes after the last completed ranking processing, providing that a new match isn't entered within this time.
POST /matches/match
call.GET /matches[/subset][/page]
call.firstMatch
and lastMatch
data added to GET /subsets
response.match
and subset
data added to GET /rankings
response.GET /rankings[/subset][/match][/page]
, POST /players/player
, and GET /subsets
calls.GET /players[/page]
response.POST /games/game
call.