Multiplayer API Logo

Multiplayer API

Core Cells

Multiplayer API for
Game Developers

A scalable, secure REST API to connect any game to a shared multiplayer backend. Manage users, project keys, JSON game states, matchmaking, and RTS sessions — all from one unified interface.

Powerful Features

Everything you need to build, deploy, and scale multiplayer games

Per-Game API Keys

Each project gets a unique key for secure access and complete data isolation between games.

Shared User Base

Players register once and can access multiple games with a single account.

Multiplayer Logic

Built-in support for matchmaking, real-time game sessions, and player state management.

API Endpoints

Comprehensive REST API for multiplayer game development

Method
Endpoint
Description

Game Players

POST
/php/game_players.php
Register new Player with API key, returns Player private key
PUT
/php/game_players.php
Authenticate Player with API key and Player private key
GET
/php/game_players.php
List all Players with API key and API private key

Game Data

GET
/php/game_data.php
Get Game data (requires API key, requires API private key)
PUT
/php/game_data.php
Update Game data (requires API key, requires API private key)
GET
/php/game_data.php
Get Player data (requires API key, requires Player private key)
PUT
/php/game_data.php
Update Player data (requires API key, requires Player private key)

Server Data

GET
/php/time.php
Get server time

SDK for Developers

Integrate our API into your game with our easy-to-use SDKs

C# / Unity SDK

Seamlessly integrate the API into your Unity projects with our C# SDK. Handles authentication, HTTP requests, JSON parsing, and project key management.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace michitai
{
    public class GameSDK
    {
        private readonly string _apiToken;
        private readonly string _apiPrivateToken;
        private readonly string _baseUrl;
        private static readonly HttpClient _http = new HttpClient();

        private readonly JsonSerializerOptions _jsonOptions = new JsonSerializerOptions
        {
            PropertyNameCaseInsensitive = true,
            DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
        };

        public GameSDK(string apiToken, string apiPrivateToken, string baseUrl = "https://api.michitai.com/v1/php/")
        {
            _apiToken = apiToken;
            _apiPrivateToken = apiPrivateToken;
            _baseUrl = baseUrl.EndsWith("/") ? baseUrl : baseUrl + "/";
        }

        private string Url(string endpoint, string extra = "")
        {
            return $"{_baseUrl}{endpoint}?api_token={_apiToken}{extra}";
        }

        private async Task<T> Send<T>(HttpMethod method, string url, object body = null)
        {
            var req = new HttpRequestMessage(method, url);

            if (body != null)
            {
                string json = JsonSerializer.Serialize(body, _jsonOptions);
                req.Content = new StringContent(json, Encoding.UTF8, "application/json");
            }

            var res = await _http.SendAsync(req);
            string str = await res.Content.ReadAsStringAsync();

            return JsonSerializer.Deserialize<T>(str, _jsonOptions);
        }

        // ------------------------------------
        // PLAYER API
        // ------------------------------------

        public Task<PlayerRegisterResponse> RegisterPlayer(string name, object playerData)
        {
            return Send<PlayerRegisterResponse>(
                HttpMethod.Post,
                Url("game_players.php"),
                new { player_name = name, player_data = playerData }
            );
        }

        public Task<PlayerAuthResponse> AuthenticatePlayer(string playerToken)
        {
            return Send<PlayerAuthResponse>(
                HttpMethod.Put,
                Url("game_players.php", $"&game_player_token={playerToken}")
            );
        }

        public Task<PlayerListResponse> GetAllPlayers()
        {
            return Send<PlayerListResponse>(HttpMethod.Get, Url("game_players.php", $"&api_private_token={_apiPrivateToken}"));
        }

        // ------------------------------------
        // GAME DATA
        // ------------------------------------

        public Task<GameDataResponse> GetGameData()
        {
            return Send<GameDataResponse>(HttpMethod.Get, Url("game_data.php", $"&api_private_token={_apiPrivateToken}"));
        }

        public Task<SuccessResponse> UpdateGameData(object data)
        {
            return Send<SuccessResponse>(HttpMethod.Put, Url("game_data.php", $"&api_private_token={_apiPrivateToken}"), data);
        }

        // ------------------------------------
        // PLAYER DATA
        // ------------------------------------

        public Task<PlayerDataResponse> GetPlayerData(string playerToken)
        {
            return Send<PlayerDataResponse>(
                HttpMethod.Get,
                Url("game_data.php", $"&game_player_token={playerToken}")
            );
        }

        public Task<SuccessResponse> UpdatePlayerData(string playerToken, object data)
        {
            return Send<SuccessResponse>(
                HttpMethod.Put,
                Url("game_data.php", $"&game_player_token={playerToken}"),
                data
            );
        }

        // ------------------------------------
        // SERVER TIME
        // ------------------------------------

        public Task<ServerTimeResponse> GetServerTime()
        {
            return Send<ServerTimeResponse>(
                HttpMethod.Get,
                $"{_baseUrl}time.php?api_key={_apiToken}"
            );
        }
    }

    // ------------------------------------
    // MODELS
    // ------------------------------------

    public class PlayerRegisterResponse
    {
        public bool Success { get; set; }
        public string Player_id { get; set; }
        public string Private_key { get; set; }
        public string Player_name { get; set; }
        public int Game_id { get; set; }
    }

    public class PlayerAuthResponse
    {
        public bool Success { get; set; }
        public PlayerInfo Player { get; set; }
    }

    public class PlayerListResponse
    {
        public bool Success { get; set; }
        public int Count { get; set; }
        public List<PlayerShort> Players { get; set; }
    }

    public class PlayerShort
    {
        public int Id { get; set; }
        public string Player_name { get; set; }
        public int Is_active { get; set; }
        public string Last_login { get; set; }
        public string Created_at { get; set; }
    }

    public class PlayerInfo
    {
        public int Id { get; set; }
        public int Game_id { get; set; }
        public string Player_name { get; set; }
        public Dictionary<string, object> Player_data { get; set; }
        public int Is_active { get; set; }
        public string Last_login { get; set; }
        public string Created_at { get; set; }
        public string Updated_at { get; set; }
    }

    public class GameDataResponse
    {
        public bool Success { get; set; }
        public string Type { get; set; }
        public int Game_id { get; set; }
        public Dictionary<string, object> Data { get; set; }
    }

    public class PlayerDataResponse
    {
        public bool Success { get; set; }
        public string Type { get; set; }
        public int Player_id { get; set; }
        public string Player_name { get; set; }
        public Dictionary<string, object> Data { get; set; }
    }

    public class SuccessResponse
    {
        public bool Success { get; set; }
        public string Message { get; set; }
        public string Updated_at { get; set; }
    }

    public class ServerTimeResponse
    {
        public bool Success { get; set; }
        public string Utc { get; set; }
        public long Timestamp { get; set; }
        public string Readable { get; set; }
    }
}

Example Usage

Here's a complete example of how to use the michitai SDK in your C# application. This example demonstrates common operations like fetching game data, updating player information, and handling authentication.

using System;
using System.Threading.Tasks;
using System.Text.Json;
using michitai;

public class Game
{
    private static GameSDK sdk;

    public static async Task Main()
    {
        Console.WriteLine("=== MICHITAI Game SDK Usage Example ===\n");

        // 1️⃣ Initialize SDK
        sdk = new GameSDK("YOUR_API_TOKEN", "YOUR_API_PRIVATE_TOKEN");
        Console.WriteLine("[INIT] SDK initialized\n");

        // 2️⃣ Register Player
        Console.WriteLine("[PLAYER] Registering new player...");
        var reg = await sdk.RegisterPlayer("TestPlayer", new
        {
            level = 1,
            score = 0,
            inventory = new[] { "sword", "shield" }
        });

        string playerToken = reg.Private_key;
        int playerId = int.Parse(reg.Player_id);

        Console.WriteLine($"[PLAYER] Registered: ID={playerId}, Token={playerToken}\n");

        // 3️⃣ Authenticate Player
        Console.WriteLine("[PLAYER] Authenticating player...");
        var auth = await sdk.AuthenticatePlayer(playerToken);

        if (auth.Success)
        {
            var pdata = auth.Player.Player_data;
            int level = pdata.ContainsKey("level") ? ((JsonElement)pdata["level"]).GetInt32() : 0;

            Console.WriteLine($"[PLAYER] Authenticated: {auth.Player.Player_name} (Level={level})\n");
        }
        else
        {
            Console.WriteLine("[PLAYER] Authentication failed\n");
        }

        // 4️⃣ List all players
        Console.WriteLine("[ADMIN] Fetching all players...");
        var allPlayers = await sdk.GetAllPlayers();
        Console.WriteLine($"[ADMIN] Total players: {allPlayers.Count}");
        foreach (var p in allPlayers.Players)
        {
            Console.WriteLine($" - ID={p.Id}, Name={p.Player_name}, Active={p.Is_active}");
        }
        Console.WriteLine();

        // 5️⃣ Get global game data
        Console.WriteLine("[GAME] Loading game data...");
        var gameData = await sdk.GetGameData();
        Console.WriteLine($"[GAME] Game ID={gameData.Game_id}, Settings={gameData.Data.Count}\n");

        // 6️⃣ Update global game data
        Console.WriteLine("[GAME] Updating game settings...");
        var updateGame = await sdk.UpdateGameData(new
        {
            game_settings = new { difficulty = "hard", max_players = 10 },
            last_updated = DateTime.UtcNow.ToString("o")
        });
        Console.WriteLine($"[GAME] {updateGame.Message} at {updateGame.Updated_at}\n");

        // 7️⃣ Get player-specific data
        Console.WriteLine("[PLAYER] Loading player data...");
        var playerData = await sdk.GetPlayerData(playerToken);

        var pDataDict = playerData.Data;
        int playerLevel = pDataDict.ContainsKey("level") ? ((JsonElement)pDataDict["level"]).GetInt32() : 0;
        int playerScore = pDataDict.ContainsKey("score") ? ((JsonElement)pDataDict["score"]).GetInt32() : 0;
        string[] inventory = pDataDict.ContainsKey("inventory")
            ? JsonSerializer.Deserialize<string[]>(((JsonElement)pDataDict["inventory"]).GetRawText())
            : new string[0];

        Console.WriteLine($"[PLAYER] Level={playerLevel}, Score={playerScore}, Inventory=[{string.Join(", ", inventory)}]\n");

        // 8️⃣ Update player data
        Console.WriteLine("[PLAYER] Updating player progress...");
        var updatedPlayer = await sdk.UpdatePlayerData(playerToken, new
        {
            level = 2,
            score = 100,
            inventory = new[] { "sword", "shield", "potion" },
            last_played = DateTime.UtcNow.ToString("o")
        });
        Console.WriteLine($"[PLAYER] {updatedPlayer.Message} at {updatedPlayer.Updated_at}\n");

        // 9️⃣ Get server time
        Console.WriteLine("[SERVER] Getting server time...");
        var serverTime = await sdk.GetServerTime();
        if (serverTime.Success)
        {
            Console.WriteLine($"[SERVER] Server time (UTC): {serverTime.Utc}");
            Console.WriteLine($"[SERVER] Timestamp: {serverTime.Timestamp}");
            Console.WriteLine($"[SERVER] Readable: {serverTime.Readable}\n");
        }
        else
        {
            Console.WriteLine("[SERVER] Failed to get server time\n");
        }

        Console.WriteLine("=== Demo Complete ===");
    }
}
How to use this example
  1. Create a new C# console application in Visual Studio or your preferred IDE
  2. Add the downloaded SDK.cs file to your project
  3. Copy this example code into your Program.cs file
  4. Replace your-api-key-here with your actual API key
  5. Run the application to see the SDK in action

Multiplayer API – Core Cells

Use our REST API directly from any platform or language. All endpoints return JSON responses with consistent error handling.

POST /v1/php/game_players.php?api_token=YOUR_API_KEY

Description: Creates a new player in the game. Returns a player_id and private_key needed for future requests.

Request Body:
{
  "player_name": "TestPlayer",
  "player_data": {
    "level": 1,
    "score": 0,
    "inventory": ["sword","shield"]
  }
}
Response:
{
  "success": true,
  "player_id": "7",
  "private_key": "46702c9b906e3361c26dbcd605ee9183",
  "player_name": "TestPlayer",
  "game_id": 4
}
PUT /v1/php/game_players.php?api_token=YOUR_API_KEY&game_player_token=PLAYER_PRIVATE_KEY

Description: Updates player info such as active status. This does not change player data like level or inventory (those are in /game_data.php).

Request Body:
{}
Response:
{
  "success": true,
  "player": {
    "id": 7,
    "game_id": 4,
    "player_name": "TestPlayer",
    "player_data": {
      "level": 1,
      "score": 0,
      "inventory": ["sword","shield"]
    },
    "is_active": 1,
    "last_login": null,
    "created_at": "2026-01-13 14:21:16",
    "updated_at": "2026-01-13 14:21:16"
  }
}
GET /v1/php/game_players.php?api_token=YOUR_API_KEY&api_private_token=YOUR_API_PRIVATE_TOKEN

Description: Retrieves a list of all players in the game. Useful for admin dashboards or multiplayer matchmaking.

Response:
{
  "success": true,
  "count": 7,
  "players": [
    {"id":3,"player_name":"TestPlayer","is_active":1,"last_login":null,"created_at":"2026-01-13 12:30:47"},
    {"id":7,"player_name":"TestPlayer","is_active":1,"last_login":"2026-01-13 14:22:33","created_at":"2026-01-13 14:21:16"}
}
GET /v1/php/game_data.php?api_token=YOUR_API_KEY&api_private_token=YOUR_API_PRIVATE_TOKEN

Description: Retrieves the global game data, including text, settings, and last update timestamp. Used to sync clients with the server.

Response:
{
  "success": true,
  "type": "game",
  "game_id": 4,
  "data": {
    "text": "hello world",
    "game_settings": {
      "difficulty": "hard",
      "max_players": 10
    },
    "last_updated": "2025-01-13T12:00:00Z"
  }
}
PUT /v1/php/game_data.php?api_token=YOUR_API_KEY&api_private_token=YOUR_API_PRIVATE_TOKEN

Description: Updates global game data. For example, changing settings or max players. Requires API key authentication.

Request Body:
{
  "game_settings": {
    "difficulty": "hard",
    "max_players": 10
  },
  "last_updated": "2025-01-13T12:00:00Z"
}
Response:
{
  "success": true,
  "message": "Game data updated successfully",
  "updated_at": "2026-01-13 14:24:23"
}
GET /v1/php/game_data.php?api_token=YOUR_API_KEY&game_player_token=PLAYER_PRIVATE_KEY

Description: Retrieves a specific player's data using their private_key. Includes level, score, and inventory.

Response:
{
  "success": true,
  "type": "player",
  "player_id": 7,
  "player_name": "TestPlayer",
  "data": {
    "level": 1,
    "score": 0,
    "inventory": ["sword","shield"]
  }
}
PUT /v1/php/game_data.php?api_token=YOUR_API_KEY&game_player_token=PLAYER_PRIVATE_KEY

Description: Updates a specific player's data like level, score, inventory, and last played timestamp.

Request Body:
{
  "level": 2,
  "score": 100,
  "inventory": ["sword","shield","potion"],
  "last_played": "2025-01-13T12:30:00Z"
}
Response:
{
  "success": true,
  "message": "Player data updated successfully",
  "updated_at": "2026-01-13 14:27:10"
}
GET /v1/php/time.php?api_key=YOUR_API_KEY

Description: Retrieves the current server time in multiple formats including UTC timestamp and human-readable format.

Response:
{
  "success": true,
  "utc": "2025-01-14T16:24:00+00:00",
  "timestamp": 1736864640,
  "readable": "2025-01-14 16:24:00 UTC"
}
Error Response (401 Unauthorized):

Description: Shows what happens when a request is sent with an invalid or missing API key.

{
  "success": false,
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}