← Back to Home

Setup Guide

How to integrate your game server with the Server Browser API

Overview

The Server Browser API allows game servers to advertise themselves and clients to discover available servers. The system uses a simple REST API with token-based authentication.

API Base URL: https://abagrow.pope.games/api

Server Registration (One-Time)

When your game server starts for the first time, it must register to obtain an authentication token. Tokens are independent of groups - you subscribe to groups separately.

Endpoint

POST /api/register

Request Body

{
  "serverId": "550e8400-e29b-41d4-a716-446655440000",  // UUID you generate
  "serverName": "My Awesome Server",
  "nonce": "123e4567-e89b-12d3-a456-426614174000"     // Random UUID for security
}

Response

{
  "success": true,
  "serverId": "550e8400-e29b-41d4-a716-446655440000",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "nonce": "123e4567-e89b-12d3-a456-426614174000",
  "message": "Server registered successfully. Use CLI to subscribe to groups."
}
Important: Store the token securely! You'll need it for all advertise requests.

Next Step: Subscribe to Groups

After registration, use the CLI tool to subscribe your token to groups:

deno run -A mod.ts subscribe --token "eyJ..." --group "myguild"

This allows your server to advertise in that group. Subscribe to multiple groups to advertise across them.

Rate Limiting

Maximum 4 server registrations per IP address. If exceeded, you'll receive a 429 error.

Server Advertising (Periodic)

Once registered, your server should advertise itself every 30 seconds to remain visible in the server list.

Endpoint

POST /api/{group}/advertise

Headers

Authorization: Bearer {your-token}

Request Body

{
  "serverId": "550e8400-e29b-41d4-a716-446655440000",
  "serverName": "My Awesome Server",
  "ipAddress": "0.0.0.0:7777",        // API will replace 0.0.0.0 with your real IP
  "currentPlayers": 2,
  "maxPlayers": 8,
  "gameVersion": "1.0.0",
  "lastSeen": 1709251200,
  "region": "us-east",                // Use: us-east, us-west, eu-west, eu-central, asia-pacific, oceania, global
  "isDedicated": true
}
The API automatically detects your public IP address. Use 0.0.0.0:port and it will be replaced.

Stale Server Removal

Servers not updated within 60 seconds are automatically removed from the listing.

Graceful Shutdown (Optional)

When your server shuts down, you can remove it immediately instead of waiting for the stale timeout:

DELETE /api/{group}/advertise

Headers (Required):

Authorization: Bearer {your-token}

Request Body: None required. The token identifies which server to delete.

Response:

{
  "success": true,
  "serverId": "550e8400-e29b-41d4-a716-446655440000",
  "message": "Server removed successfully"
}
Note: No request body needed! Your JWT token contains the serverId, so the API knows which server to delete. This is optional - if not called, the server will be automatically removed after 60 seconds of inactivity.

Client Integration

Game clients can retrieve the server list without authentication (for public groups).

Endpoint

GET /api/{group}/list

Response

{
  "servers": [
    {
      "serverId": "550e8400-e29b-41d4-a716-446655440000",
      "serverName": "My Awesome Server",
      "ipAddress": "203.0.113.42:7777",
      "currentPlayers": 2,
      "maxPlayers": 8,
      "gameVersion": "1.0.0",
      "lastSeen": 1709251200,
      "region": "us-east",              // Geographic location
      "isDedicated": true,
      "group": "myguild"                // Social organization
    }
  ],
  "total": 1,
  "group": "myguild"
}

List All Accessible Servers

Get all servers you have access to (public + subscribed private groups):

GET /api/list
Authorization: Bearer {your-token}

Without token: Returns only public servers. With token: Returns public + subscribed private servers.

CLI Tool - Managing Subscriptions

Use the CLI tool to manage which groups your token can advertise to.

Subscribe to a Group

deno run -A mod.ts subscribe --token "eyJ..." --group "myguild"

Unsubscribe from a Group

deno run -A mod.ts unsubscribe --token "eyJ..." --group "myguild"

List Token Subscriptions

deno run -A mod.ts list --token "eyJ..."
Note: Private groups require subscription. Public groups don't require subscription but you still need to subscribe to advertise.

Group Management

Groups are social organizations (clans, communities, tournaments, etc.) that can have servers in any region. Groups can be public or private.

Groups vs Regions: Groups are social (like "MyGuild"). Regions are geographical (like "us-east"). Groups can span multiple regions.

Create/Update Group

PUT /api/groups/{name}
{
  "isPublic": false,
  "description": "Private tournament servers"
}

List All Groups

GET /api/groups?public=true
Groups are automatically created when servers register. Default: isPublic: true

Code Examples

Unity C# Example

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class ServerAdvertiser : MonoBehaviour
{
    private string apiUrl = "https://abagrow.pope.games/api";
    private string groupName = "myguild";  // The group to advertise in
    private string authToken;
    private string serverId;

    void Start()
    {
        serverId = System.Guid.NewGuid().ToString();
        StartCoroutine(RegisterServer());
    }

    IEnumerator RegisterServer()
    {
        var nonce = System.Guid.NewGuid().ToString();
        var json = JsonUtility.ToJson(new {
            serverId = serverId,
            serverName = "My Unity Server",
            nonce = nonce
        });

        // Register without group
        using (UnityWebRequest www = UnityWebRequest.Post($"{apiUrl}/register", json, "application/json"))
        {
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                var response = JsonUtility.FromJson<RegisterResponse>(www.downloadHandler.text);
                authToken = response.token;

                // IMPORTANT: Use CLI to subscribe token to groups before advertising
                // deno run -A mod.ts subscribe --token "TOKEN" --group "myguild"

                StartCoroutine(AdvertisePeriodically());
            }
        }
    }

    IEnumerator AdvertisePeriodically()
    {
        while (true)
        {
            yield return new WaitForSeconds(30f);

            var json = JsonUtility.ToJson(new {
                serverId = serverId,
                serverName = "My Unity Server",
                ipAddress = "0.0.0.0:7777",
                currentPlayers = GetCurrentPlayers(),
                maxPlayers = 8,
                gameVersion = "1.0.0",
                lastSeen = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                region = "us-east",  // or us-west, eu-west, etc.
                isDedicated = true
            });

            using (UnityWebRequest www = UnityWebRequest.Post($"{apiUrl}/{groupName}/advertise", json, "application/json"))
            {
                www.SetRequestHeader("Authorization", $"Bearer {authToken}");
                yield return www.SendWebRequest();
            }
        }
    }

    int GetCurrentPlayers()
    {
        // Your player count logic here
        return 0;
    }

    void OnApplicationQuit()
    {
        // Gracefully remove server from listing on shutdown
        StartCoroutine(RemoveServer());
    }

    IEnumerator RemoveServer()
    {
        using (UnityWebRequest www = UnityWebRequest.Delete($"{apiUrl}/{groupName}/advertise"))
        {
            www.SetRequestHeader("Authorization", $"Bearer {authToken}");
            yield return www.SendWebRequest();

            if (www.result == UnityWebRequest.Result.Success)
            {
                Debug.Log("Server removed from listing");
            }
        }
    }
}

JavaScript/Deno Example

// Register server (no group in URL)
const response = await fetch('https://abagrow.pope.games/api/register', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    serverId: crypto.randomUUID(),
    serverName: 'My JS Server',
    nonce: crypto.randomUUID()
  })
});

const { token, serverId } = await response.json();

// IMPORTANT: Use CLI to subscribe token to groups before advertising
// deno run -A mod.ts subscribe --token "TOKEN" --group "myguild"

// Advertise periodically (to a specific group)
const groupName = 'myguild';  // Must be subscribed via CLI first
const advertiseInterval = setInterval(async () => {
  await fetch(`https://abagrow.pope.games/api/${groupName}/advertise`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    body: JSON.stringify({
      serverId: serverId,
      serverName: 'My JS Server',
      ipAddress: '0.0.0.0:3000',
      currentPlayers: 0,
      maxPlayers: 10,
      gameVersion: '1.0.0',
      lastSeen: Date.now(),
      region: 'us-east',  // or us-west, eu-west, asia-pacific, etc.
      isDedicated: true
    })
  });
}, 30000);

// Graceful shutdown - remove server from listing
process.on('SIGINT', async () => {
  clearInterval(advertiseInterval);

  await fetch(`https://abagrow.pope.games/api/${groupName}/advertise`, {
    method: 'DELETE',
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  console.log('Server removed from listing');
  process.exit(0);
});