Prerequisites

  • Unity 2021 LTS or newer
  • A LightLeaderboard account, game, and API key
  • UnityEngine.Networking — included in Unity, no install needed
iOS / Android: UnityWebRequest works on all platforms Unity supports. No extra networking configuration required.

Step 1 — Add the Data Classes

Create ScorePayload.cs in your project. Unity's JsonUtility requires [Serializable] classes — no Newtonsoft needed.

ScorePayload.cs C#
// ScorePayload.cs — add to your project
using System;

[Serializable]
public class ScorePayload
{
    public int    score;
    public string playerRefId;
    public string playerName;
    public string submissionId;
}

[Serializable]
public class ScoreResponse
{
    public int    id;
    public int    rank;
    public int    score;
    public string playerName;
}

[Serializable]
public class LeaderboardEntry
{
    public int    rank;
    public string playerName;
    public int    score;
}

[Serializable]
public class LeaderboardResponse
{
    public LeaderboardEntry[] entries;
}

Step 2 — Submit a Score

Attach LeaderboardManager to a persistent GameObject (e.g. your GameManager). Call SubmitScore() from any other script.

LeaderboardManager.cs C#
// LeaderboardManager.cs — attach to any GameObject
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;

public class LeaderboardManager : MonoBehaviour
{
    const string ApiUrl = "https://yourapp.com/api/v1/games/my_game";
    const string ApiKey = "YOUR_API_KEY";

    public void SubmitScore(int score, string playerId, string playerName)
        => StartCoroutine(SubmitScoreCoroutine(score, playerId, playerName));

    IEnumerator SubmitScoreCoroutine(int score, string playerId, string playerName)
    {
        var payload = new ScorePayload {
            score        = score,
            playerRefId  = playerId,
            playerName   = playerName,
            submissionId = System.Guid.NewGuid().ToString(),
        };
        byte[] body = System.Text.Encoding.UTF8
            .GetBytes(JsonUtility.ToJson(payload));

        using var req = new UnityWebRequest(ApiUrl + "/scores", "POST");
        req.uploadHandler   = new UploadHandlerRaw(body);
        req.downloadHandler = new DownloadHandlerBuffer();
        req.SetRequestHeader("Authorization", "Bearer " + ApiKey);
        req.SetRequestHeader("Content-Type",  "application/json");

        yield return req.SendWebRequest();

        if (req.result == UnityWebRequest.Result.Success)
        {
            var res = JsonUtility.FromJson<ScoreResponse>(req.downloadHandler.text);
            Debug.Log($"Submitted! Rank: #{res.rank}");
            // update your UI here
        }
    }
}

Step 3 — Fetch the Leaderboard

Add GetLeaderboard() to the same manager. Call it from your leaderboard UI screen's Start() or OnEnable().

LeaderboardManager.cs (continued) C#
// Add to LeaderboardManager.cs
public void GetLeaderboard(int limit = 10)
    => StartCoroutine(GetLeaderboardCoroutine(limit));

IEnumerator GetLeaderboardCoroutine(int limit)
{
    using var req = UnityWebRequest.Get(
        $"{ApiUrl}/leaderboard?limit={limit}");
    req.SetRequestHeader("Authorization", "Bearer " + ApiKey);

    yield return req.SendWebRequest();

    if (req.result == UnityWebRequest.Result.Success)
    {
        var res = JsonUtility.FromJson<LeaderboardResponse>(
            req.downloadHandler.text);
        foreach (var e in res.entries)
            Debug.Log($"#{e.rank}  {e.playerName}  {e.score}");
            // populate your UI Text or TMP components
    }
}

Tips

  • Store ApiKey in a ScriptableObject or Unity's PlayerPrefs rather than hardcoding it if you need runtime configuration.
  • System.Guid.NewGuid().ToString() is the cleanest way to generate a unique submissionId in Unity.
  • For TMP (TextMeshPro) leaderboards, set rankText.text = $"#{e.rank}" inside the loop — works identically to Debug.Log.
  • If targeting WebGL, replace UnityWebRequest with a JS interop call — or route through your own backend since WebGL CORS restrictions can block direct API calls depending on browser policy.