Quick Start Guide
Get up and running with Rankora in minutes. Learn the basics of creating leaderboards and submitting scores.
Get StartedEverything you need to integrate secure, scalable leaderboards into your games and applications
Get up and running with Rankora in minutes. Learn the basics of creating leaderboards and submitting scores.
Get StartedComplete API documentation with examples, endpoints, and detailed explanations for all features.
View API DocsOfficial client libraries to help you integrate Rankora faster. Choose the SDK that fits your development environment.
Drop‑in C# client for Unity projects with ready-to-use prefabs and comprehensive documentation.
Lightweight GDScript API for seamless leaderboard integration in Godot projects.
Coming SoonDirect HTTP API access for custom integrations and any programming language.
View API DocsComplete API documentation with examples, authentication details, and all available endpoints.
Tip: Use the sidebar navigation to jump to specific sections.
Complete guide to integrate Rankora's leaderboard API service into your application.
All API requests must include a valid API key using either the Authorization header with Bearer token.
Authorization: Bearer YOUR_API_KEY_HERENever expose your API key in client-side code if you're using this API from a frontend application.
Anyone with access to your API key can submit, delete, or fetch entries from your leaderboard.
https://www.rankora.dev/api/v1/usageRetrieve the remaining API usage limits for your API key.
{
"currentRequests": 150,
"remainingRequests": 850,
"currentLeaderboards": 5,
"remainingLeaderboards": 45,
"currentEntries": 1200,
"remainingEntries": 8800
}1const response = await fetch('https://www.rankora.dev/api/v1/usage', {
2 method: 'GET',
3 headers: {
4 'Authorization': 'Bearer YOUR_API_KEY_HERE',
5 'Content-Type': 'application/json'
6 }
7});
8const data = await response.json();
9console.log(data);/leaderboardGet metadata information about your leaderboard.
{
"id": "d5e1fc9e-461c-4328-a2bd-c033d7a33b37",
"name": "Rankora Leaderboard 1",
"sort_order": "desc",
"total_entries": 128
}1const response = await fetch('https://www.rankora.dev/api/v1/leaderboard', {
2 method: 'GET',
3 headers: {
4 'Authorization': 'Bearer YOUR_API_KEY_HERE'
5 }
6});
7const data = await response.json();
8console.log(data);/leaderboard/entriesRetrieve the top entries from your leaderboard with pagination support. Responses are cached for 5 seconds to improve performance.
limitNumber of entries to return (default: 5, max: 50)offsetNumber of entries to skip (default: 0)orderSort order: "asc" or "desc" (defaults to your leaderboard's current sort setting.player_idOptional Player Id. When provided if the player is in the entries will have a property is_current_player is set to true{
"entries": [
{ "name": "PlayerOne", "score": 9500, "metadata": null, "rank": 1, "updated_at": "2025-07-21T19:22:47.782875+00:00"},
{ "name": "PlayerTwo", "score": 8750, "metadata": { "other": "value" }, "rank": 2, "updated_at": "2025-07-21T12:12:41.623156+00:00" },
{ "name": "PlayerThree", "score": 4750, "metadata": null, "is_current_player": true, "rank": 3, "updated_at": "2025-07-24T11:12:41.613156+00:00" },
],
"pagination": { "limit": 5, "offset": 0, "total": 156 }
}1const params = new URLSearchParams({
2 limit: '5',
3 offset: '0',
4 order: 'desc',
5});
6const response = await fetch(`https://www.rankora.dev/api/v1/leaderboard/entries?${params}`, {
7 headers: {
8 'Authorization': 'Bearer YOUR_API_KEY_HERE'
9 }
10});
11const data = await response.json();
12console.log(data.entries);/leaderboard/entriesCreate a new entry or update an existing one. If player_id is provided, the entry will be updated.
{
"name": "string (required, validated)",
"score": "number (required, must be finite)",
"player_id": "string (optional, UUID format)",
"metadata": {
"key1": "value1",
"key2": "value2"
}
}Metadata is only available on "Indie" or higher plans.
{
"success": true,
"player_id": "929f5200-0d3a-436c-b54b-eb281bf6b41a",
"rank": 15
}1const entry = {
2 name: 'PlayerOne',
3 score: 1200,
4 player_id: 'optional-player-id',
5 metadata: {
6 character: 'wizard',
7 level: '12'
8 }
9};
10
11const response = await fetch('https://www.rankora.dev/api/v1/leaderboard/entries', {
12 method: 'POST',
13 headers: {
14 'Authorization': 'Bearer YOUR_API_KEY_HERE',
15 'Content-Type': 'application/json'
16 },
17 body: JSON.stringify(entry)
18});
19const data = await response.json();
20console.log(data);/leaderboard/entries/:player_idRetrieve a specific entry by player_id.
{
"leaderboard_id": "d5e1fc9e-461c-4328-a2bd-c033d7a33b37",
"name": "Dummy Test 3",
"score": 12.020123,
"player_id": "929f5200-0d3a-436c-b54b-eb281bf6b41a",
"metadata": { "other": "value" },
"rank": 12,
"created_at": "2025-07-14T19:19:40.956582+00:00",
"updated_at": "2025-07-21T12:12:41.623156+00:00",
}1const playerId = '929f5200-0d3a-436c-b54b-eb281bf6b41a';
2
3const response = await fetch(`https://www.rankora.dev/api/v1/leaderboard/entries/${playerId}`, {
4 headers: {
5 'Authorization': 'Bearer YOUR_API_KEY_HERE'
6 }
7});
8const data = await response.json();
9console.log(data);/leaderboard/entries/:player_idPermanently remove a leaderboard entry associated with the provided player_id.
player_idUnique identifier of the player entry to delete.{
"success": true
}1await fetch("https://www.rankora.dev/api/v1/leaderboard/entries/PLAYER_ID", {
2 method: "DELETE",
3 headers: {
4 Authorization: "Bearer YOUR_API_KEY_HERE",
5 },
6});Customize every aspect of your embed leaderboards with our comprehensive CSS class system. Over 100+ classes available for complete design control.
Realtime updates are available for Pro plan users and above. Get live updates when entries are added, updated, or deleted.
GET /api/v1/realtimeServer-Sent Events (SSE) endpoint for realtime updateslimitNumber of entries to return (default: 5, max: 50)offsetNumber of entries to skip (default: 0)orderSort order: "asc" or "desc" (default: leaderboard setting)player_idFilter by specific player ID (optional)The endpoint uses Server-Sent Events (SSE) format. Each message contains a JSON object with different types:
{
"type": "initial",
"success": true,
"entries": [
{ "name": "PlayerOne", "score": 9500, "rank": 1, "updated_at": "2024-01-01T00:00:00Z" },
{ "name": "PlayerTwo", "score": 8750, "rank": 2, "updated_at": "2024-01-01T00:00:00Z" }
],
"pagination": { "limit": 5, "offset": 0, "total": 100 },
"timestamp": "2025-01-01T00:00:00.000Z"
}Realtime updates only send the changed data, not the entire leaderboard:
{
"type": "update",
"payload": {
"eventType": "INSERT",
"new": { "name": "NewPlayer", "score": 10000, "updated_at": "2025-01-01T00:01:00Z" },
"old": null
},
"timestamp": "2025-01-01T00:01:00.000Z"
}{
"type": "update",
"payload": {
"eventType": "UPDATE",
"new": { "name": "PlayerOne", "score": 10500, "updated_at": "2025-01-01T00:02:00Z" },
"old": { "name": "PlayerOne", "score": 9500, "updated_at": "2025-01-01T00:00:00Z" }
},
"timestamp": "2025-01-01T00:02:00.000Z"
}{
"type": "update",
"payload": {
"eventType": "DELETE",
"new": null,
"old": { "name": "OldPlayer", "score": 5000, "updated_at": "2025-01-01T00:00:00Z" }
},
"timestamp": "2025-01-01T00:03:00.000Z"
}{
"type": "connected",
"message": "Realtime connection established",
"timestamp": "2025-01-01T00:00:00.000Z",
"user_plan": "pro"
}1const eventSource = new EventSource(`https://www.rankora.dev/api/v1/realtime?limit=10&offset=0&order=desc`, {
2 headers: {
3 'Authorization': 'Bearer YOUR_API_KEY_HERE'
4 }
5});
6
7eventSource.onmessage = (event) => {
8 const data = JSON.parse(event.data);
9
10 if (data.type === 'initial') {
11 console.log('Initial data:', data.entries);
12 } else if (data.type === 'update') {
13 console.log('Updated entries:', data.entries);
14 } else if (data.type === 'connected') {
15 console.log('Connected to realtime updates');
16 } else if (data.type === 'error') {
17 console.error('Error:', data.message);
18 }
19};
20
21eventSource.onerror = (error) => {
22 console.error('Connection error:', error);
23 eventSource.close();
24};The API uses standard HTTP status codes to indicate success or failure of requests.
200 OK: Request succeeded400 Bad Request: Invalid request data, validation errors, or plan restrictions401 Unauthorized: Missing or invalid API key403 Forbidden: Access denied for this resource or operation404 Not Found: Resource not found429 Too Many Requests: Rate limit exceeded500 Internal Server Error: Server encountered an errorAPI usage is limited based on your subscription plan. Monitor your usage with the /usage endpoint.
💡 Tip: When you exceed your rate limits, you'll receive a 429 status code. Consider implementing exponential backoff in your client code.
The API provides useful headers for monitoring and optimization:
X-Cache: Shows "HIT" or "MISS" for cached responsesCache-Control: Indicates caching behavior (5 seconds with 30s stale-while-revalidate)X-RateLimit-*: Rate limiting information when applicableCan't find what you're looking for? Our support team is here to help.
Contact SupportManage your API keys, view usage statistics, and monitor your leaderboards.
Go to Dashboard