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.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Michitai.SDK
{
///
/// Client for interacting with the Michitai Game Platform API
///
public class MichitaiClient
{
private readonly HttpClient _httpClient;
private const string API_BASE_URL = "https://api.michitai.com/v1/php";
private readonly string _apiKey;
///
/// Event raised when authentication is required
///
public event Action OnAuthenticationRequired;
///
/// Initialize a new instance of the MichitaiClient with API key authentication
///
/// Your Michitai API key
/// Thrown when API key is null or empty
public MichitaiClient(string apiKey)
{
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentException("API key is required", nameof(apiKey));
_apiKey = apiKey;
_httpClient = new HttpClient();
_httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
_httpClient.DefaultRequestHeaders.Add("X-Requested-With", "XMLHttpRequest");
_httpClient.DefaultRequestHeaders.Add("X-API-Key", _apiKey);
}
#region Game Data
///
/// Get game data
///
/// Game data
public async Task GetGameDataAsync()
{
return await GetAsync("/games/data");
}
///
/// Update game data (admin only)
///
/// Updated game data
/// Updated game data
public async Task UpdateGameDataAsync(GameData gameData)
{
return await PutAsync("/games/data", gameData);
}
#endregion
#region Player Data
///
/// Get current player's data
///
/// Player data
public async Task GetPlayerDataAsync()
{
return await GetAsync("/games/players/data");
}
///
/// Update current player's data
///
/// Updated player data
/// Updated player data
public async Task UpdatePlayerDataAsync(PlayerData playerData)
{
return await PutAsync("/games/players/data", playerData);
}
///
/// List all players (admin only)
///
/// List of players
public async Task> ListPlayersAsync()
{
return await GetAsync>("/games/players");
}
#endregion
#region HTTP Methods
private async Task GetAsync(string endpoint)
{
try
{
var url = endpoint.StartsWith("http") ? endpoint : $"{API_BASE_URL}/{endpoint.TrimStart('/')}";
var response = await _httpClient.GetAsync(url);
await HandleResponse(response);
var content = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize(content);
}
catch (HttpRequestException ex)
{
throw new MichitaiException("Network error occurred", ex);
}
}
private async Task PostAsync(string endpoint, object data)
{
try
{
var content = new StringContent(
JsonSerializer.Serialize(data),
Encoding.UTF8,
"application/json"
);
var url = endpoint.StartsWith("http") ? endpoint : $"{API_BASE_URL}/{endpoint.TrimStart('/')}";
var response = await _httpClient.PostAsync(url, content);
await HandleResponse(response);
var responseContent = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize(responseContent);
}
catch (HttpRequestException ex)
{
throw new MichitaiException("Network error occurred", ex);
}
}
private async Task PutAsync(string endpoint, object data)
{
try
{
var content = new StringContent(
JsonSerializer.Serialize(data),
Encoding.UTF8,
"application/json"
);
var url = endpoint.StartsWith("http") ? endpoint : $"{API_BASE_URL}/{endpoint.TrimStart('/')}";
var response = await _httpClient.PutAsync(url, content);
await HandleResponse(response);
var responseContent = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize(responseContent);
}
catch (HttpRequestException ex)
{
throw new MichitaiException("Network error occurred", ex);
}
}
private async Task HandleResponse(HttpResponseMessage response)
{
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
OnAuthenticationRequired?.Invoke();
throw new MichitaiException("Authentication required", response.StatusCode, errorContent);
}
throw new MichitaiException("API request failed", response.StatusCode, errorContent);
}
}
#endregion
}
#region Data Models
public class GameData
{
public int Id { get; set; }
public string Name { get; set; }
public string JsonStructure { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
}
public class PlayerData
{
public int Id { get; set; } = 0;
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string JsonData { get; set; } = string.Empty;
public int Level { get; set; } = 1;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? LastLogin { get; set; }
}
public class PlayerInfo
{
public string PlayerId { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? LastLogin { get; set; }
}
#endregion
#region Exceptions
public class MichitaiException : Exception
{
public System.Net.HttpStatusCode StatusCode { get; }
public string ResponseContent { get; }
public MichitaiException(string message) : base(message) { }
public MichitaiException(string message, Exception innerException)
: base(message, innerException) { }
public MichitaiException(string message, System.Net.HttpStatusCode statusCode, string responseContent)
: base($"{message}. Status: {statusCode}, Response: {responseContent}")
{
StatusCode = statusCode;
ResponseContent = responseContent;
}
}
#endregion
}
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;
namespace Michitai.Example
{
/// <summary>
/// Example class demonstrating how to use the Michitai SDK
/// </summary>
public class Game
{
private readonly Michitai.SDK.MichitaiClient _apiClient;
public Game(string apiKey)
{
if (string.IsNullOrEmpty(apiKey))
throw new ArgumentException("API key cannot be null or empty", nameof(apiKey));
// Initialize the API client with your API key
_apiClient = new Michitai.SDK.MichitaiClient(apiKey);
// Subscribe to authentication events
_apiClient.OnAuthenticationRequired += OnAuthenticationRequired!;
}
/// <summary>
/// Example method to demonstrate game data operations
/// </summary>
public async Task RunGameExample()
{
try
{
Console.WriteLine("Fetching game data...");
var gameData = await _apiClient.GetGameDataAsync();
Console.WriteLine($"Game: {gameData.Name}, Last Updated: {gameData.UpdatedAt}");
Console.WriteLine("\nFetching player data...");
var playerData = await _apiClient.GetPlayerDataAsync();
Console.WriteLine($"Player: {playerData.Username}, Level: {playerData.Level}");
// Example of updating player data
Console.WriteLine("\nUpdating player data...");
playerData.Level += 1;
playerData.LastLogin = DateTime.UtcNow;
var updatedPlayer = await _apiClient.UpdatePlayerDataAsync(playerData);
Console.WriteLine($"Player level updated to: {updatedPlayer.Level}");
// Example of listing all players (admin only)
Console.WriteLine("\nFetching all players...");
var players = await _apiClient.ListPlayersAsync();
foreach (var player in players)
{
Console.WriteLine($"- {player.Username} (Last login: {player.LastLogin})");
}
}
catch (Michitai.SDK.MichitaiException ex)
{
Console.WriteLine($"Error: {ex.Message}");
if (!string.IsNullOrEmpty(ex.ResponseContent))
{
Console.WriteLine($"Details: {ex.ResponseContent}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error: {ex.Message}");
}
}
private void OnAuthenticationRequired()
{
Console.WriteLine("Authentication required! Please provide valid API credentials.");
// Here you would typically show a login dialog or redirect to login page
}
/// <summary>
/// Entry point for the example
/// </summary>
public static async Task Main(string[] args)
{
try
{
Console.WriteLine("Michitai Game Example");
Console.WriteLine("=====================\n");
// Get API key from command line arguments or use a default one
string apiKey = args.Length > 0 ? args[0] : "your-api-key-here";
if (apiKey == "your-api-key-here")
{
Console.WriteLine("Warning: Using default API key. Please provide your own API key as a command line argument.");
}
var game = new Game(apiKey);
await game.RunGameExample();
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
Console.WriteLine("\nPress any key to exit...");
Console.ReadKey();
}
}
}
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.
{
"player_name": "player123",
"player_data": {
"level": 1,
"class": "warrior"
}
}
{
"success": true,
"data": {
"player_id": 42,
"private_key": "a1b2c3d4e5f6g7h8i9j0",
"player_name": "player123",
"game_id": 5
}
}
{}
{
"success": true,
"data": {
"player_id": 42,
"player_name": "player123",
"game_id": 5,
"is_active": true,
"player_data": {
"level": 1,
"class": "warrior"
},
"last_login": "2025-09-11 12:30:45"
}
}
{
"success": true,
"game_id": 5,
"data": {
"name": "Epic Adventure",
"version": "1.0.0",
"max_players": 100,
"game_state": "lobby",
"settings": {
"difficulty": "normal",
"allow_pvp": true
}
}
}
{
"level": 2,
"experience": 150,
"inventory": ["sword", "potion"],
"position": {"x": 100, "y": 200}
}
{
"success": true,
"message": "Player data updated successfully"
}
{
"success": false,
"error": {
"code": "unauthorized",
"message": "Invalid or missing API key"
}
}