Friends of Risk Open API
Free, keyless, read-only JSON API for community data: users, badges, tournaments, the RISK calendar, game settings, leaderboards and game statistics. Please be gentle — cache what you can and don't hammer it.
How it works
- Base URL:
https://friendsofrisk.com/openapi/ - Call a command as
/openapi/<command>, with one parameter as/openapi/<command>/<param>/<value>, or classic query-string style/openapi.php?command=<command>¶m=value. - Commands marked GET/POST also accept the parameters as a JSON body:
curl -X POST -H "Content-Type: application/json" -d '{"userid":"..."}' https://friendsofrisk.com/openapi/getUserProfile - Responses are JSON (UTF-8). Errors come back as
{"error": "..."}with a 400/404 status. - All ids are Discord snowflakes handled as strings — they overflow ordinary 64-bit floats, so never parse them as numbers.
- No authentication and no write operations — everything here is public community data.
- Rate limit: 60 requests per minute per client. Exceeding it returns HTTP 429 with a
Retry-Afterheader — back off and cache responses on your side.
getUsers
GET
Every registered Friends of Risk user with their public profile basics.
Parameters: —
https://friendsofrisk.com/openapi/getUsers
[
{
"discordid": "796768778977148938",
"name": "eirik",
"color": "Purple",
"country": "NO",
"avail_lastupdate": "2026-08-12 19:33:41",
"timezone": "Europe/Oslo",
"bestplace_ffa": "rankno1",
"bestplace_1v1": "first",
"bestplace_team": ""
}, ...
]
getUser
GET
One user by Discord id, including their registered availability (the next gamecount preferred game times).
Parameters: userid (Discord id, required), gamecount (optional, default 1)
https://friendsofrisk.com/openapi/getUser/userid/796768778977148938
{
"discordid": "796768778977148938",
"name": "eirik",
"color": "Purple",
"country": "NO",
"timezone": "Europe/Oslo",
"bestplace_ffa": "rankno1",
"availability": ["2026-08-30 19:00:00"]
}
getUserProfile
GET/POST
Everything public from a player's profile in one call: the user record, every badge they have earned, their placement on every leaderboard they appear on, tournament signup count and their aggregated tournament-game stats.
Parameters: userid (Discord id, required)
https://friendsofrisk.com/openapi/getUserProfile/userid/796768778977148938
{
"discordid": "796768778977148938",
"name": "eirik",
"country": "NO",
"bestplace_ffa": "rankno1",
"badges": [
{ "id": 219, "name": "Discord member 5 years", "category": "Discord", "earned": "2026-08-29" }, ...
],
"leaderboards": {
"sabrffa": { "rank": 12, "score1": 431, "score2": 25, "title": "Sabr FFA ranking" },
"ffaelo": { "rank": 4, "score1": 1287, "score2": 210, "title": "FFA ELO ranking" }
},
"tournament_signups": 31,
"allgames_stats": { "games": 208, "won": 45, "winrate": "21.63", "favmap": "The Classic Board", ... }
}
getBadge
GET/POST
One badge by id: name, category, description, how many players hold it and the ten latest recipients.
Parameters: id (badge/merit id, required)
https://friendsofrisk.com/openapi/getBadge/id/219
{
"id": 219,
"sysname": "discord_streak_30",
"name": "Discord streak 30 days",
"category": "Discord",
"description": "Chatted on Discord 30 days in a row",
"holders": 143,
"latest_recipients": [
{ "discordid": "3383326805...", "name": "Strafe", "earned": "2026-08-29" }, ...
]
}
getSetting
GET/POST
One game setting from the community settings database, with the URL of its rendered settings image.
Parameters: id (setting id, required)
https://friendsofrisk.com/openapi/getSetting/id/1093
{
"id": 1093,
"map": "The Classic Board",
"gametype": "World Domination",
"blizzards": "Off",
"fog": "Off",
"portals": "Off",
"placement": "Random",
"cards": "Progressive",
"turntimer": "Normal",
"dicerolls": "Balanced Blitz",
"image": "https://friendsofrisk.com/setting/1093.png"
}
getRandomSetting
GET
One random setting from the community settings database. Same shape as getSetting.
Parameters: —
https://friendsofrisk.com/openapi/getRandomSetting
{ "id": 4711, "map": "Halloween Village", "gametype": "Capital Conquest", ..., "image": "https://friendsofrisk.com/setting/4711.png" }
getUpcomingGames
GET
Every scheduled, not-yet-completed tournament game (group) across all events, with the players in each group. Groups with a gametime in year 4000 are placeholder entries for games that have not been scheduled yet (unscheduled: true).
Parameters: —
https://friendsofrisk.com/openapi/getUpcomingGames
[
{
"groupid": 5121,
"groupname": "Round 2 Group 3",
"gametime": "2026-09-02 19:00:00",
"roundname": "Round 2",
"bracket": 1,
"eventid": 189,
"eventname": "Fog of War FFA Season 2",
"serverid": "465846009164070912",
"unscheduled": false,
"players": [
{ "discordid": "796768778977148938", "name": "eirik" }, ...
]
}, ...
]
getLiveSchedule
GET/POST
The /liveschedule/ dataset: every scheduled, not-yet-completed tournament game across all events, from 15 minutes before now (games that just started have playing: true) up to the last scheduled one, soonest first. Unscheduled placeholder groups are excluded. Each game lists its players, flags which of them are registered streamers, and includes the Twitch live status of those streamers (live, stream title, viewer count and channel url). Live status is refreshed every minute, so a stream shows up within a minute or two of going live; a streamer counts as live when one of their linked channels is Online and was checked within the last 30 minutes. counts is always for the unfiltered set. All times are UTC.
Parameters: filter (optional: all (default), streamer = only games with a streamer in the lobby, live = only games with a streamer who is live on Twitch right now)
https://friendsofrisk.com/openapi/getLiveSchedule/filter/live
{
"generated_at": "2026-09-05T18:42:10Z",
"filter": "all",
"counts": { "all": 14, "streamer": 3, "live": 1 },
"games": [
{
"groupid": 5121,
"groupname": "Round 2 Group 3",
"eventid": 189,
"eventname": "Fog of War FFA Season 2",
"eventtype": "FFA",
"serverid": "465846009164070912",
"roundid": 611,
"roundname": "Round 2",
"bracket": 1,
"threadid": "1412345678901234567",
"gametime": "2026-09-05 19:00:00",
"gametime_iso": "2026-09-05T19:00:00Z",
"gametime_unix": 1788634800,
"playing": false,
"url": "https://friendsofrisk.com/eventmanager/189/group/5121",
"has_streamer": true,
"any_live": true,
"players": [
{ "discordid": "796768778977148938", "name": "eirik", "streamer": false, "live": false },
{ "discordid": "123456789012345678", "name": "Nordic_Noob", "streamer": true, "live": true }, ...
],
"streamers": [
{
"discordid": "123456789012345678",
"name": "Nordic_Noob",
"live": true,
"channel": "Nordic_Noob",
"url": "https://www.twitch.tv/nordic_noob",
"stream_title": "FoR tournament night!",
"viewers": 42,
"last_check": "2026-09-05 18:40:12"
}
]
}, ...
]
}
getCalendarEvents
GET/POST
All live RISK calendar entries with raw ISO dates, the host server, format type and the linked eventmanager event id when there is one. (The older getCalendar returns pre-formatted dates instead.)
Parameters: upcoming (optional, 1 = only events that have not started yet)
https://friendsofrisk.com/openapi/getCalendarEvents/upcoming/1
[
{
"eventid": 236,
"name": "The Feast",
"description": "...",
"hostserverid": "RISK: Global Domination",
"type": "FFA",
"rules_link": "https://...",
"status": "DRAFT",
"signup_start_date": "2026-08-24",
"signup_close_date": "2026-11-08",
"start_date": "2026-09-05",
"end_date": "2026-11-08",
"eventmanagerid": 194
}, ...
]
getLeaderboards
GET
Every available leaderboard: the type key (for getLeaderboard), title, what the scores mean and a description.
Parameters: —
https://friendsofrisk.com/openapi/getLeaderboards
[
{ "type": "ffaelo", "title": "FFA ELO ranking", "score1_name": "Points", "score2_name": "Games", "description": "" },
{ "type": "sabrffa", "title": "Sabr FFA ranking", "score1_name": "Points", "score2_name": "Appearances", "description": "..." }, ...
]
getLeaderboard
GET/POST
One leaderboard's entries, best rank first.
Parameters: type (required, see getLeaderboards), limit (optional, default 100, max 1000)
https://friendsofrisk.com/openapi/getLeaderboard/type/ffaelo
{
"type": "ffaelo",
"title": "FFA ELO ranking",
"score1_name": "Points",
"score2_name": "Games",
"entries": [
{ "rank": 1, "playerid": "2456819...", "displayname": "SomePlayer", "score1": 1451, "score2": 320, "score3": null }, ...
]
}
getEloGames
GET/POST
A player's FFA ELO history, newest first: one row per rated game with the ELO before, the change and the ELO after, plus the setting played and the game's player count.
Parameters: userid (Discord id, required), limit (optional, default 100, max 1000)
https://friendsofrisk.com/openapi/getEloGames/userid/796768778977148938
[
{
"gameid": 16639,
"gametime": "2026-08-20 14:00:00",
"prev_elo": "1041.78231",
"change": "-0.84527",
"new_elo": "1040.93705",
"settingid": 13800,
"eventid": "Speedy Worlddom",
"playercount": 6
}, ...
]
getAllgames
GET/POST
A player's individual tournament games from the allgames database, newest first: all players in the game with their scores, the setting and which event/round it belonged to.
Parameters: userid (Discord id, required), limit (optional, default 100, max 1000)
https://friendsofrisk.com/openapi/getAllgames/userid/796768778977148938
[
{
"id": 16645,
"type": "FOR",
"eventid": "Speedy Worlddom",
"roundid": "Round 4",
"groupid": "17573",
"gameid": 2,
"playercount": 6,
"date": "2026-08-27 18:00:00",
"player1": "HudsonHornet250", "player1id": "982321622520299601", "player1score": 9,
"player2": "RobertoLoz", "player2id": "331761695787712512", "player2score": 6,
"settingid": 13800,
"scoring": "POINTS",
"elo": 1
}, ...
]
getAllgamesStats
GET/POST
A player's aggregated tournament-game stats (rebuilt nightly): games, winrate overall and per settings family, favourite map/mode, per-lobby-size winrates, nemesis and more.
Parameters: userid (Discord id, required)
https://friendsofrisk.com/openapi/getAllgamesStats/userid/796768778977148938
{
"player": "796768778977148938",
"games": 208,
"won": 45,
"winrate": "21.63",
"favgamemode": "World Domination",
"favmap": "The Classic Board",
"winratewd": "24.10",
"winrateprogwd": "19.00",
"6plplayed": 150,
"6plwinrate": "20.00",
"nemesis": "33833268...",
"lastgame": "2026-08-28 23:19:48"
}
getEvents
GET
Every live eventmanager event (raw table rows, including the Discord channel/role ids the bot needs).
Parameters: —
https://friendsofrisk.com/openapi/getEvents
[ { "id": 189, "type": "NORMAL", "name": "Fog of War FFA Season 2", "owner": "...", "serverid": "...", "signupstatus": "OPEN", ... }, ... ]
getEventSignups
GET/POST
Current tournament signups, optionally filtered by player and/or event.
Parameters: playerid (optional), eventid (optional)
https://friendsofrisk.com/openapi/getEventSignups/eventid/189
[ { "id": 9182, "eventid": 189, "playerid": "796768778977148938", "waitlist": null, "placement": null, ... }, ... ]
getAllSignups
GET/POST
The Discord ids of every player with a signup in any live event.
Parameters: serverid (optional)
https://friendsofrisk.com/openapi/getAllSignups
[ "796768778977148938", "338332680561360927", ... ]
getCalendar
GET
Legacy calendar feed with pre-formatted dates (kept for the Discord bot). Prefer getCalendarEvents for new integrations.
Parameters: —
https://friendsofrisk.com/openapi/getCalendar
[ { "hostserverid": "RISK: Global Domination", "name": "The Feast", "daystillsignup": -5, "start_date": "September 5th", ... }, ... ]
getloungestats
GET
ELO Lounge winrate toplists for the last 7 days (relaxed and competitive lounges, minimum 3 games).
Parameters: —
https://friendsofrisk.com/openapi/getloungestats
{
"relaxed_winrate": [ { "playerid": "...", "won": "5", "played": 6, "name": "SomePlayer" }, ... ],
"competitive_winrate": [ ... ]
}
Internal endpoints
A few additional commands exist for the riskbot and the website itself
(getEvent, getEventGroupThread,
getChannelPingLog, usersearch).
They are shaped around bot internals and may change without notice — don't build on them.
