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

# Public API Reference

> The Rankly public API for server and bot lookups, vote status, and reviews.

The public API is read-only and requires an API key tied to a Rankly server or bot.

## Base URL

```text theme={null}
https://api.rankly.live/api/v1
```

## Authentication

Send your API key in the `X-API-Key` header.

```bash theme={null}
curl https://api.rankly.live/api/v1/server \
  -H "X-API-Key: rk_live_your_key_here"
```

You can also provide the key as `?key=...`, but the header is the preferred form.

## Response shape

Most endpoints return a standard envelope:

```json theme={null}
{
  "success": true,
  "data": {},
  "meta": {}
}
```

Errors return:

```json theme={null}
{
  "success": false,
  "error": "Message here"
}
```

## Endpoints at a glance

| Method | Path             | Use it for                                               | Works for       |
| ------ | ---------------- | -------------------------------------------------------- | --------------- |
| GET    | `/server`        | Fetch the authenticated server profile and stats.        | Servers only    |
| GET    | `/bot`           | Fetch the authenticated bot profile and stats.           | Bots only       |
| GET    | `/votes/:userId` | Check vote cooldown and eligibility for a specific user. | Servers or bots |
| GET    | `/reviews`       | Read the authenticated server reviews.                   | Servers only    |

## `GET /server`

Returns the server metadata for the API key owner.

### Example response

```json theme={null}
{
  "success": true,
  "data": {
    "id": "123456789012345678",
    "name": "Rankly Community",
    "description": "A friendly Discord community.",
    "votes": 124,
    "monthlyVotes": 37,
    "tags": ["discord", "community"],
    "category": "Community",
    "ownerDiscordId": "234567890123456789",
    "features": [],
    "emojis": [],
    "channelCount": 12,
    "roleCount": 18,
    "rules": [],
    "url": "https://rankly.live/server/123456789012345678",
    "stats": {
      "members": 842,
      "online": 114
    }
  }
}
```

## `GET /bot`

Returns the bot metadata for the API key owner.

### Example response

```json theme={null}
{
  "success": true,
  "data": {
    "id": "987654321098765432",
    "name": "Rankly Bot",
    "description": "Bot utilities and rewards.",
    "votes": 52,
    "tags": [],
    "url": "https://rankly.live/bot/987654321098765432",
    "stats": {
      "servers": 0,
      "shards": 0
    }
  }
}
```

## `GET /votes/:userId`

Checks whether a user can vote again right now.

### Path parameters

| Parameter | Type   | Description                                |
| --------- | ------ | ------------------------------------------ |
| `userId`  | string | Discord user ID to check. Must be numeric. |

### Example response

```json theme={null}
{
  "success": true,
  "data": {
    "canVote": false,
      "nextVoteDate": "2026-01-02T00:00:00.000Z",
    "lastVoteDate": "2026-01-01T12:00:00.000Z",
    "secondsUntilVote": 43200
  }
}
```

The cooldown window is 12 hours.

## `GET /reviews`

Returns reviews for the authenticated server.

### Query parameters

| Parameter | Type   | Default  | Description                                    |
| --------- | ------ | -------- | ---------------------------------------------- |
| `limit`   | number | `10`     | Maximum reviews to return. The hard cap is 50. |
| `sort`    | string | `newest` | Use `newest`, `highest`, or `lowest`.          |

### Example response

```json theme={null}
{
  "success": true,
  "data": [
    {
      "username": "Skyline",
      "rating": 5,
      "comment": "Very active and welcoming.",
      "createdAt": "2026-01-01T12:00:00.000Z"
    }
  ],
  "meta": {
    "total": 14,
    "shown": 1
  }
}
```

## Example client code

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={null}
    const response = await fetch('https://api.rankly.live/api/v1/server', {
      headers: {
        'X-API-Key': process.env.RANKLY_API_KEY,
      },
    });

    const payload = await response.json();

    if (!payload.success) {
      throw new Error(payload.error);
    }

    console.log(payload.data.name);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl "https://api.rankly.live/api/v1/votes/123456789012345678" \
      -H "X-API-Key: rk_live_your_key_here"
    ```
  </Tab>
</Tabs>

## Error handling

* `401` means the key is missing or invalid.
* `400` means the endpoint does not match the key type or the parameter is invalid.
* `429` means the request limit was exceeded.
* `500` means the backend hit an unexpected error.

## Best practices

* Keep the API key on your server.
* Cache responses that do not need to change every second.
* Use `/votes/:userId` only when you need the live cooldown state.
* Prefer the public API reference over reverse-engineering dashboard calls.
