Documentation
Public client API

Connect your game to Realm GameOps.

Authenticate players, track achievements, fetch live configuration, read leaderboard standings, and synchronize save data from a game client. Every request is scoped to the app environment attached to its API key.

Base URL

https://www.realmgames.com/v1

Content type

application/json

All responses, including errors, use JSON.

Before you make a request

  1. 01Create or select an active app environment.
  2. 02Create a game-client key under Manage → API Keys.
  3. 03Create and activate a leaderboard for that same environment.

Authentication

Send an API key with every request

Use the X-Realm-API-Key header for the game-client key. Keys begin with rg_client_ and are shown only once when created. Player-authorized requests also send the session returned by player login.

Game client · every request

X-Realm-API-Key: rg_client_YOUR_KEY

Player · when required

Authorization: Bearer rg_player_SESSION
ServiceRead · GET/HEADWrite · POST/PUT/DELETE
Player Authplayer-auth:readplayer-auth:write
Leaderboardsleaderboards:readleaderboards:write
Achievementsachievements:readachievements:write
Remote Configremote-config:readNot used by public API
Cloud Savescloud-saves:readcloud-saves:write

Write permission always includes read permission for the same service; write-only service access is not valid.

Treat game-client keys as environment credentials. Use separate keys for development, staging, and production, rotate exposed keys, and never commit production keys to source control.

POST /v1/player-auth/device

Login with device

Creates or resolves an anonymous player using a stable device identifier, then returns a new player session token. The endpoint must be enabled under Operate → Player Auth for the API key’s environment.

JSON fieldRequiredDescription
deviceIdPlatform strategyStable device identifier, maximum 512 characters
displayNameNoInitial or updated player-facing name, maximum 80 characters
platformNoClient platform such as ios, android, or windows

With the Realm-generated strategy, omit deviceId on the first request. Store the returned device.deviceId securely and send it on later logins to recover the same player.

cURL
curl --request POST \
  --url 'https://www.realmgames.com/v1/player-auth/device' \
  --header 'Content-Type: application/json' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --data '{
    "deviceId": "ios-vendor-device-id",
    "displayName": "Nova",
    "platform": "ios"
  }'
Unity / .NET C#
[System.Serializable]
public class DeviceLoginRequest
{
    public string deviceId;
    public string displayName;
    public string platform;
}

IEnumerator LoginWithDevice(string deviceId)
{
    var payload = new DeviceLoginRequest {
        deviceId = deviceId,
        displayName = "Nova",
        platform = Application.platform.ToString().ToLowerInvariant()
    };
    byte[] body = Encoding.UTF8.GetBytes(JsonUtility.ToJson(payload));
    string url = BaseUrl + "/v1/player-auth/device";

    using (var request = new UnityWebRequest(url, "POST"))
    {
        request.uploadHandler = new UploadHandlerRaw(body);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
            Debug.Log(request.downloadHandler.text);
        else
            Debug.LogError(request.downloadHandler.text);
    }
}
A successful response returns player.id, session.accessToken, and session.expiresAt. Store the player token securely; a new device login revokes the previous active session for that device.
GET /v1/leaderboard

List leaderboards

Returns active leaderboards in the API key’s environment. Results are ordered by name.

QueryTypeDescription
limitinteger1–100, default 25
offsetinteger0–100,000, default 0
cURL
curl --request GET \
  --url 'https://www.realmgames.com/v1/leaderboard?limit=25&offset=0' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY'
Unity / .NET C#
IEnumerator ListLeaderboards()
{
    string url = BaseUrl + "/v1/leaderboard?limit=25&offset=0";

    using (UnityWebRequest request = UnityWebRequest.Get(url))
    {
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
            Debug.Log(request.downloadHandler.text);
        else
            Debug.LogError(request.downloadHandler.text);
    }
}
GET /v1/leaderboard/:leaderboardKey

Get leaderboard standings

Returns ranked entries for one active leaderboard. Use its key—not its UUID—in the URL. Ranking direction follows the leaderboard’s ascending or descending configuration.

ParameterLocationDescription
leaderboardKeypathLeaderboard key, such as season-score
limitquery1–100, default 25
offsetquery0–100,000, default 0
cURL
curl --request GET \
  --url 'https://www.realmgames.com/v1/leaderboard/season-score?limit=25&offset=0' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY'
Unity / .NET C#
IEnumerator GetLeaderboard(string leaderboardKey)
{
    string key = UnityWebRequest.EscapeURL(leaderboardKey);
    string url = BaseUrl + "/v1/leaderboard/" + key +
                 "?limit=25&offset=0";

    using (UnityWebRequest request = UnityWebRequest.Get(url))
    {
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
            Debug.Log(request.downloadHandler.text);
        else
            Debug.LogError(request.downloadHandler.text);
    }
}
GET /v1/leaderboard/:leaderboardKey/players/:playerId

Get a player’s rank

Returns a single player’s score and current rank. A player ID can be up to 128 characters and should be URL encoded.

cURL
curl --request GET \
  --url 'https://www.realmgames.com/v1/leaderboard/season-score/players/019faa5e-5292-75ae-8c05-e89965aa0d32' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY'
Unity / .NET C#
IEnumerator GetPlayerRank(string leaderboardKey, string playerId)
{
    string key = UnityWebRequest.EscapeURL(leaderboardKey);
    string player = UnityWebRequest.EscapeURL(playerId);
    string url = BaseUrl + "/v1/leaderboard/" + key +
                 "/players/" + player;

    using (UnityWebRequest request = UnityWebRequest.Get(url))
    {
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
            Debug.Log(request.downloadHandler.text);
        else
            Debug.LogError(request.downloadHandler.text);
    }
}
POST /v1/leaderboard/:leaderboardKey/scores

Submit or improve a score

Requires a player session from device login. The authenticated player ID is used automatically, so a client cannot submit a score for another player. On descending boards, higher wins; on ascending boards, lower wins. A valid but non-improving score returns accepted: false.

Send both credentials: the environment’s rg_client_ key in X-Realm-API-Key and the logged-in player’s rg_player_ token as a Bearer token.

JSON fieldRequiredDescription
scoreYesFinite number; integer and duration boards require whole numbers
displayNameNoPlayer-facing name, maximum 80 characters
metadataNoJSON object, maximum 8 KB
playerIdNoDeprecated; if sent, it must match the authenticated player
cURL
curl --request POST \
  --url 'https://www.realmgames.com/v1/leaderboard/season-score/scores' \
  --header 'Content-Type: application/json' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'Authorization: Bearer rg_player_SESSION' \
  --data '{
    "displayName": "Nova",
    "score": 18450,
    "metadata": { "season": 4, "character": "mage" }
  }'
Unity / .NET C#
[System.Serializable]
public class ScoreMetadata
{
    public int season;
    public string character;
}

[System.Serializable]
public class ScoreSubmission
{
    public string displayName;
    public long score;
    public ScoreMetadata metadata;
}

IEnumerator SubmitScore(string leaderboardKey, string playerAccessToken)
{
    var payload = new ScoreSubmission {
        displayName = "Nova",
        score = 18450,
        metadata = new ScoreMetadata { season = 4, character = "mage" }
    };
    byte[] body = Encoding.UTF8.GetBytes(JsonUtility.ToJson(payload));
    string key = UnityWebRequest.EscapeURL(leaderboardKey);
    string url = BaseUrl + "/v1/leaderboard/" + key + "/scores";

    using (var request = new UnityWebRequest(url, "POST"))
    {
        request.uploadHandler = new UploadHandlerRaw(body);
        request.downloadHandler = new DownloadHandlerBuffer();
        request.SetRequestHeader("Content-Type", "application/json");
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        request.SetRequestHeader("Authorization", "Bearer " + playerAccessToken);
        yield return request.SendWebRequest();

        if (request.result == UnityWebRequest.Result.Success)
            Debug.Log(request.downloadHandler.text);
        else
            Debug.LogError(request.downloadHandler.text);
    }
}
Unity setup: add using System.Collections;, using System.Text;, and using UnityEngine.Networking;. Define BaseUrl and ApiKey in your client configuration, and pass the player token returned by login when submitting scores.
GET POST /v1/achievements

Achievements

List active achievement definitions, load the authenticated player’s progress, and report absolute or incremental progress. Secret achievements remain hidden until unlocked.

MethodPathPurpose
GET/v1/achievementsList active, non-secret definitions
GET/v1/achievements/:keyRead one non-secret achievement
GET/v1/achievements/playerList the logged-in player’s visible progress
POST/v1/achievements/:key/progressSet progress or increment it atomically

Player progress endpoints require both credentials. Send the environment API key with X-Realm-API-Key and the player session with Authorization: Bearer.

Increment progress
curl --request POST \
  --url 'https://www.realmgames.com/v1/achievements/monster-hunter/progress' \
  --header 'Content-Type: application/json' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'Authorization: Bearer rg_player_SESSION' \
  --data '{ "increment": 1 }'
Response
{
  "environment": "production",
  "playerId": "0198...",
  "achievement": {
    "key": "monster-hunter",
    "name": "Monster Hunter",
    "points": 50,
    "target": 10,
    "progress": 7,
    "percentComplete": 70,
    "unlocked": false,
    "unlockedAt": null
  }
}
JSON fieldUseBehavior
progressAbsoluteSets a new high-water mark; progress never moves backward
incrementRelativeAtomically adds to current progress

Send exactly one field. Values must be finite, non-negative numbers. Progress is capped at the achievement target, and the first request to reach that target records unlockedAt.

GET /v1/remote-config

Fetch Remote Config

Returns every enabled key in the API key’s environment as a single JSON object. Values preserve their JSON types, so booleans, numbers, strings, arrays, and objects arrive without client-side conversion.

Store the response’s ETag header and send it as If-None-Match on the next poll. Realm returns 304 Not Modified with no body when configuration has not changed.

MethodPathPurpose
GET/v1/remote-configFetch all enabled values and response metadata
GET/v1/remote-config/:keyFetch one enabled value, its version, and update time
cURL
curl --request GET \
  --url 'https://www.realmgames.com/v1/remote-config' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'If-None-Match: "LAST_ETAG"'
Response
{
  "environment": "production",
  "values": {
    "gameplay.double_xp": true,
    "economy.daily_coins": 250,
    "ui.season_theme": "winter"
  },
  "meta": {
    "count": 3,
    "etag": "CONFIG_ETAG",
    "updatedAt": "2026-08-04T18:30:00.000Z"
  }
}
Unity / .NET C#
IEnumerator FetchRemoteConfig(string previousEtag = null)
{
    string url = BaseUrl + "/v1/remote-config";
    using (UnityWebRequest request = UnityWebRequest.Get(url))
    {
        request.SetRequestHeader("X-Realm-API-Key", ApiKey);
        if (!string.IsNullOrEmpty(previousEtag))
            request.SetRequestHeader("If-None-Match", previousEtag);

        yield return request.SendWebRequest();
        if (request.responseCode == 304)
            yield break;

        if (request.result == UnityWebRequest.Result.Success)
        {
            string etag = request.GetResponseHeader("ETag");
            Debug.Log(request.downloadHandler.text);
        }
        else
            Debug.LogError(request.downloadHandler.text);
    }
}

Key behavior

  • Disabled keys are omitted and single-key reads return 404.
  • The API key selects the environment; clients cannot override it in a query.
  • Keys may use letters, numbers, dots, underscores, and hyphens.
GET PUT DELETE /v1/cloud-saves

Cloud save slots

Store up to 20 JSON save slots per player and environment, with a 1 MB limit per slot. Every endpoint requires both the environment API key and the player’s Bearer session token.

MethodPathPurpose
GET/v1/cloud-savesList the authenticated player’s save slot metadata
GET/v1/cloud-saves/:slotKeyRead one slot and its JSON data
PUT/v1/cloud-saves/:slotKeyCreate or replace a slot
DELETE/v1/cloud-saves/:slotKeyPermanently delete a slot

Send expectedVersion: 0 when creating a new slot. For later writes, use the version returned by the previous read or write. A stale version returns 409 cloud_save_conflict instead of overwriting newer progress.

Write with cURL
curl --request PUT \
  --url 'https://www.realmgames.com/v1/cloud-saves/main' \
  --header 'Content-Type: application/json' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'Authorization: Bearer rg_player_SESSION' \
  --data '{
    "data": {
      "level": 12,
      "checkpoint": "forest-gate",
      "inventory": ["map", "key"]
    },
    "expectedVersion": 0
  }'
Read with cURL
curl --request GET \
  --url 'https://www.realmgames.com/v1/cloud-saves/main' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'Authorization: Bearer rg_player_SESSION'
Slot keys are 1–64 characters and may contain letters, numbers, dots, underscores, and hyphens. Data may be any valid JSON value. List responses omit payload data to remain lightweight.
GET POST /v1/live-communication/messages

Live Communication

Deliver active, scheduled messages to game clients without releasing a new build. Messages can be grouped into channels, styled by severity, and linked to an HTTPS destination or game deep link.

MethodPathPurpose
GET/v1/live-communication/messagesList messages that are live now
GET/v1/live-communication/messages/:keyRead one active message
POST/v1/live-communication/messages/:key/acknowledgeRecord that the logged-in player saw or dismissed it

Clients only receive messages with an active publishing status whose optional start and end times include the current server time. Draft, archived, future, and expired messages are excluded automatically.

List a channel
curl --request GET \
  --url 'https://www.realmgames.com/v1/live-communication/messages?channel=news&limit=20' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY'
Response
{
  "environment": "production",
  "messages": [{
    "key": "double-xp-weekend",
    "channel": "news",
    "title": "Double XP weekend",
    "body": "Earn twice the XP through Sunday.",
    "severity": "success",
    "action": {
      "label": "Play now",
      "url": "mygame://events/double-xp"
    },
    "startsAt": "2026-08-07T17:00:00.000Z",
    "endsAt": "2026-08-10T07:00:00.000Z",
    "publishedAt": "2026-08-04T18:30:00.000Z",
    "updatedAt": "2026-08-04T18:30:00.000Z"
  }],
  "paging": {
    "limit": 20,
    "hasMore": false,
    "nextCursor": null
  }
}
Acknowledge a message
curl --request POST \
  --url 'https://www.realmgames.com/v1/live-communication/messages/double-xp-weekend/acknowledge' \
  --header 'X-Realm-API-Key: rg_client_YOUR_KEY' \
  --header 'Authorization: Bearer rg_player_SESSION'

Client behavior

  • Use channel to populate separate surfaces such as news, inbox, and service status.
  • Acknowledgement is idempotent. Repeating it preserves the player’s original timestamp.
  • Reads need the API key; acknowledgement also needs the player Bearer session.
Pagination uses the response’s ISO-8601 nextCursor. Pass it back as ?cursor=…. Limits range from 1 to 100.

Errors

Consistent JSON errors

Check both the HTTP status and the machine-readable error code. An inactive environment returns a specific message so clients can distinguish configuration problems from invalid credentials.

Error response
{
  "error": {
    "code": "environment_inactive",
    "message": "The Production environment is currently maintenance. Activate it before using this API key."
  }
}
StatusMeaning
400Invalid request, score, slot key, or version
401Missing or invalid API key or player session
403Inactive environment, app, player, or insufficient API-key permission
404Requested leaderboard, player, or save slot not found
409Cloud save version conflict or slot limit reached
413Cloud save exceeds 1 MB
500Server error

Ready to connect?

Create an API key and make your first request.

Open dashboard