# Portal Leaderboard API

The Leaderboard API lets you retrieve your community's merged leaderboard rankings and look up individual user positions. All leaderboard data is aggregated across every visible leaderboard in your community.

## Overview

Use the Leaderboard API to:

* Display leaderboard rankings in your own UI or application
* Look up a specific user's rank and points by user ID
* Look up a user by social ID or username (Discord, Twitter, Telegram, Reddit, email, etc.)
* Filter rankings by time period (daily, weekly, bi-weekly, monthly, or all-time)
* Paginate through large leaderboards with cursor-based pagination

## Authentication

All Leaderboard API requests require a **Community API Key** passed in the `x-api-key` header. You can create Community API Keys from your community dashboard.

```
x-api-key: <community-api-key>
```

{% hint style="info" %}
Replace `your-community` in the URLs below with your community slug. For example, if your portal is at `acme.domino.page`, your slug is `acme`.
{% endhint %}

***

## Get Leaderboard Rankings

Retrieves the full leaderboard with all users ranked by the default leaderboard, including per-leaderboard point breakdowns.

```
GET https://your-community.domino.page/api/v1/leaderboard
```

### Query Parameters

| Parameter | Type   | Required | Description                                                                                           |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `limit`   | Number | No       | Number of users to return per page (1–100, default `20`)                                              |
| `cursor`  | Number | No       | Pagination cursor returned from a previous request. Omit for the first page                           |
| `view`    | String | No       | Time period filter. One of `all_time`, `daily`, `weekly`, `bi_weekly`, `monthly` (default `all_time`) |

### Response

| Property                           | Type    | Description                                                               |
| ---------------------------------- | ------- | ------------------------------------------------------------------------- |
| `leaderboards`                     | Array   | All visible leaderboards for the community                                |
| `leaderboards[].id`                | String  | Leaderboard ID                                                            |
| `leaderboards[].name`              | String  | Leaderboard name                                                          |
| `leaderboards[].portalColumnLabel` | String  | Custom column label displayed in the portal (may be `null`)               |
| `leaderboards[].isDefault`         | Boolean | Whether this is the default leaderboard used for ranking                  |
| `users`                            | Array   | Ranked list of users                                                      |
| `users[].user`                     | Object  | User profile                                                              |
| `users[].user.id`                  | String  | User ID                                                                   |
| `users[].user.name`                | String  | Display name                                                              |
| `users[].user.imageUrl`            | String  | Profile image URL (may be `null`)                                         |
| `users[].rank`                     | Number  | User's rank based on the default leaderboard                              |
| `users[].pointsByLeaderboard`      | Object  | Points keyed by leaderboard ID, e.g. `{ "lb-id-1": 500, "lb-id-2": 120 }` |
| `users[].rankByLeaderboard`        | Object  | Rank keyed by leaderboard ID, e.g. `{ "lb-id-1": 1, "lb-id-2": 3 }`       |
| `nextCursor`                       | Number  | Cursor value for the next page, or `null` if there are no more results    |
| `hasMore`                          | Boolean | Whether more results are available                                        |

### Example Response

```json
{
  "leaderboards": [
    {
      "id": "lb-abc123",
      "name": "Main Leaderboard",
      "portalColumnLabel": "XP",
      "isDefault": true,
      "startDate": null,
      "endDate": null
    },
    {
      "id": "lb-def456",
      "name": "Bonus Points",
      "portalColumnLabel": "Bonus",
      "isDefault": false,
      "startDate": null,
      "endDate": null
    }
  ],
  "users": [
    {
      "user": {
        "id": "user-001",
        "name": "Alice",
        "imageUrl": "https://cdn.example.com/alice.png"
      },
      "rank": 1,
      "pointsByLeaderboard": {
        "lb-abc123": 1500,
        "lb-def456": 300
      },
      "rankByLeaderboard": {
        "lb-abc123": 1,
        "lb-def456": 3
      }
    },
    {
      "user": {
        "id": "user-002",
        "name": "Bob",
        "imageUrl": null
      },
      "rank": 2,
      "pointsByLeaderboard": {
        "lb-abc123": 1200,
        "lb-def456": 450
      },
      "rankByLeaderboard": {
        "lb-abc123": 2,
        "lb-def456": 1
      }
    }
  ],
  "nextCursor": 2,
  "hasMore": true
}
```

### Example Request

```javascript
const response = await fetch('https://acme.domino.page/api/v1/leaderboard?limit=10&view=weekly', {
  headers: {
    'x-api-key': 'your-community-api-key'
  }
});

const leaderboard = await response.json();
console.log(leaderboard.users); // Top 10 users for this week
```

### Paginating Through Results

```javascript
async function getAllRankings() {
  const allUsers = [];
  let cursor = undefined;

  do {
    const params = new URLSearchParams({ limit: '100' });
    if (cursor) params.set('cursor', String(cursor));

    const response = await fetch(
      `https://acme.domino.page/api/v1/leaderboard?${params}`,
      { headers: { 'x-api-key': 'your-community-api-key' } }
    );

    const page = await response.json();
    allUsers.push(...page.users);
    cursor = page.nextCursor;
  } while (cursor);

  return allUsers;
}
```

***

## Get User Ranking

Retrieves a single user's rank and points across all visible leaderboards.

```
GET https://your-community.domino.page/api/v1/leaderboard/:userId
```

### Path Parameters

| Parameter | Type   | Required | Description   |
| --------- | ------ | -------- | ------------- |
| `userId`  | String | Yes      | The user's ID |

### Query Parameters

| Parameter | Type   | Required | Description                                                                                           |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `view`    | String | No       | Time period filter. One of `all_time`, `daily`, `weekly`, `bi_weekly`, `monthly` (default `all_time`) |

### Response

| Property              | Type   | Description                                                               |
| --------------------- | ------ | ------------------------------------------------------------------------- |
| `user`                | Object | User profile                                                              |
| `user.id`             | String | User ID                                                                   |
| `user.name`           | String | Display name                                                              |
| `user.imageUrl`       | String | Profile image URL (may be `null`)                                         |
| `rank`                | Number | User's rank based on the default leaderboard                              |
| `pointsByLeaderboard` | Object | Points keyed by leaderboard ID, e.g. `{ "lb-id-1": 500, "lb-id-2": 120 }` |
| `rankByLeaderboard`   | Object | Rank keyed by leaderboard ID, e.g. `{ "lb-id-1": 1, "lb-id-2": 3 }`       |

### Example Response

```json
{
  "user": {
    "id": "user-001",
    "name": "Alice",
    "imageUrl": "https://cdn.example.com/alice.png"
  },
  "rank": 1,
  "pointsByLeaderboard": {
    "lb-abc123": 1500,
    "lb-def456": 300
  },
  "rankByLeaderboard": {
    "lb-abc123": 1,
    "lb-def456": 3
  }
}
```

### Example Request

```javascript
const userId = 'user-001';
const response = await fetch(`https://acme.domino.page/api/v1/leaderboard/${userId}?view=monthly`, {
  headers: {
    'x-api-key': 'your-community-api-key'
  }
});

const ranking = await response.json();
console.log(`Rank #${ranking.rank}`);
```

***

## Look Up User Ranking by Social ID

Finds a user by a social platform ID or username and returns their ranking. This is useful when you don't have the Domino user ID but know the user's social identity.

```
GET https://your-community.domino.page/api/v1/leaderboard/lookup
```

At least one identifier query parameter is required. If multiple identifiers are provided, a user matching **any** of them will be returned.

### Query Parameters — Identifiers

| Parameter          | Type   | Description                  |
| ------------------ | ------ | ---------------------------- |
| `discordId`        | String | Discord user ID              |
| `discordUsername`  | String | Discord username             |
| `twitterId`        | String | Twitter/X user ID            |
| `twitterUsername`  | String | Twitter/X username           |
| `telegramId`       | String | Telegram user ID             |
| `telegramUsername` | String | Telegram username            |
| `redditId`         | String | Reddit user ID               |
| `redditUsername`   | String | Reddit username              |
| `externalId`       | String | External ID from your system |
| `email`            | String | User's email address         |

### Query Parameters — Options

| Parameter | Type   | Required | Description                                                                                           |
| --------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- |
| `view`    | String | No       | Time period filter. One of `all_time`, `daily`, `weekly`, `bi_weekly`, `monthly` (default `all_time`) |

### Response

The response shape is the same as [Get User Ranking](#get-user-ranking).

### Example Response

```json
{
  "user": {
    "id": "user-001",
    "name": "Alice",
    "imageUrl": "https://cdn.example.com/alice.png"
  },
  "rank": 1,
  "pointsByLeaderboard": {
    "lb-abc123": 1500,
    "lb-def456": 300
  },
  "rankByLeaderboard": {
    "lb-abc123": 1,
    "lb-def456": 3
  }
}
```

### Example Requests

**Look up by Discord ID:**

```javascript
const response = await fetch(
  'https://acme.domino.page/api/v1/leaderboard/lookup?discordId=123456789012345678',
  { headers: { 'x-api-key': 'your-community-api-key' } }
);

const ranking = await response.json();
console.log(`Rank #${ranking.rank}`);
```

**Look up by Twitter username:**

```javascript
const response = await fetch(
  'https://acme.domino.page/api/v1/leaderboard/lookup?twitterUsername=alice_dev',
  { headers: { 'x-api-key': 'your-community-api-key' } }
);
```

**Look up by email with weekly view:**

```javascript
const response = await fetch(
  'https://acme.domino.page/api/v1/leaderboard/lookup?email=alice@example.com&view=weekly',
  { headers: { 'x-api-key': 'your-community-api-key' } }
);
```

**Look up by external ID (your system's user ID):**

```javascript
const response = await fetch(
  'https://acme.domino.page/api/v1/leaderboard/lookup?externalId=usr_abc123',
  { headers: { 'x-api-key': 'your-community-api-key' } }
);
```

***

## Error Responses

All endpoints return standard error responses:

| Status | Description                                      |
| ------ | ------------------------------------------------ |
| `400`  | Missing required parameters (e.g. no identifier) |
| `401`  | Missing or invalid API key                       |
| `404`  | Community or user not found                      |
| `500`  | Internal server error                            |

```json
{
  "error": "User not found in leaderboard"
}
```

***

## Related Resources

* [Authenticating users with the portal API](https://docs.domino.run/docs/developer-resources/authenticating-users-with-the-portal-api)
* [Create Leaderboards](https://docs.domino.run/docs/domino-portal/creating-leaderboards)
