REST API リファレンス

SDK は、この HTTPS + JSON API を薄くラップしたクライアントです。どのエンジン、ツール、サーバーからでも API を直接利用できます。

コードのコメントと API 名は、SDK と一致させるため英語のままにしています。

このページの内容

基本#

ベース URL:https://majacloud.majanite.com/v1。localhost からのリクエストを除き、HTTPS が必須です。リクエストボディは Content-Type: application/json の JSON で送信します。

OpenAPI 3.1 定義をダウンロードして、クライアントを生成したり、Postman や Insomnia にインポートしたりできます。

ヘッダー#

ヘッダー意味
X-Project-IDダッシュボードのプロジェクト ID(常に必要)。
X-Client-Key公開クライアントキー(常に必要。ビルドに含めても安全)。
X-Secret-Keyクライアントキーの代わりに使う、サーバー用のシークレットキー(サーバー間通信のみ)。
Authorizationプレイヤー向けエンドポイントでは Bearer <access_token>。
X-Device-ID任意のインストール ID(ゲストのデバイスラベルとして使用)。
X-Majacloud-SDK任意のクライアント名とバージョン(例: unity/2.0.0)。

レスポンス#

すべてのレスポンスは ok を含む JSON です。エラーの場合は、安定した code、message、request_id、場合によっては details も含まれます。

C#
var top = await Majacloud.Leaderboards.GetTopAsync("coins", 10);
if (top.Ok)
{
    foreach (var entry in top.Value.Entries)
        Debug.Log($"#{entry.Rank} {entry.PlayerName} {entry.Score}");
}
else if (top.Error.IsRetryable)
{
    // Network, timeout, 5xx or rate limit: try again later
    Debug.Log("Retry in " + top.Error.RetryAfterSeconds + " s");
}
else
{
    Debug.LogWarning(top.Error.Code + ": " + top.Error.Message + " (" + top.Error.RequestId + ")");
}

例#

bash
export PROJECT_ID="<project id>" CLIENT_KEY="pk_live_…"

curl https://majacloud.majanite.com/v1/project -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY"

curl -X POST https://majacloud.majanite.com/v1/auth/guest -H "X-Project-ID: $PROJECT_ID" -H "X-Client-Key: $CLIENT_KEY" \
  -H "Content-Type: application/json" -d '{}'

エンドポイント#

プロジェクト#

GET/projectプロジェクト情報、プラン、リモートコンフィグの公開鍵クライアントキー
レスポンス 200
{
    "ok": true,
    "project": {
        "id": "8f3c…",
        "name": "Space Runner",
        "plan": "free",
        "config_version": 12,
        "config_public_key_xml": "<RSAKeyValue>…</RSAKeyValue>",
        "config_public_key_pem": "-----BEGIN PUBLIC KEY-----\n…\n-----END PUBLIC KEY-----\n",
        "services": {
            "player_auth": true,
            "leaderboards": true,
            "remote_config": true,
            "cloud_save": true,
            "rewards": true
        }
    }
}

プレイヤー認証#

POST/auth/guestゲストプレイヤーとセッションを作成クライアントキー
ボディ
{
    "device_id": "optional installation id"
}
レスポンス 201
{
    "ok": true,
    "auth_method": "guest",
    "access_token": "eyJ2IjoyLCJ0IjoiYWNjZXNz…",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "2d0f…",
    "refresh_expires_in": 2592000,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false
    }
}
POST/auth/refreshリフレッシュトークンをローテーションし、新しいアクセストークンを取得クライアントキー
ボディ
{
    "refresh_token": "…"
}
レスポンス 200
{
    "ok": true,
    "auth_method": "guest",
    "access_token": "eyJ2IjoyLCJ0IjoiYWNjZXNz…",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "2d0f…",
    "refresh_expires_in": 2592000,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false
    }
}
エラー
  • unauthorized (reason: invalid | expired | revoked | reused)
POST/auth/logoutセッションを失効クライアントキー
ボディ
{
    "refresh_token": "optional"
}
レスポンス 200
{
    "ok": true,
    "revoked": true
}
POST/auth/link/startWeb ログインを開始(ゲストをメールアドレスまたは Google と連携)プレイヤートークン
ボディ
{
    "code_challenge": "base64url(sha256(verifier))",
    "code_challenge_method": "S256",
    "return_url": "optional, https on this host or an allowlisted scheme"
}
レスポンス 201
{
    "ok": true,
    "flow_id": "uuid",
    "flow_token": "…",
    "auth_url": "https://majacloud.majanite.com/player-auth.php?flow_id=…&flow_token=…",
    "expires_at": "2026-10-09T08:27:00Z",
    "poll_interval_seconds": 3
}
POST/auth/link/exchange完了したフローをセッションと交換クライアントキー
ボディ
{
    "flow_id": "uuid",
    "exchange_code": "…",
    "code_verifier": "the original verifier"
}
レスポンス 200
{
    "ok": true,
    "auth_method": "guest",
    "access_token": "eyJ2IjoyLCJ0IjoiYWNjZXNz…",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "2d0f…",
    "refresh_expires_in": 2592000,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false
    },
    "merged_guest": true
}
GET/players/meログイン中のプレイヤープレイヤートークン
レスポンス 200
{
    "ok": true,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false
    }
}
PATCH/players/me表示名を変更プレイヤートークン
ボディ
{
    "display_name": "Nova"
}
レスポンス 200
{
    "ok": true,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false
    }
}
GET/players/{player_id}任意のプレイヤーを読み取り(シークレットキー)シークレットキー
レスポンス 200
{
    "ok": true,
    "player": {
        "id": "c7a1…",
        "player_id": "player_3f9c…",
        "display_name": "Guest 4821",
        "auth_type": "guest",
        "email_verified": false,
        "email": "nova@example.com",
        "wallets": [
            {
                "currency": "coins",
                "balance": 150
            }
        ]
    }
}

リーダーボード#

POST/leaderboards/{slug}/scoresスコアを送信プレイヤートークン
ボディ
{
    "score": 120
}
レスポンス 200
{
    "ok": true,
    "accepted": true,
    "entry": {
        "rank": 1,
        "player_id": "player_3f9c…",
        "player_name": "Nova",
        "score": 9840,
        "score_updated_at": "2026-10-09T08:12:00Z",
        "is_me": false
    },
    "period": {
        "key": "2026-W41",
        "ends_at": "2026-10-12T00:00:00Z"
    }
}
エラー
  • validation (bounds)
  • rate_limited (cooldown)
  • plan_limit (entry cap)
GET/leaderboards/{slug}/entries上位のエントリークライアントキー
クエリ
  • limit — 1-100 (default 10)
  • offset — 0+
  • period — current | previous
レスポンス 200
{
    "ok": true,
    "leaderboard": {
        "slug": "coins",
        "name": "Coins",
        "sort_type": "DESC",
        "score_mode": "BEST",
        "reset_rule": "WEEKLY"
    },
    "period": {
        "key": "2026-W41",
        "ends_at": "2026-10-12T00:00:00Z"
    },
    "entries": [
        {
            "rank": 1,
            "player_id": "player_3f9c…",
            "player_name": "Nova",
            "score": 9840,
            "score_updated_at": "2026-10-09T08:12:00Z",
            "is_me": false
        }
    ],
    "total": 42,
    "limit": 10,
    "offset": 0,
    "max_entries": 10
}
GET/leaderboards/{slug}/me自分の順位とスコアプレイヤートークン
クエリ
  • period — current | previous
レスポンス 200
{
    "ok": true,
    "entry": {
        "rank": 1,
        "player_id": "player_3f9c…",
        "player_name": "Nova",
        "score": 9840,
        "score_updated_at": "2026-10-09T08:12:00Z",
        "is_me": false
    },
    "total": 42
}
GET/leaderboards/{slug}/around-me自分の順位の前後のエントリープレイヤートークン
クエリ
  • radius — 1-25 (default 3)
レスポンス 200
{
    "ok": true,
    "entries": [
        {
            "rank": 1,
            "player_id": "player_3f9c…",
            "player_name": "Nova",
            "score": 9840,
            "score_updated_at": "2026-10-09T08:12:00Z",
            "is_me": false
        }
    ],
    "me": {
        "rank": 1,
        "player_id": "player_3f9c…",
        "player_name": "Nova",
        "score": 9840,
        "score_updated_at": "2026-10-09T08:12:00Z",
        "is_me": false
    },
    "total": 42
}

リモートコンフィグ#

GET/configRSA 署名付きのライブコンフィグ。If-None-Match を送ると 304 が返りますクライアントキー
レスポンス 200
{
    "ok": true,
    "project_id": "8f3c…",
    "version": 12,
    "checksum": "sha256 of data",
    "data": "base64url(JSON payload)",
    "signature": "base64 RSA-SHA256 over data",
    "signature_algorithm": "rsa-sha256",
    "signing_key_id": "config-v1",
    "configs": [
        {
            "key": "enemy_damage",
            "type": "number",
            "value": "25"
        }
    ]
}

クラウドセーブ#

GET/cloud保存済みのキーを一覧表示プレイヤートークン
レスポンス 200
{
    "ok": true,
    "keys": [
        {
            "key": "progress",
            "revision": 3,
            "size_bytes": 180,
            "updated_at": "…"
        }
    ],
    "total_bytes": 180
}
GET/cloud/{key}ドキュメントを読み込みプレイヤートークン
レスポンス 200
{
    "ok": true,
    "key": "progress",
    "data": {
        "level": 3
    },
    "revision": 3,
    "size_bytes": 180,
    "updated_at": "…"
}
PUT/cloud/{key}ドキュメントを保存(期待するリビジョンは任意)プレイヤートークン
ボディ
{
    "data": {
        "level": 4
    },
    "revision": "optional: expected current revision (0 = create only)"
}
レスポンス 200
{
    "ok": true,
    "key": "progress",
    "revision": 4,
    "size_bytes": 190,
    "updated_at": "…",
    "created": false
}
エラー
  • revision_mismatch (details.current_revision)
  • plan_limit (storage)
DELETE/cloud/{key}ドキュメントを削除プレイヤートークン
レスポンス 200
{
    "ok": true,
    "key": "progress",
    "deleted": true
}

報酬とウォレット#

GET/rewards有効な報酬(プレイヤートークンがある場合は受け取り可否のフラグ付き)クライアントキー
レスポンス 200
{
    "ok": true,
    "rewards": [
        {
            "reward_key": "daily_coins",
            "name": "Daily coins",
            "amount": 50,
            "currency": "coins",
            "cooldown": "daily",
            "claimable": true,
            "next_claim_at": null
        }
    ]
}
POST/rewards/claim報酬を受け取るプレイヤートークン
ボディ
{
    "reward_key": "daily_coins"
}
レスポンス 200
{
    "ok": true,
    "accepted": true,
    "reward_key": "daily_coins",
    "amount": 50,
    "currency": "coins",
    "balance": 150,
    "next_claim_at": "2026-10-10T00:00:00Z"
}
エラー
  • conflict (already claimed; details.next_claim_at)
GET/walletウォレットの残高プレイヤートークン
レスポンス 200
{
    "ok": true,
    "wallets": [
        {
            "currency": "coins",
            "balance": 150,
            "updated_at": "…"
        }
    ]
}

ページタイトル、見出し、本文を検索します。

↑↓ で移動 ↵ で開く Esc で閉じる