> ## 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.

# Bot API Integration

> Use the Rankly public API from your bot or backend service.

Use this guide when your bot needs Rankly data on demand.

## When to use the API

* Show server or bot stats in a command
* Check whether a user can vote again
* Render review summaries in your own dashboard
* Cache Rankly data in a backend job

If you need Rankly to push updates to you, use the webhook guides instead.

## Recommended setup

<Steps>
  <Step title="Keep the API key server-side">
    Store the key in an environment variable. Do not ship it in a browser bundle or public client app.
  </Step>

  <Step title="Call the smallest endpoint you need">
    Use `/server` for server stats, `/bot` for bot stats, `/votes/:userId` for cooldown checks, and `/reviews` for review summaries.
  </Step>

  <Step title="Handle failures cleanly">
    Treat `401`, `400`, and `429` as normal outcomes and show a useful message instead of crashing the command.
  </Step>

  <Step title="Cache anything that is safe to cache">
    Rankings and review summaries do not usually need to be fetched for every message.
  </Step>
</Steps>

## Example: fetch server stats

<Tabs>
  <Tab title="Node.js">
    ```javascript theme={null}
    const baseUrl = 'https://api.rankly.live/api/v1';

    async function getServerStats() {
      const response = await fetch(`${baseUrl}/server`, {
        headers: {
          'X-API-Key': process.env.RANKLY_API_KEY,
        },
      });

      const payload = await response.json();
      if (!payload.success) {
        throw new Error(payload.error);
      }

      return payload.data;
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import os
    import requests

    base_url = "https://api.rankly.live/api/v1"
    headers = {"X-API-Key": os.environ["RANKLY_API_KEY"]}

    response = requests.get(f"{base_url}/server", headers=headers, timeout=10)
    payload = response.json()

    if not payload["success"]:
        raise RuntimeError(payload["error"])

    server = payload["data"]
    ```
  </Tab>
</Tabs>

## Example: check vote eligibility

```javascript theme={null}
const baseUrl = 'https://api.rankly.live/api/v1';
const userId = interaction.user.id;

const response = await fetch(`${baseUrl}/votes/${userId}`, {
  headers: {
    'X-API-Key': process.env.RANKLY_API_KEY,
  },
});

const payload = await response.json();

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

if (payload.data.canVote) {
  // Show the vote button or reward hint.
}
```

## Good integration habits

* Never trust the client with your API key.
* Use the public API for live reads, not for write operations.
* Keep your command output short and readable.
* Cache responses that users ask for repeatedly.
* Add a small error message when the API key is invalid or the cooldown has not expired.

## Related docs

<CardGroup cols={2}>
  <Card title="Public API Reference" href="/servers/api-reference">
    Endpoint details, auth rules, and response examples.
  </Card>

  <Card title="Bot Vote Webhooks" href="/bots/vote">
    Receive push updates when a vote is processed.
  </Card>
</CardGroup>
