ScoreDrop
Home Documentation FAQ Features About

API Documentation

Simple leaderboard API for indie games


Authentication

All endpoints require your API key, which you receive when creating a leaderboard.

Base URL

https://leaderboard-game.vercel.app

All API endpoints are relative to this base URL.

Quick Start

Integrate ScoreDrop in less than a minute:

  1. Create a leaderboard and copy your API key.
  2. Generate a unique player_id inside your game (UUID recommended).
  3. Send player scores using the /api/add endpoint.
  4. Retrieve the leaderboard using the /api/top endpoint.

ScoreDrop works with any engine or language capable of making HTTP requests.

Player ID

Each player must have a unique player_id. This identifier is generated by your game and must remain the same for that player across sessions.

We recommend using a UUID (Universally Unique Identifier). Many engines (Unity, Godot, Unreal) and most programming languages can generate UUIDs easily.

Example UUID format

e5e27da1-d3a7-4cca-b991-2802f356be39
a19c73f2-2b17-4c18-9b62-11c03a7a9d02

The player_id should be stored locally on the device or linked to your game's account system. ScoreDrop uses this ID to update scores and player names correctly.

Testing the API

You can test the API directly in your browser or using tools like Postman or curl.

Example request

https://leaderboard-game.vercel.app/api/top?key=YOUR_API_KEY

Replace YOUR_API_KEY with your leaderboard key to retrieve scores instantly.

Add Player Score

Send a player score to your leaderboard. Each player is identified by a unique player_id generated by your game.

ENDPOINT

GET
/api/add?key=YOUR_API_KEY&player_id=UNIQUE_ID&player=NAME&score=NUMBER

Parameters

Parameter Description
key Your API key (required)
player_id Unique identifier for the player (required)
player Display name of the player (required)
score Player's score (required)

EXAMPLES BY PLATFORM

Unity Godot Unreal HTML/JS Python C++ C# Construct
// Unity C# with UnityWebRequest
using UnityEngine.Networking;
using System.Collections;

IEnumerator AddScore(string playerName, int score, string playerId) {
  string url = "https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=" + playerId + "&player=" + UnityWebRequest.EscapeURL(playerName) + "&score=" + score;
  UnityWebRequest www = UnityWebRequest.Get(url);
  yield return www.SendWebRequest();

  if (www.result == UnityWebRequest.Result.Success) {
    Debug.Log("Score added: " + www.downloadHandler.text);
  } else {
    Debug.LogError("Error: " + www.error);
  }
}
# Godot GDScript with HTTPRequest
extends Node

func add_score(player_name: String, score: int, player_id: String):
  var url = "https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=" + player_id + "&player=" + player_name.uri_encode() + "&score=" + str(score)
  var http = HTTPRequest.new()
  add_child(http)
  http.request_completed.connect(_on_request_completed)
  http.request(url)

func _on_request_completed(result, response_code, headers, body):
  var json = JSON.parse_string(body.get_string_from_utf8())
  print("Response: ", json)
// Unreal C++ with FHttpModule
#include "HttpModule.h"
#include "Interfaces/IHttpRequest.h"
#include "Interfaces/IHttpResponse.h"

void AMyGameMode::AddScore(FString PlayerName, int32 Score, FString PlayerId)
{
  FString URL = FString::Printf(TEXT("https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=%s&player=%s&score=%d"),
    *PlayerId, *PlayerName, Score);

  TSharedRef<IHttpRequest, ESPMode::ThreadSafe> Request = FHttpModule::Get().CreateRequest();
  Request->SetURL(URL);
  Request->SetVerb("GET");
  Request->OnProcessRequestComplete().BindUObject(this, &AMyGameMode::OnAddScoreResponse);
  Request->ProcessRequest();
}

void AMyGameMode::OnAddScoreResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
  if (bWasSuccessful)
  {
    UE_LOG(LogTemp, Warning, TEXT("Response: %s"), *Response->GetContentAsString());
  }
}
// JavaScript with fetch API
async function addScore(playerName, score, playerId) {
  const url = `https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=${playerId}&player=${encodeURIComponent(playerName)}&score=${score}`;
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.log('Score added:', data);
  } catch (error) {
    console.error('Error:', error);
  }
}

// Example usage
addScore("Ana", 500, "e5e27da1-d3a7-4cca-b991-2802f356be41");
# Python with requests library
import requests

def add_score(player_name, score, player_id):
  url = "https://leaderboard-game.vercel.app/api/add"
  params = {
    "key": "YOUR_API_KEY",
    "player_id": player_id,
    "player": player_name,
    "score": score
  }
  response = requests.get(url, params=params)
  print(response.json())

# Example usage
add_score("Ana", 500, "e5e27da1-d3a7-4cca-b991-2802f356be41")
// C++ with libcurl
#include <curl/curl.h>
#include <string>

size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
  size_t totalSize = size * nmemb;
  output->append((char*)contents, totalSize);
  return totalSize;
}

void addScore(const std::string& playerName, int score, const std::string& playerId) {
  CURL* curl = curl_easy_init();
  if (curl) {
    std::string url = "https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=" + playerId + "&player=" + playerName + "&score=" + std::to_string(score);
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    std::string response;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
    curl_easy_perform(curl);
    curl_easy_cleanup(curl);
    std::cout << "Response: " << response << std::endl;
  }
}
// C# with HttpClient (.NET)
using System;
using System.Net.Http;
using System.Threading.Tasks;

class ScoreDropClient {
  static readonly HttpClient client = new HttpClient();

  public async Task AddScore(string playerName, int score, string playerId) {
    string url = $"https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id={playerId}&player={Uri.EscapeDataString(playerName)}&score={score}";
    HttpResponseMessage response = await client.GetAsync(url);
    string responseBody = await response.Content.ReadAsStringAsync();
    Console.WriteLine(responseBody);
  }
}
// Construct 3 - AJAX event sheet
// On "Add Score" button clicked:
- AJAX: Request URL: "https://leaderboard-game.vercel.app/api/add?key=YOUR_API_KEY&player_id=" & PlayerID & "&player=" & PlayerName & "&score=" & Score
- AJAX: Method: GET

// On AJAX completed:
- System: Set text to AJAX.LastData
- JSON: Parse AJAX.LastData
- System: If JSON.Get("success") = true → Show "Score added!"

Name & Score Behavior

When you send a score with an existing player_id:

Example: If "Ana" (e5e27da1-d3a7-4cca-b991-2802f356be41) with 500 pts wants to change her name to "AnaPro", she can send any score (even 0) and the name will update instantly!

ScoreDrop-Unity SDK

Get Leaderboard

Returns the top scores of your leaderboard.

ENDPOINT

GET
/api/top?key=YOUR_API_KEY&limit=10&page=1&period=today

Parameters

Parameter Description
limit Number of scores to return (default: 10, max depends on your plan)
page Leaderboard page number (default: 1)
period Time filter: today, week, month, or all (default: all)

EXAMPLE (JavaScript)

fetch("https://leaderboard-game.vercel.app/api/top?key=YOUR_API_KEY&limit=20")
  .then(res => res.json())
  .then(data => console.log(data))

Delete Score

Delete a player's score from the leaderboard. Available on paid plans only.

ENDPOINT

GET
/api/delete?key=YOUR_API_KEY&player_id=UNIQUE_ID
/api/delete?key=YOUR_API_KEY&all=true

Parameters

Parameter Description
key Your API key (required)
player_id ID of the player to delete (required unless all=true)
all Set to true to delete all scores (paid plans only)

Response Example

{
  "leaderboard": "My Leaderboard",
  "plan": "free",
  "page": 1,
  "limit": 20,
  "total_scores": 2,
  "scores": [
    {
      "player": "Ana",
      "score": 500,
      "player_id": "e5e27da1-d3a7-4cca-b991-2802f356be41"
    },
    {
      "player": "John",
      "score": 300,
      "player_id": "a19c73f2-2b17-4c18-9b62-11c03a7a9d02"
    }
  ]
}

Add Score Responses

When adding a score, the API returns one of these messages:

Message Meaning
"Name updated (score unchanged)" Same player, lower score → only name changed
"Score updated (same score)" Same player, equal score → name and score updated
"Score updated (new score is higher)" Same player, higher score → new personal best
"Score added successfully" New player added within limits
"Score added (replaced lowest score in top)" New player added, replaced the lowest score

ℹ️ The player_id field is used to uniquely identify players. You should generate this ID in your game and send it with every score.


Error Responses

If the request fails, the API may return one of the following errors:

Error Meaning
Missing parameters Required parameters were not provided in the request
Leaderboard not found The API key is invalid or the leaderboard does not exist
Rate limit exceeded The player exceeded the allowed number of requests per minute (returns HTTP 429)
Score limit reached... The leaderboard is full and the new score doesn't beat the lowest (returns HTTP 403)
Daily limit reached... You've used all your allowed deletes for today (paid plans)

The API returns only the top scores based on your plan. All scores are stored (up to your plan's limit), but only the best are visible.

Rate Limits

To ensure fair usage and maintain server performance, the API enforces request limits per player (per IP), not per leaderboard.

If the rate limit is exceeded, the API will return a 429 Too Many Requests response.

Plan limits for donors

Plan Max Scores Rate Limit (per player) Deletes/day
Free 20 30/min 0
Basic ($5) 50 60/min 1
Pro ($20) 100 120/min 5
Unlimited ($50+) 500 300/min

⚠️ Keep your API key private. Anyone with access to it can submit or retrieve scores from your leaderboard. Do not expose it in public repositories or client builds when possible.

Create Content, Get Featured!

Are you a YouTuber, blogger, or game dev educator? We'd love to feature your tutorials!

Unity

Official package available

Godot

Example in docs, need tutorial!

Unreal

Example in docs, need tutorial!

Python

Example in docs

HTML/JS

Example in docs

Construct

Example in docs

Calling All Creators!

If you create a tutorial (video, blog, or code example) for ScoreDrop in any platform, we'll feature it here and promote it on our social media. Your content will help the community and give you exposure!

Send us your tutorial

The API is the same for all platforms. Only the HTTP request code changes. If you know how to make HTTP requests in your favorite engine, you already know how to use ScoreDrop!

ScoreDrop is currently in beta.

If this project gains traction and we secure sponsors, we'll move to a custom domain and roll out exciting improvements. Want to support the journey? Every donation helps us grow. Thank you!