Leaderboards
Create Leaderboard Type You Need
Reset Windows
- All-time leaderboards never reset.
- Daily, weekly, and monthly boards reset automatically.
- Archived snapshots can be kept when a season rolls over.
Ranking Logic
- Descending mode supports classic high score leaderboards.
- Ascending mode supports lowest-time or lowest-moves wins.
- Choose best-score-only, multiple entries, or cumulative totals.
Score Submission
Submit scores with optional metadata. Server-side validation enforces min and max bounds. Invalid submissions are rejected with clear errors.
The optional leaderboard parameter defaults to global (premade Leaderboard). For REST endpoints, see the leaderboard API reference.
Queries
Top N Players
Fetch the highest or lowest ranked entries with limits from 1 to 100.
Current Rank
Get the current player's live position without loading the full board.
Surrounding Players
Request +/-N entries around a player to show immediate context in the UI.
Combined Response
Fetch top scores and player context in one request for the main leaderboard screen.
Extras
Metadata
Attach optional JSON or string metadata to each score for level, run type, build version, or replay references.
Configuration
Configure leaderboard behavior in full when creating it, including bounds, reset schedule, ordering, and entry rules.
Quick Usage
// Submit a score (uses TurnKitConfig.PlayerId by default)
await Leaderboard.SubmitScore(15420, "{\"level\":\"forest\"}");
// Get top 10
var top = await Leaderboard.GetTopScores(limit: 10);
// Get my rank + 5 players around me
var myRank = await Leaderboard.GetMyRank(surrounding: 5);
// Combined top + my context (recommended for main screen)
var combined = await Leaderboard.GetCombined(topLimit: 50, surrounding: 5);Full API
// Generic internal helper for all leaderboard requests
private async Task<T> Request<T>(string url, string method, string playerId, string json = null)
{
using UnityWebRequest req = new UnityWebRequest(url, method);
if (json != null) req.uploadHandler = new UploadHandlerRaw(System.Text.Encoding.UTF8.GetBytes(json));
req.downloadHandler = new DownloadHandlerBuffer();
req.SetRequestHeader("Content-Type", "application/json");
req.SetRequestHeader("Authorization", "Bearer YOUR_CLIENT_KEY");
req.SetRequestHeader("X-Player-Id", playerId);
var op = req.SendWebRequest();
while (!op.isDone) await Task.Yield();
return req.result == UnityWebRequest.Result.Success
? JsonUtility.FromJson<T>(req.downloadHandler.text)
: default;
}
public async Task<ScoreSubmitResponse> SubmitScore(string playerId, double score, string board = "global")
{
string json = "{\"scoreValue\":" + score + "}";
return await Request<ScoreSubmitResponse>($"https://api.turnkit.dev/v1/leaderboards/{board}/scores", "POST", playerId, json);
}
public async Task<TopScores> GetTopScores(string playerId, int limit, string board = "global")
{
return await Request<TopScores>($"https://api.turnkit.dev/v1/leaderboards/{board}/top?limit={limit}", "GET", playerId);
}
public async Task<PlayerScore> GetMyRank(string playerId, int surrounding, string board = "global")
{
return await Request<PlayerScore>($"https://api.turnkit.dev/v1/leaderboards/{board}/me?surrounding={surrounding}", "GET", playerId);
}
public async Task<CombinedScores> GetCombined(string playerId, int topLimit, int surrounding, string board = "global")
{
string url = $"https://api.turnkit.dev/v1/leaderboards/{board}/combined?topLimit={topLimit}&surrounding={surrounding}";
return await Request<CombinedScores>(url, "GET", playerId);
}
[Serializable] public class ScoreSubmitResponse { public string id; public double scoreValue; public long rank; }
[Serializable] public class TopScores { public List<LeaderboardEntry> scores; }
[Serializable] public class PlayerScore { public long startRank; public List<LeaderboardEntry> scores; }
[Serializable] public class CombinedScores { public List<LeaderboardEntry> topScores; public PlayerScore playerScore; }
[Serializable] public class LeaderboardEntry { public string playerId; public double scoreValue; public long rank; public string metadata; }Tip: Use GetCombined() for the main leaderboard UI. It reduces requests and improves performance.