Core Cells
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.
Everything you need to build, deploy, and scale multiplayer games
Each project gets a unique key for secure access and complete data isolation between games.
Players register once and can access multiple games with a single account.
Built-in support for matchmaking, real-time game sessions, and player state management.
Comprehensive REST API for multiplayer game development
Integrate our API into your game with our easy-to-use SDKs
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; }
}
}
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 ===");
}
}
SDK.cs file to your projectProgram.cs fileyour-api-key-here with your actual API keyUse our REST API directly from any platform or language. All endpoints return JSON responses with consistent error handling.
Description: Creates a new player in the game. Returns a player_id and private_key needed for future requests.
{
"player_name": "TestPlayer",
"player_data": {
"level": 1,
"score": 0,
"inventory": ["sword","shield"]
}
}
{
"success": true,
"player_id": "7",
"private_key": "46702c9b906e3361c26dbcd605ee9183",
"player_name": "TestPlayer",
"game_id": 4
}
Description: Updates player info such as active status. This does not change player data like level or inventory (those are in /game_data.php).
{}
{
"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"
}
}
Description: Retrieves a list of all players in the game. Useful for admin dashboards or multiplayer matchmaking.
{
"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"}
}
Description: Retrieves the global game data, including text, settings, and last update timestamp. Used to sync clients with the server.
{
"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"
}
}
Description: Updates global game data. For example, changing settings or max players. Requires API key authentication.
{
"game_settings": {
"difficulty": "hard",
"max_players": 10
},
"last_updated": "2025-01-13T12:00:00Z"
}
{
"success": true,
"message": "Game data updated successfully",
"updated_at": "2026-01-13 14:24:23"
}
Description: Retrieves a specific player's data using their private_key. Includes level, score, and inventory.
{
"success": true,
"type": "player",
"player_id": 7,
"player_name": "TestPlayer",
"data": {
"level": 1,
"score": 0,
"inventory": ["sword","shield"]
}
}
Description: Updates a specific player's data like level, score, inventory, and last played timestamp.
{
"level": 2,
"score": 100,
"inventory": ["sword","shield","potion"],
"last_played": "2025-01-13T12:30:00Z"
}
{
"success": true,
"message": "Player data updated successfully",
"updated_at": "2026-01-13 14:27:10"
}
Description: Retrieves the current server time in multiple formats including UTC timestamp and human-readable format.
{
"success": true,
"utc": "2025-01-14T16:24:00+00:00",
"timestamp": 1736864640,
"readable": "2025-01-14 16:24:00 UTC"
}
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"
}
}