# List leaderboards

List the leaderboards in the community that owns your API key, one page at a time.

- Endpoint: `GET https://api.returning.ai/v1/leaderboards`
- Section: Gamification / Leaderboards
- Authentication: `Authorization: Bearer <API_KEY>` (Community API key)
- Permission: `leaderboard` (Shown in the dashboard as "Leaderboard")
- Retries: Read-only; exact retries are safe
- Guide: hand-written
- Verified: live, 2026-09-27
- Last updated: 26 Sep 2026
- Web page: https://docs.returning.ai/api-reference/gamification-leaderboards/list-leaderboards

## When to use this

- Find a leaderboard's ID before you read or change it.
- Check that a slug or name is free before you create a leaderboard.
- Audit which leaderboards are live and who can see them.

**Instead:** Use [Get leaderboard](https://docs.returning.ai/api-reference/gamification-leaderboards/get-leaderboard.md) instead when you already have the ID.

## Authentication

- Header: `Authorization: Bearer <API_KEY>`
- Permission: `leaderboard`

Send a Community API key with the `leaderboard` permission. The key decides the community, so never send a community ID.

## Behaviour

The list includes every leaderboard in your community, whether or not it is enabled, started or ended, and whoever it is visible to. Without `sort`, the oldest leaderboard comes first; to show them in their display order, sort `data` by `displayOrder` yourself.

## Request

### Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | `integer` | No | Page number, starting at 1. (Whole number, 1 or more; default 1) |
| `limit` | `integer` | No | Leaderboards per page, up to 100. (Default 20; max 100) |
| `sort` | `string` | No | One field and a direction. Sortable fields are `createdAt`, `updatedAt`, `name` and `slug`. Without it, the oldest leaderboard comes first. (`field:asc` or `field:desc`) |
| `search` | `string` | No | `keyword:<text>` matches the name or slug; `name:<text>` or `slug:<text>` matches one of them. Matches anywhere in the value, ignoring case. (`keyword:`, `name:` or `slug:` prefix) |
| `fields` | `string` | No | Comma-separated fields to return; `_id` always comes back. Use the stored names here: `leaderImage` returns `image`, `serverId` returns `communityID`. (Leaderboard field names) |

### Headers

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `Authorization` | `string` | Yes | Community API key with `leaderboard`. (`Bearer <API_KEY>`) |

### Example request

```bash
curl --request GET \
  --url 'https://api.returning.ai/v1/leaderboards?page=1&limit=20&sort=createdAt:desc' \
  --header 'Authorization: Bearer <API_KEY>'
```

## Response

A `200` returns the page in `data` and the paging details in `meta`. When `meta.page * meta.limit` is less than `meta.total`, request the next page. Branch on the HTTP status.

### Response fields

| Field | Type | Presence | Description |
| --- | --- | --- | --- |
| `meta` | `object` | always | Status and paging details. There is no `meta.code` on success. |
| `meta.status` | `string` | always | Result of the request. (`success`) |
| `meta.statusCode` | `integer` | always | The HTTP status, repeated. |
| `meta.page` | `integer` | always | The page returned. |
| `meta.limit` | `integer` | always | The page size used. |
| `meta.total` | `integer` | always | Leaderboards that match your search, across all pages. |
| `message` | `string` | always | Human-readable summary. Do not branch on it. |
| `data` | `object[]` | always | Leaderboards on this page. An empty array when none match. |
| `data._id` | `string` | - | Leaderboard ID. Use it to read, update or delete the leaderboard. |
| `data.communityID` | `string` | - | Your community ID. |
| `data.kind` | `string` | - | `default` for your community's built-in Default Leaderboard, which can't be deleted; `custom` for every other leaderboard. |
| `data.name` | `string` | - | Leaderboard name. |
| `data.slug` | `string` | - | URL-friendly ID, unique in your community. |
| `data.description` | `string` | - | Description shown to traders. Empty string when none. |
| `data.image` | `string` | - | Leaderboard image URL, when one is set. |
| `data.enabled` | `boolean` | - | `true` when the leaderboard is live for the traders who can see it. |
| `data.displayOrder` | `number` | - | Position among your leaderboards, starting at 1. Older leaderboards may not have one. |
| `data.order` | `number` | - | Same value as `displayOrder`. |
| `data.rankBy` | `string` | - | What traders are ranked by: `XP`, `Coins`, `Referrals`, or a user-field key. |
| `data.duration` | `object` | - | When the leaderboard runs. |
| `data.duration.start` | `string` | - | Start date. The leaderboard starts at `startTime` on this date, in its time zone. |
| `data.duration.end` | `string` | - | End date, or `null` when there is none. (Nullable) |
| `data.duration.noEndDate` | `boolean` | - | `true` when the leaderboard runs with no end date. |
| `data.duration.timeZone` | `number` | - | Time zone as an offset from UTC in minutes, for example `480` for UTC+8. |
| `data.duration.startTime` | `object` | - | Start time of day, as `hours` (1-12), `minutes` and `ampm`. |
| `data.duration.endTime` | `object` | - | End time of day, in the same format. |
| `data.timeFilters` | `string[]` | - | Period tabs traders can switch between: `all-time`, `daily`, `weekly`, `monthly`, `yearly`. |
| `data.rankedUserRoles` | `object` | - | Traders who get ranked. |
| `data.rankedUserRoles.users` | `object[]` | - | Traders listed one by one, as `id` (numeric platform user ID), `_id`, `username` and `email`. The last three are `null` for a trader who has left your community. |
| `data.rankedUserRoles.roles` | `object[]` | - | Roles, as `_id` and `name`. `name` is `null` for a deleted role. |
| `data.rankedUserRoles.tags` | `object[]` | - | Tags, as `_id` and `name`. `name` is `null` for a deleted tag. |
| `data.viewPermissionUserRoles` | `object` | - | Traders who can see the leaderboard, in the same shape as `rankedUserRoles`. |
| `data.enableLeaderboardReset` | `boolean` | - | `true` when scores restart every period. |
| `data.leaderboardResetFrequency` | `string` | - | How often scores restart: `daily`, `weekly`, `monthly` or `yearly`. |
| `data.enablePrizePool` | `boolean` | - | `true` when prizes are paid. |
| `data.prizes` | `object[]` | - | Prize rows by rank. |
| `data.displayedFields` | `string[]` | - | Columns shown in the leaderboard table. |
| `data.displayFieldsOrder` | `string[]` | - | Column order. |
| `data.performanceDisplay` | `object` | - | Table display options: `showTop` blurs rows below the top `value` ranks, `showPositive` hides scores of 0 or less. |
| `data.banner` | `object` | - | Banner settings. |
| `data.userInformationDisplay` | `object[]` | - | How much of each trader's details the table shows. |
| `data.previewEnabled` | `boolean` | - | `true` when guests can see the leaderboard, if your community allows guest preview. |
| `data.selected` | `boolean` | - | `true` for the one leaderboard your community has set as its active leaderboard. |
| `data.updatedAt` | `string` | - | When the leaderboard last changed, ISO 8601 UTC. |
| `data.createdAt` | `string` | - | When the leaderboard was created, ISO 8601 UTC. |
| `data.widget` | `object` | - | Embeddable widget settings, when set. |
| `data.translations` | `object` | - | Translated names and descriptions, when set. |
| `data.leaderboardPageConfig` | `object` | - | Leaderboard page layout settings, when set. |
| `data.configurationHistory` | `object[]` | - | Log of settings changes. Present only on the Default Leaderboard after it has been changed. |

### Example response (200)

```json
{
  "meta": {
    "status": "success",
    "statusCode": 200,
    "page": 1,
    "limit": 20,
    "total": 1
  },
  "message": "Read leaderboards success.",
  "data": [
    {
      "_id": "66f000000000000000000301",
      "communityID": "66f000000000000000000010",
      "kind": "custom",
      "name": "Monthly Trading Volume",
      "slug": "monthly-trading-volume",
      "description": "Top traders by trading volume each month.",
      "rankBy": "tradingvolume",
      "displayedFields": ["user", "tier", "level"],
      "displayFieldsOrder": ["user", "tier", "level"],
      "timeFilters": ["monthly", "all-time"],
      "performanceDisplay": {
        "showTop": {
          "enabled": false,
          "value": 0
        },
        "showPositive": {
          "enabled": false
        },
        "showDummy": {
          "enabled": false
        }
      },
      "duration": {
        "start": "2026-10-01T00:00:00.000Z",
        "end": null,
        "noEndDate": true,
        "timeZone": 0,
        "startTime": {
          "hours": 12,
          "minutes": 0,
          "ampm": "AM"
        },
        "endTime": {
          "hours": 11,
          "minutes": 59,
          "ampm": "PM"
        }
      },
      "rankedUserRoles": {
        "users": [],
        "roles": [
          {
            "_id": "66f000000000000000000502",
            "name": "@all"
          }
        ],
        "tags": []
      },
      "viewPermissionUserRoles": {
        "users": [],
        "roles": [
          {
            "_id": "66f000000000000000000502",
            "name": "@all"
          }
        ],
        "tags": []
      },
      "banner": {},
      "enableLeaderboardReset": true,
      "leaderboardResetFrequency": "monthly",
      "enablePrizePool": false,
      "prizes": [],
      "userInformationDisplay": [],
      "enabled": true,
      "previewEnabled": false,
      "selected": false,
      "displayOrder": 2,
      "order": 2,
      "updatedAt": "2026-09-26T08:30:00.000Z",
      "createdAt": "2026-09-26T08:30:00.000Z"
    }
  ]
}
```

## Errors

`401`, `403` and `400` errors carry a code in `meta.code`. `500` and `502` errors have no code; branch on the HTTP status and read `detail`.

### Fix the request

| Status | Code | What to do |
| --- | --- | --- |
| 400 | `VALIDATION_FAILED` | A query value is malformed or out of range, such as `limit` over 100, `sort=displayOrder`, or `search` without a `field:` prefix. `detail` names the parameter. |
| 401 | `AUTH_API_KEY_REQUIRED` | No key was sent. Send `Authorization: Bearer <API_KEY>`. |
| 401 | `AUTH_API_KEY_INVALID` | The key is unknown, expired or malformed. Use a current Community API key. |
| 403 | `AUTH_PERMISSION_REQUIRED` | The key lacks `leaderboard`. Add the permission in Settings > Integration > API Keys. |

### Retry with backoff

| Status | Code | What to do |
| --- | --- | --- |
| 500 | - | The read failed unexpectedly. Retry the same request with exponential backoff. |
| 502 | - | Leaderboards are briefly unavailable. Retry the same request with exponential backoff. |
| 401 | `AUTH_API_KEY_VALIDATION_FAILED` | The key could not be checked just now. Retry with backoff; the key itself may be fine. |

**Retries:** This endpoint is read-only, so retrying the exact same request is safe after a network error, a `500` or a `502`. Use bounded exponential backoff. Over the [rate limit](https://docs.returning.ai/how-it-works.md#rate-limits), requests return `429`; wait for the window to reset, then retry.

## Next step

- [Get leaderboard](https://docs.returning.ai/api-reference/gamification-leaderboards/get-leaderboard.md): `GET /v1/leaderboards/{leaderboardID}`. Read one leaderboard in full, using an `_id` from this list.
- [Need a new one? Create leaderboard](https://docs.returning.ai/api-reference/gamification-leaderboards/create-leaderboard.md): `POST /v1/leaderboards`.
