อ้างอิงชนิดข้อมูลและข้อผิดพลาด
TypeScript ของทุก request / response ขีดจำกัดของข้อมูล และตารางข้อผิดพลาดทั้งหมด
เกี่ยวกับหน้านี้
รวมชนิดข้อมูล (TypeScript) ของทุก request และ response และตารางข้อผิดพลาดทั้งหมดไว้ที่เดียว คัดลอกไปใช้เป็น type ในโปรเจกต์ของคุณได้เลย รายละเอียดการทำงานของแต่ละ endpoint อยู่ที่ Sign in with Minecraft และ Instance API: ผู้เล่น
รูปแบบคำตอบ
ts
// สำเร็จ (HTTP 2xx)
interface ApiResponse<T> {
statusCode: number; // เท่ากับ HTTP status เช่น 200
data: T;
}
// ข้อผิดพลาดทั่วไป (HTTP 4xx / 5xx)
interface ApiError {
statusCode: number;
message: string; // ข้อความภาษาอังกฤษที่ระบุสาเหตุ
error?: string; // ชื่อมาตรฐานของ HTTP status เช่น "Unauthorized" "Not Found"
}
// ข้อผิดพลาดการตรวจข้อมูลที่ส่งมา (HTTP 400)
interface ValidationError {
statusCode: 400;
message: "Validation failed";
errors: {
code: string; // เช่น "invalid_type" "too_small" "too_big"
path: (string | number)[]; // ตำแหน่งของฟิลด์ที่ผิด เช่น ["players", 0, "uuid"]
message: string; // คำอธิบายของข้อผิดพลาดนั้น
expected?: string; // ชนิดที่คาดไว้ (บางกรณี)
}[];
}json
{
"statusCode": 400,
"message": "Validation failed",
"errors": [
{ "expected": "string", "code": "invalid_type", "path": ["players", 0, "uuid"], "message": "Invalid input: expected string, received undefined" }
]
}ชนิดข้อมูลทั้งหมด
ทั่วไป
ts
/** UUID ของ Minecraft: 32 หลักฐานสิบหก ตัวพิมพ์เล็ก ไม่มีขีด (ขาออกเป็นรูปนี้เสมอ ขาเข้ารับมีขีดและตัวพิมพ์ใหญ่ได้) */
type MinecraftUuid = string;
/** เวลา ISO 8601 UTC เช่น "2026-10-06T08:30:00.000Z" */
type IsoDateTime = string;
/** ตัวระบุ Instance ที่ใช้ใน path (ฟิลด์ name ไม่ใช่ title) */
type InstanceName = string;
type ApplicationScope = "PLAYERS_READ" | "PLAYERS_WRITE"; // สิทธิ์ต่อ Instance
type AuthScope = "identify"; // scope ของ Sign in with Minecraft
type PlayerStatus = "ACTIVE" | "PENDING" | "NOT_FOUND";Auth
ts
// ---- GET {Dashboard}/authorize (query string ของหน้าเว็บ)
interface AuthorizeQuery {
client_id: string;
redirect_uri?: string; // จำเป็นเมื่อ callbackType = REDIRECT ต้องตรงกับที่ลงทะเบียน
scope?: string; // ค่าเริ่มต้น "identify" คั่นด้วย ช่องว่าง , หรือ +
state: string; // 8..200 ตัวอักษร
}
// ---- ผลของ Redirect: query ที่เติมต่อท้าย redirect_uri
type OpenTabResult =
| { code: string; state: string } // ผู้เล่นยืนยัน
| { error: "access_denied"; state: string }; // ผู้เล่นปฏิเสธหรือยกเลิก
// ---- POST /api/v1/auth/token
interface TokenRequest {
code: string; // 1..200 ตัวอักษร
}
type TokenResponse = ApiResponse<{
state: string;
scopes: AuthScope[];
player: { uuid: MinecraftUuid; name: string };
}>;
// ---- Webhook (server เราส่งไปหาแอป)
interface AuthCompletedWebhook {
event: "auth.completed";
state: string;
scopes: AuthScope[];
player: { uuid: MinecraftUuid; name: string };
}
// headers: X-DMS-Timestamp (Unix วินาที เป็นสตริง), X-DMS-Signature ("sha256=" + hex)Instance API
ts
// ---- GET /api/v1/instances
interface InstanceGrant {
name: InstanceName;
title: string;
scopes: ApplicationScope[];
}
type ListInstancesResponse = ApiResponse<InstanceGrant[]>;
// ---- GET /api/v1/instances/{name}/players
interface InstancePlayer {
uuid: MinecraftUuid | null;
name: string | null;
status: PlayerStatus;
joinedAt: IsoDateTime;
}
type ListPlayersResponse = ApiResponse<InstancePlayer[]>;
// ---- PUT /api/v1/instances/{name}/players
interface PlayerInput {
uuid: string; // 1..64 ตัวอักษร ต้องอ่านเป็น UUID ได้
username?: string; // 0..32 ตัวอักษร คำใบ้แสดงผลเท่านั้น
}
interface PutPlayersRequest {
players: PlayerInput[]; // 1..100
}
type PutPlayersResponse = ApiResponse<{
added: number;
pending: number;
duplicates: number;
invalid: string[];
}>;
// ---- DELETE /api/v1/instances/{name}/players และ /players/{uuid}
interface DeletePlayersRequest {
players: { uuid: string }[]; // 1..100 (เฉพาะแบบมี body)
}
type DeletePlayersResponse = ApiResponse<{
removed: number;
notOnInstance: MinecraftUuid[];
invalid: string[];
}>;ขีดจำกัดของข้อมูลที่ส่ง
| ฟิลด์ | ข้อกำหนด |
|---|---|
players[] | 1-100 รายการต่อคำขอ (PUT และ DELETE) |
players[].uuid | string 1-64 ตัวอักษร (ต้องเป็น UUID ที่อ่านได้ ไม่งั้นเข้า invalid) |
players[].username | string 0-32 ตัวอักษร (ใช้เป็นคำใบ้เมื่อเป็นชื่อ Minecraft ที่ถูกต้อง 1-16 ตัว A-Z a-z 0-9 _) |
code | string 1-200 ตัวอักษร |
state | string 8-200 ตัวอักษร |
redirect_uri | string ไม่เกิน 500 ตัวอักษร ตรงกับที่ลงทะเบียน |
client_id / name ใน path | ตรงตัวพิมพ์เล็กใหญ่ |
ตารางข้อผิดพลาด
ค่า message ต่อไปนี้คือข้อความจริงที่ API ส่งกลับ (ข้อความภาษาอังกฤษ ใช้เทียบในโค้ดได้ แต่ควรอาศัย HTTP status เป็นหลัก)
ทุก endpoint ใต้ /api/v1
| สถานะ | message | สาเหตุ |
|---|---|---|
401 | Use "Authorization: Basic base64(client_id:client_secret)" | ไม่มี header Authorization หรือไม่ใช่ Basic |
401 | Invalid client credentials | client_id ไม่มีอยู่ หรือ secret ผิด (หรือเป็น secret ที่ถูกเปลี่ยนไปแล้ว) |
400 | Validation failed | body ชนิดผิด ขาดฟิลด์ที่จำเป็น หรือเกินขีดจำกัด (มี errors) |
Instance API
| สถานะ | message | สาเหตุ |
|---|---|---|
404 | Instance not found | ไม่มี Instance ชื่อนี้ หรือแอปไม่ได้รับ Instance นี้ (ตอบเหมือนกัน) |
403 | This application has no PLAYERS_READ access to that instance | เรียก GET โดยไม่มีสิทธิ์ players:read |
403 | This application has no PLAYERS_WRITE access to that instance | เรียก PUT หรือ DELETE โดยไม่มีสิทธิ์ players:write |
POST /api/v1/auth/token
| สถานะ | message | สาเหตุ |
|---|---|---|
400 | Invalid or expired code | code ไม่มี หมดอายุ (เกิน 5 นาที) ใช้ไปแล้ว หรือออกให้แอปอื่น |
หน้า /authorize และ Launcher (ผู้เล่นเห็น)
| สถานะ | message | สาเหตุ |
|---|---|---|
404 | Unknown application | ไม่มีแอปที่ client_id นี้ |
400 | redirect_uri is not registered for this application | Redirect แต่ไม่ส่ง redirect_uri หรือไม่ตรงที่ลงทะเบียน |
400 | Unknown scope: <ชื่อ> | ขอ scope ที่ไม่มีในระบบ |
400 | No scope requested | ส่ง scope มาแต่ไม่มีค่าที่ใช้ได้เลย |
403 | This application may not ask for: <ชื่อ> | แอปไม่ได้เปิด scope นั้น |
400 | This application has no webhook set | โหมด Webhook แต่ยังไม่มี webhookUrl |
404 | This sign-in request has expired or was already used | คำขอหมดอายุ (10 นาที) หรือถูกตอบไปแล้ว |
400 | That code does not match the one on the website (n tries left) | ผู้เล่นกรอกรหัสใน Launcher ผิด |
403 | Too many wrong codes. Start again from the website. | กรอกรหัสผิดครบ 5 ครั้ง คำขอถูกยกเลิก |
การจัดการข้อผิดพลาดที่แนะนำ
- ตัดสินจาก HTTP status ก่อน แล้วค่อยอ่าน
messageเพื่อแสดงหรือบันทึก log 401หลังทำงานได้ปกติมาก่อน แปลว่า secret ถูกเปลี่ยน ให้ตรวจ secret ล่าสุดในหน้าแอป- 5xx และข้อผิดพลาดเครือข่ายลองใหม่ได้ (PUT และ DELETE ปลอดภัยที่จะส่งซ้ำ) ส่วน
4xxลองซ้ำก็ได้ผลเดิม ต้องแก้ที่คำขอหรือการตั้งค่า

