Leaderboard API required scopes

I cannot for the life of me find where the required scopes for the leaderboards are documented (if they are at all).

I want to use a serviceaccount to push scores to a leaderboard: https://services.docs.unity.com/leaderboards/v1/index.html#tag/Leaderboards/operation/addLeaderboardPlayerScore

The only way I can do this is with a service account that has limited permissions, since the leaderboard scopes are not listed. Where can I find the leaderboard scopes, or can anyone tell me what they are?

Hi! Thanks for raising the issue that we can improve on the documentation for service accounts.

When calling Leaderboards from Cloud Code you should be able to call addLeaderboardPlayerScore() and pass a Player ID without any specific setup or configuration.

If that's not your use case (e.g. you are using a game server, or a script?) could you expand a little on how you are using a service account and what sort of permissions / scope it would ideally have. Thanks!

Hi Iain,

For my game server, I am using the access token that is provided with the game server at http://localhost:8086/v1/payload/token

However for development purposes, I use a service account in order to fetch an access token to use with the leaderboard (and other) UGS APIs. When the service account has a lot of scopes, it requires you to request the access bearer token with only specific scopes. Like, for example, the allocations LIST endpoint requires me to fetch an access token with the scope multiplay.allocations.list.

However, for leaderboards, I cannot work out what scope I need to request to be able to push player scores. The only way I can do it is if I specially set up a service account that has less than 100 scopes, because I don't know what scope I'm supposed to be requesting. Here is an example of where I am using the leaderboard in a server authoritive fashion for testing purposes. I also use it in my Unity Game code (which is running as a server) using web requests, because the SDK does not fit my purposes, and for various reasons, I don't want to use Cloud Code.

def fill_leaderboard_with_fake_data(bracket: str, data: list):
    loop = asyncio.get_event_loop()
    header = get_access_token()
    header = {"Authorization": f"Bearer {header}"}
    rqs = []
    for i in range(100):
        player_id = random.randrange(0, 1_000_000, 1)
        score = random.triangular(500, 2500)
        score_payload = {"score": score}
        url = f"https://leaderboards.services.api.unity.com/v1/projects/{PROJECT_ID}/leaderboards/{bracket}v{bracket}/scores/players/{player_id}"
        rqs.append(post_request(url, header, score_payload))
        url = f"https://leaderboards.services.api.unity.com/v1/projects/{PROJECT_ID}/leaderboards/{bracket}v{bracket}-elo/scores/players/{player_id}"
        rqs.append(post_request(url, header, score_payload))
    tasks = asyncio.gather(*rqs)
    loop.run_until_complete(tasks)

get_access_token looks like:

def get_service_account_auth_headers() -> dict:
    plain_text_secret = f"{SA_KEY_ID}:{SA_KEY_SECRET}"
    secret_encoded = plain_text_secret.encode("ascii")
    secret_b64_bytes = base64.b64encode(secret_encoded)
    secret_b64 = secret_b64_bytes.decode("ascii")
    return {"Authorization": f"Basic {secret_b64}"}


def get_access_token(scopes: list[str] | str | None = None) -> str | None:
    if isinstance(scopes, str):
        scopes = [scopes]

    header = get_service_account_auth_headers()
    token_exchange = f"https://services.api.unity.com/auth/v1/token-exchange?projectId={PROJECT_ID}&environmentId={ENVIRONMENT_ID}"
    if scopes:
        r = requests.post(token_exchange, headers=header, json={"scopes": scopes})
    else:
        r = requests.post(token_exchange, headers=header)
    try:
        return r.json()["accessToken"]
    except (json.JSONDecodeError, KeyError):
        logging.exception(f"bad response: {r.text}")
    return None

What I am missing, is what are the required scopes in the token exchange request. I can find the read scopes on this page:https://services.docs.unity.com/docs/service-account-auth/

But not the write scopes. It would be really nice if the API documentation examples included the required scope in either the request sample or under the Service Account authorization part, ie: (https://services.docs.unity.com/leaderboards/#tag/Leaderboards/operation/addLeaderboardPlayerScore)