> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trophy.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Leaderboards

> Learn how to use Leaderboards in a gamified product experience with Trophy.

<h2 id="what-are-leaderboards">
  What are Leaderboards?
</h2>

Leaderboards are social competitions between users of your application. Use leaderboards to increase engagement and foster social interaction.

<Frame>
  <img height="100" width="100%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/hero.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=049a7c74a2b1ea634e0612b39204ab7d" data-path="assets/features/leaderboards/hero.png" />
</Frame>

<h2 id="types-of-leaderboards">
  Types of Leaderboards
</h2>

In this section we outline the different types of leaderboards supported in Trophy and when to use each one.

<h3 id="perpetual-leaderboards">
  Perpetual Leaderboards
</h3>

Perpetual leaderboards never reset. Once started they continually track and rank users progress over time forever, or until the configured [end date](#end-dates).

Use perpetual leaderboards when you want to create all-time rankings of user activity.

<h3 id="repeating-leaderboards">
  Repeating Leaderboards
</h3>

Repeating leaderboards can be configured to reset after any arbitrary number of days, months or years.

In Trophy each instance of a repeating leaderboard is called a **'run'**. For example, a monthly leaderboard would have 12 runs in a year, but a daily leaderboard would have `n` runs in a month where `n` is the number of days in a given month.

Trophy tracks the rankings in each run of a repeating leaderboard individually and provides [APIs](/api-reference/endpoints/leaderboards/get-leaderboard) to fetch ranking data on historical runs.

<Tip>
  We recommend using repeating leaderboards over perpetual where possible as
  repeating leaderboards give new users an equal chance to compete with existing
  users, helping to prevent leaderboards from becoming stale.
</Tip>

<h4 id="handling-time-zones">
  Handling Time Zones
</h4>

If you have tracked users' [time zones](/features/users#param-tz) with Trophy, these will be used to ensure that each user has an equal chance of winning no matter where they are in the world.

In practice this means leaderboards are finalized and winners chosen about 12 hours after they naturally finish in UTC to allow users in all time zones to make their final push.

<h4 id="tips-for-weekly-leaderboards">
  Tips for Weekly Leaderboards
</h4>

To create a weekly leaderboard, set up a [repeating leaderboard](#repeating-leaderboards) on a 7 day schedule and set the start date to be the next occurring first day of the week.

While you wait for the start date to come around, the leaderboard will be in `scheduled` status and will automatically go live on the start date.

<h2 id="ranking-logic">
  Ranking Logic
</h2>

Leaderboards in Trophy are configurable to rank participants in a number of different ways to support common use cases.

<h3 id="ranking-methods">
  Ranking Methods
</h3>

The ranking method of a leaderboard determines on what dimension participants will be ordered.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/ranking_methods.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=fc1a90e689331488db6619daaffd7a47" data-path="assets/features/leaderboards/ranking_methods.png" />
</Frame>

<h4 id="metric-rankings">
  Metric Rankings
</h4>

Metric leaderboards are linked to an existing Trophy [Metric](/features/metrics) and rank users based on their total metric value.

Use metric leaderboards if you only want to rank users based on a single interaction.

<h4 id="points-rankings">
  Points Rankings
</h4>

Points leaderboards are linked to an existing Trophy [Points System](/features/points) and automatically rank users according to their total points.

Use a points leaderboard if you want to rank users based on a combination of metrics, achievements or other Trophy features.

<h4 id="streak-rankings">
  Streak Rankings
</h4>

Streak leaderboards rank users based on their current streak length.

<Note>
  Streak leaderboards can only be [perpetual](#perpetual-leaderboards).
</Note>

<h3 id="ranking-breakdowns">
  Ranking Breakdowns
</h3>

If you have a large user base, it's best practice to split up leaderboard participants into smaller, more socially-connected groups. This often leads to higher engagement than when using global leaderboards.

Leaderboards in Trophy can be configured to group users into smaller groups according to one or more [custom user attributes](/features/users#custom-user-attributes).

<Tip>
  When using leaderboard breakdowns, [participant limits](#participant-limits)
  apply at the group level, not overall.
</Tip>

To set up a leaderboard breakdown, head to the leaderboard configuration page and create or select one or more user attributes in the 'Breakdown Attributes' field.

Trophy will automatically start grouping users into smaller leaderboards based on the values of your chosen attributes for each user.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-15/4" src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/breakdowns.mp4?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=b03de11f5e4ecf25838f43654666b5a1" data-path="assets/features/leaderboards/breakdowns.mp4" />
</Frame>

To fetch rankings for a particular group of users with a specific attribute value, use the [leaderboard rankings API](/api-reference/endpoints/leaderboards/get-leaderboard), specifying one attribute filter in the `userAttributes` parameter as follows:

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.trophy.so/v1/leaderboards/{key}?userAttributes=city:london \
    --header 'X-API-KEY: <api-key>'
  ```

  ```typescript Node theme={null}
  trophy.leaderboards.get("daily_champions", {
    offset: 0,
    limit: 10,
    run: "2025-01-15",
    userAttributes: "city:london"
  });
  ```

  ```python Python theme={null}
  client.leaderboards.get(
      key="daily_champions",
      offset=0,
      limit=10,
      run="2025-01-15",
      user_attributes="city:london"
  )
  ```

  ```php PHP theme={null}
  $request = new LeaderboardsGetRequest([
      'offset' => 0,
      'limit' => 10,
      'run' => "2025-01-15",
      'user_attributes' => "city:london"
  ]);

  $trophy->leaderboards->get("daily_champions", $request);
  ```

  ```java Java theme={null}
  LeaderboardsGetRequest request = LeaderboardsGetRequest.builder()
        .offset(0)
        .limit(10)
        .run("2025-01-15")
        .userAttributes("city:london")
        .build();

  LeaderboardsGetResponse response = client.leaderboards().get("daily_champions", request);
  ```

  ```go Go theme={null}
  response, err := client.Leaderboards.Get(
      "daily_champions",
      &api.LeaderboardsGetRequest{
          Offset: 0,
          Limit: 10,
          Run: "2025-01-15",
          UserAttributes: "city:london",
      },
  )
  ```

  ```csharp C# theme={null}
  var request = new LeaderboardsGetRequest {
     Offset = 0,
     Limit = 10,
     Run = "2025-01-15",
     UserAttributes = "city:london"
  };

  await trophy.Leaderboards.GetAsync("daily_champions", request);
  ```

  ```ruby Ruby theme={null}
  result = client.Leaderboards.Get(
    :key => "daily_champions",
    :offset => 0,
    :limit => 10,
    :run => "2025-01-15",
    :user_attributes => "city:london"
  )
  ```
</CodeGroup>

To fetch rankings for a particular group of users with a specific combination of user attributes, pass multiple comma-delimited `key:value` filters in `userAttributes` as follows:

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.trophy.so/v1/leaderboards/{key}?userAttributes=region:southeast,city:london \
    --header 'X-API-KEY: <api-key>'
  ```

  ```typescript Node theme={null}
  trophy.leaderboards.get("daily_champions", {
    offset: 0,
    limit: 10,
    run: "2025-01-15",
    userAttributes: "region:southeast,city:london"
  });
  ```

  ```python Python theme={null}
  client.leaderboards.get(
      key="daily_champions",
      offset=0,
      limit=10,
      run="2025-01-15",
      user_attributes="region:southeast,city:london"
  )
  ```

  ```php PHP theme={null}
  $request = new LeaderboardsGetRequest([
      'offset' => 0,
      'limit' => 10,
      'run' => "2025-01-15",
      'user_attributes' => "region:southeast,city:london"
  ]);

  $trophy->leaderboards->get("daily_champions", $request);
  ```

  ```java Java theme={null}
  LeaderboardsGetRequest request = LeaderboardsGetRequest.builder()
        .offset(0)
        .limit(10)
        .run("2025-01-15")
        .userAttributes("region:southeast,city:london")
        .build();

  LeaderboardsGetResponse response = client.leaderboards().get("daily_champions", request);
  ```

  ```go Go theme={null}
  response, err := client.Leaderboards.Get(
      "daily_champions",
      &api.LeaderboardsGetRequest{
          Offset: 0,
          Limit: 10,
          Run: "2025-01-15",
          UserAttributes: "region:southeast,city:london",
      },
  )
  ```

  ```csharp C# theme={null}
  var request = new LeaderboardsGetRequest {
     Offset = 0,
     Limit = 10,
     Run = "2025-01-15",
     UserAttributes = "region:southeast,city:london"
  };

  await trophy.Leaderboards.GetAsync("daily_champions", request);
  ```

  ```ruby Ruby theme={null}
  result = client.Leaderboards.Get(
    :key => "daily_champions",
    :offset => 0,
    :limit => 10,
    :run => "2025-01-15",
    :user_attributes => "region:southeast,city:london"
  )
  ```
</CodeGroup>

<Note>
  When multiple `userAttributes` filters are provided, all filters must match
  for a user to be included in the returned rankings.
</Note>

<h2 id="start-end-dates">
  Start & End Dates
</h2>

Use start and end dates to control the window within which leaderboards are actively ranking users.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/start_end_dates.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=e28ee3309c4a5d266495fce1b1779c51" data-path="assets/features/leaderboards/start_end_dates.png" />
</Frame>

<h3 id="start-dates">
  Start Dates
</h3>

Leaderboards in Trophy can be set to start at a future date of your choice. This is often useful to allow some time for last minute changes or adjustments before leaderboards start ranking users.

Leaderboards with a start date in the future are scheduled and automatically go live on the start date you choose.

<h3 id="end-dates">
  End Dates
</h3>

Leaderboards in Trophy can have end dates. If you set an end date on a leaderboard then after that date it will enter `finished` status and rankings will be finalized and winners chosen.

<Note>
  Due to differences in [time zones](#handling-time-zones), leaderboards can be
  finalized up to 12 hours after the end date in UTC to allow all users to reach
  the end date according to their local clock.
</Note>

<h2 id="participant-limits">
  Participant Limits
</h2>

Leaderboards in Trophy have a maximum number of participants of **1,000**. However a leaderboard can be configured to have any arbitrary number of participants to support use cases like *Top 100* or similar.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/max_participants.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=debf31155cf7c85abaf5d5f281e989e3" data-path="assets/features/leaderboards/max_participants.png" />
</Frame>

If a leaderboard already has a number of participants that matches its configured maximum, new users will have to surpass the score of the lowest rank to join the leaderboard.

<Tip>
  We chose to limit leaderboard size to help guide customers on best practice.

  Traditionally, leaderboards with lots of participants fail to engage users beyond the top 1%, and have a **negative** impact on users in the bottom half, particularly new users. To avoid this, keep your leaderboards small by breaking them down into smaller leaderboards using [breakdown attributes](#ranking-breakdowns).

  For more background on the negative effects on global leaderboards, read this [blog post](https://www.trophy.so/blog/leaderboard-only-motivating-top-one-percent).
</Tip>

The only exception to this is when using [breakdown attributes](#ranking-breakdowns) to group participants into smaller cohorts. When using breakdown attributes the participant limit applies to each group, not overall.

<h2 id="creating-leaderboards">
  Creating Leaderboards
</h2>

To create a leaderboard, head to the [leaderboards page](https://app.trophy.so/leaderboards) in the Trophy dashboard and hit the *New Leaderboard* button.

<Frame>
  <video autoPlay muted loop playsInline className="w-full aspect-15/4" src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/creating_leaderboards.mp4?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=232145780869eb1434fa6b53f80c491f" data-path="assets/features/leaderboards/creating_leaderboards.mp4" />
</Frame>

<Steps>
  <Step title="Enter a name">
    Choose a name for the leaderboard.
  </Step>

  <Step title="Enter a unique key">
    Enter a unique reference key for the leaderboard. This is what you'll use to reference the leaderboard in your application code.
  </Step>

  <Step title="Choose a ranking method">
    Choose one of the [methods](#ranking-methods) that the leaderboard will rank users by:

    * **Metric**: Ranks users by total value of a chosen metric
    * **Points**: Ranks users by total points in a chosen points system
    * **Streak**: Ranks users by current streak length
  </Step>

  <Step title="Set max participants">
    Choose the maximum number of participants the leaderboard should support. The
    current upper limit supported by Trophy is 1,000. Read [this
    section](#participant-limits) to learn more about how we chose this limit.
  </Step>

  <Step title="Hit save">
    Hit save and head to the configure page to set up [start & end dates](#start-end-dates), [repeating leaderboard schedules](#repeating-leaderboards) and more.
  </Step>
</Steps>

<h2 id="managing-leaderboards">
  Managing Leaderboards
</h2>

Leaderboards in Trophy have a number of statuses to help you control when users and how users can join them.

<h3 id="leaderboard-statuses">
  Leaderboard Statuses
</h3>

Leaderboards can have one of the following statuses:

* `Inactive`
* `Scheduled`
* `Active`
* `Finished`

All new leaderboards are created as `Inactive`. While inactive, any properties or settings of the leaderboard can be changed, they won't be visible to users and users can't join them.

Once you're ready for users to start participating, you can make it `Active`. This means Trophy will start tracking users' activity and entering them into leaderboards.

Leaderboards that have been configured with a [start date](#start-dates) in the future can't be made active, they can only be `Scheduled`. Once the start date is past, Trophy will automatically make them `Active` and start accepting participants.

If a leaderboard has an [end date](#end-dates), then once it has past Trophy will automatically move it to `Finished` status and stop monitoring user activity. Once a leaderboard has finished it won't be visible to users but you can still query APIs to get rankings for historical runs.

<h2 id="displaying-leaderboards">
  Displaying Leaderboards
</h2>

<Tip>
  Check out our [full guide](/guides/how-to-build-a-leaderboards-feature) on
  adding leaderboards to your app for more details.
</Tip>

<h2 id="leaderboard-analytics">
  Leaderboard Analytics
</h2>

Trophy has built-in analytics to help you understand how users are engaging with your leaderboards.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/analytics.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=a8f19b2fb32d0947a0ebb1021f71791a" data-path="assets/features/leaderboards/analytics.png" />
</Frame>

<h3 id="total-unique-participants">
  Total Unique Participants
</h3>

This chart shows how many unique users have participated in any run of a leaderboard over time. This is useful to understand how many of your users actually take part in leaderboards and how [participant limits](#participant-limits) are affecting this.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/total_unique_participants.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=c8775a05e44ae66903aff2d074ad533e" data-path="assets/features/leaderboards/total_unique_participants.png" />
</Frame>

<h3 id="active-users">
  Active Users
</h3>

This chart show the number of users who have changed rank at least once in a given leaderboard. This is useful to get a sense of how competitive the average user is in a particular leaderboard.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/active_users.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=8c2b72920aaf074722017a3f38d22ea3" data-path="assets/features/leaderboards/active_users.png" />
</Frame>

<h3 id="rank-changes">
  Rank Changes
</h3>

This chart shows the total number of rank changes in a particular leaderboard over time. This is useful to understand how competitive users are across the board.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/rank_changes.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=391639d30430c55520215d27ab6d352d" data-path="assets/features/leaderboards/rank_changes.png" />
</Frame>

<h3 id="score-distribution">
  Score Distribution
</h3>

This chart is a histogram of users' scores in a particular leaderboard. This is useful to get a sense of how bunched up or spread out users are, and what sections of the rankings are the most competitive.

<Frame>
  <img height="200" width="50%" noZoom src="https://mintcdn.com/trophy/rGjOHIeZYrVU9hOo/assets/features/leaderboards/score_distribution.png?fit=max&auto=format&n=rGjOHIeZYrVU9hOo&q=85&s=2ecd5df45a24b84a5bd3ae0deba58103" data-path="assets/features/leaderboards/score_distribution.png" />
</Frame>

<h2 id="frequently-asked-questions">
  Frequently Asked Questions
</h2>

<AccordionGroup>
  <Accordion id="leaderboard-participant-limit-faq" title="How many participants can be in a leaderboard at once?">
    We limit leaderboards to 1,000 participants.

    Read more about this in the [dedicated section](#participant-limits) of this page.
  </Accordion>

  {" "}

  <Accordion id="leaderboard-weekly-faq" title="I don't see a weekly leaderboard option, how can I set one up?">
    Trophy supports running repeating leaderboards on any arbitrary number of
    days. So a weekly leaderboard would just be a leaderboard that repeats every 7
    days. Read [this section](#tips-for-weekly-leaderboards) for more tips of
    creating weekly leaderboards.
  </Accordion>
</AccordionGroup>

<h2 id="get-support">
  Get Support
</h2>

Want to get in touch with the Trophy team? Reach out to us via [email](mailto:support@trophy.so). We're here to help!
