PJT AIPJT AI/API REFERENCE
v1https://api.pjt.ai/api/external/v1
เริ่มต้นใช้งานMCP
ภาพรวมการยืนยันตัวตนรหัสข้อผิดพลาด
Account
  • GET/me
Provisioning
  • POST/provisioning/workspacesENT
Tenants
  • GET/tenants
  • GET/tenants/{tenantId}
Workspaces
  • POST/workspaces
  • GET/workspaces/slug/available
  • GET/workspaces
  • GET/workspaces/{workspaceId}
Projects
  • GET/projects
  • GET/workspaces/{workspaceId}/projects
  • POST/projects
  • GET/projects/{projectId}
  • PUT/projects/{projectId}
  • DELETE/projects/{projectId}
  • GET/projects/{projectId}/timeline
  • GET/projects/{projectId}/activities
  • GET/projects/{projectId}/files
Tasks
  • GET/projects/{projectId}/tasks
  • POST/tasks
  • GET/tasks/{taskId}
  • PUT/tasks/{taskId}
  • DELETE/tasks/{taskId}
  • GET/tasks/assigned
Documents
  • GET/projects/{projectId}/documents
  • GET/documents/{documentId}
  • POST/documents
  • PUT/documents/{documentId}
  • DELETE/documents/{documentId}
OVERVIEW

PJT AI REST API

REST API มาตรฐานสำหรับการเชื่อมต่อข้อมูล PJT AI กับระบบภายนอก คำขอและการตอบกลับทั้งหมดเป็น JSON และ base URL คือ https://api.pjt.ai/api/external/v1.

พื้นฐาน
  • การยืนยันตัวตน — เฮดเดอร์ X-API-Key (API key ของบัญชี, prefix pjt_)
  • ขอบเขตคีย์ — read (อ่านอย่างเดียว ค่าเริ่มต้น) / write. POST·PUT·DELETE ต้องใช้คีย์ที่มีขอบเขต write — ไม่เช่นนั้นจะได้ 403 SCOPE_FORBIDDEN
  • ขีดจำกัด — 60 ครั้ง/นาที + 10,000 ครั้ง/เดือน ต่อคีย์ (Enterprise ตกลงเพิ่มเติม)
  • รหัสการตอบกลับ — 2xx สำเร็จ, 4xx ข้อผิดพลาดฝั่งไคลเอนต์, 5xx ข้อผิดพลาดเซิร์ฟเวอร์
  • วันที่ — timestamp ทั้งหมดเป็น ISO 8601 (UTC)
AUTH

การยืนยันตัวตน

ทุกคำขอต้องมี header X-API-Key: <API_KEY> สร้างคีย์ได้ที่ การตั้งค่าบัญชี > API key (แสดงเพียงครั้งเดียวตอนสร้าง)

⚠
การจัดเก็บคีย์
ใช้ API key เฉพาะฝั่งเซิร์ฟเวอร์เท่านั้น หากคีย์ถูกเปิดเผยต่อไคลเอนต์ (เบราว์เซอร์หรือแอปมือถือ) ให้เพิกถอนและออกใหม่ทันที
🔑
สิทธิ์ของ key
API key ทำงานด้วยสิทธิ์ของบัญชีที่ออกคีย์ การสร้างภายใต้ tenant ที่มีอยู่ (tenantId) ต้องการให้บัญชีนั้นเป็น OWNER/ADMIN ของ tenant (มิฉะนั้น 403); เมื่อสร้าง tenant ใหม่ บัญชีนั้นจะกลายเป็น OWNER การออกคีย์ที่มีสโคป provisioning จำกัดเฉพาะ SUPER_ADMIN
Account
GET/me

API key ของฉัน (ทดสอบการเชื่อมต่อ)

คืนความถูกต้องและความสามารถ (สโคป) ของ API key เนื่องจากเป็น GET จึงไม่ต้องมี write scope — แม้ key แบบอ่านอย่างเดียวก็ดูความสามารถของตัวเองได้ key ที่ขาด/ไม่ถูกต้อง/หมดอายุจะคืน 401 ซึ่งเป็นผลของการทดสอบการเชื่อมต่อในตัว ใช้ canProvision/canWrite/canRead ในการตอบกลับเพื่อประเมินความสามารถล่วงหน้า (เช่น ถ้า canProvision=false ให้เตือนก่อนเรียกจัดสรร → เลี่ยงไฟเขียวหลอก) แยกจาก liveness ของโครงสร้างพื้นฐาน (เซิร์ฟเวอร์ยังทำงานหรือไม่)

รหัสการตอบกลับ
200OK401Unauthorized
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

401UNAUTHORIZEDX-API-Key ขาดหาย ไม่ถูกต้อง หรือหมดอายุ — 401 นี้เองคือสัญญาณ 'ยังไม่เชื่อมต่อ' (200 = เชื่อมต่อแล้ว)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Provisioning
POST/provisioning/workspacesเฉพาะ Enterprise

จัดสรรเวิร์กสเปซ (idempotent)

จัดสรร tenant และเวิร์กสเปซในคำขอเดียวด้วย API key ขอบเขต provisioning ส่ง tenantId เพื่อใช้ tenant นั้น (บัญชีของ key ต้องเป็น OWNER/ADMIN) หากไม่ส่ง จะใช้ tenantExternalRef ค้นหา/สร้าง tenant แบบ idempotent ใน namespace ของบัญชี (400 หากไม่มีทั้งคู่) workspaceExternalRef เป็นคีย์ idempotent ที่จำเป็น — เรียกซ้ำจะคืนทรัพยากรเดิม (200) แทนการสร้างใหม่ (201) โดยดูจาก createdTenant/createdWorkspace ลำดับขอบเขต provisioning ⊃ write (ไม่ต้องมี write แยก) ⚠️ businessType ยังไม่มีผลต่อผลลัพธ์ (บันทึก audit เท่านั้น); defaultLocale/accentHue/template ตรวจสอบแบบหลวม (ส่งค่าที่ถูกต้อง; template ที่ไม่รู้จักจะถูกข้าม); tenant.myRole ในการตอบกลับอาจเป็น null — อย่าใช้ตัดสินสิทธิ์

endpoint นี้ใช้ได้เฉพาะแพ็กเกจ Enterprise เท่านั้น การออกและใช้ key สโคปการจัดสรรรวมอยู่ในสัญญา Enterprise

พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
tenantIdintegerID ของ tenant ที่มีอยู่ (Long, ไม่บังคับ) หากระบุ จะไม่สนใจ tenant·tenantExternalRef บัญชีของ key ต้องเป็น OWNER/ADMIN ของ tenant นั้น
tenantExternalRefstringคีย์ idempotent ของ tenant ใหม่ (≤100, เมื่อไม่มี tenantId) ค่าเดียวกัน (บัญชี, ค่า) จะใช้ tenant เดิม
tenant.namestringชื่อ tenant ใหม่ (≤100, ใช้ workspace.name หากเว้นว่าง)
tenant.slugstringslug ของ tenant ใหม่ (≤50, ไม่ซ้ำทั่วระบบ·สร้างอัตโนมัติหากไม่ระบุ)
tenant.descriptionstringคำอธิบาย tenant ใหม่ (≤500)
workspaceExternalRefREQUIREDstringคีย์ idempotent ของเวิร์กสเปซ (≤100, จำเป็น) ค่าเดียวกัน (tenantId, ค่า) จะใช้เวิร์กสเปซเดิม
workspace.nameREQUIREDstringชื่อเวิร์กสเปซ (≤100, จำเป็น)
workspace.slugstringslug เวิร์กสเปซ (≤50, ไม่ซ้ำภายใน tenant·อนุมานจากชื่อหากไม่ระบุ)
workspace.descriptionstringคำอธิบายเวิร์กสเปซ (≤500)
workspace.defaultLocalestringlocale เริ่มต้น — ko|en|ja|zh|zh-TW|es|vi|th (ไม่ตรวจสอบ; ส่งค่าที่ถูกต้อง)
workspace.accentHueintegerเฉดสีเน้น (0–360, ไม่ตรวจสอบ)
workspace.templatestringพรีเซ็ต — BLANK|DEV|AGENCY|OPS (ค่าที่ไม่รู้จักจะถูกข้าม)
workspace.businessTypestringประเภทธุรกิจ (เผื่ออนาคต) — บันทึก audit เท่านั้น·ไม่สะท้อนในเวิร์กสเปซที่สร้าง
รหัสการตอบกลับ
200OK201Created400Bad Request401Unauthorized403Forbidden429Rate Limited
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

403SCOPE_FORBIDDENพยายามเขียนด้วย key แบบอ่านอย่างเดียว (ไม่มี write scope) — ถูกบล็อกโดยตัวกรองเกตเวย์
{
  "error": "SCOPE_FORBIDDEN",
  "message": "This API key is read-only. A 'write' scope is required for this operation."
}
403FORBIDDENkey ที่ไม่มี provisioning scope — endpoint นี้ต้องมี provisioning (มีแค่ write ไม่พอ)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "The 'provisioning' scope is required."
}
403FORBIDDENเมื่อระบุ tenantId ที่มีอยู่ บัญชีที่เรียกไม่ใช่ OWNER/ADMIN (หรือไม่ใช่สมาชิก) ของ tenant นั้น
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "OWNER or ADMIN role on the tenant is required."
}
400BAD_REQUESTไม่ได้ส่งทั้ง tenantId และ tenantExternalRef
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "One of tenantId or tenantExternalRef is required."
}
400VALIDATION_ERRORตรวจสอบไม่ผ่าน (จำเป็น/ความยาว ฯลฯ) — รายละเอียดรายฟิลด์ใน errors[]
{
  "timestamp": "2026-07-14T09:00:00Z",
  "code": "VALIDATION_ERROR",
  "message": "workspaceExternalRef: must not be blank",
  "errors": [
    { "field": "workspaceExternalRef", "code": "NotBlank", "message": "must not be blank" }
  ]
}
401UNAUTHORIZEDX-API-Key ขาดหาย ไม่ถูกต้อง หรือหมดอายุ (ใช้ร่วมกับทุก endpoint External)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Tenants
GET/tenants

tenant ของฉัน

คืนค่า tenant ทั้งหมดที่บัญชีของ API key สังกัดอยู่ (สมาชิกโดยตรงของ tenant + องค์กรที่เข้าถึงได้ผ่านเวิร์กสเปซเท่านั้น = MEMBER) เนื่องจากเป็น GET จึงมี read scope ก็เพียงพอ ตัดสินสิทธิ์จาก myRole ของแต่ละรายการ (OWNER|ADMIN|MEMBER) — การสร้างเวิร์กสเปซ (POST /workspaces) ทำได้เฉพาะบน tenant ที่ myRole ∈ [OWNER, ADMIN] เท่านั้น ดังนั้น client SI จึงเลือก id ของรายการที่เป็น OWNER/ADMIN จากรายการนี้แล้วใช้เป็น tenantId

Response fields
ชื่อประเภทคำอธิบาย
idLongID เทแนนต์ — ใช้เป็น tenantId ใน POST /workspaces
myRoleString (enum)OWNER | ADMIN | MEMBER (null หากไม่ได้เป็นสมาชิก) การสร้างเวิร์กสเปซ (POST /workspaces) ทำได้เฉพาะเทแนนต์ที่คุณเป็น OWNER หรือ ADMIN เท่านั้น
statusString (enum)สถานะเทแนนต์ — ACTIVE | ARCHIVED | DELETE (Tenant.Status)
slugStringslug ขององค์กร (ใช้สำหรับการกำหนดเส้นทาง)
mfaSetupRequiredbooleantrue หากองค์กรบังคับใช้ 2FA และยังไม่ได้ตั้งค่า
slugSetbooleanผู้ใช้ตั้งค่า slug เองหรือไม่ (org-xxxx ที่สร้างอัตโนมัติเป็น false)
รหัสการตอบกลับ
200OK401Unauthorized
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

401UNAUTHORIZEDX-API-Key ขาดหาย ไม่ถูกต้อง หรือหมดอายุ (ใช้ร่วมกับทุก endpoint External)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/tenants/{tenantId}

tenant รายการเดียว

คืนค่า tenant หนึ่งรายการด้วย shape เดียวกับรายการทั้งหมด หากไม่ได้สังกัดจะตรวจสอบการเข้าถึงไม่ผ่าน (403); tenant ที่ไม่มีอยู่จะคืน 400 tenant.not_found มี read scope ก็เพียงพอ

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
tenantIdREQUIREDintegerID ของ tenant ที่จะเรียกดู (Long, จำเป็น)
รหัสการตอบกลับ
200OK400Bad Request401Unauthorized403Forbidden
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

403FORBIDDENบัญชีที่เรียกไม่ใช่สมาชิกของ tenant นั้น (ตรวจสอบการเข้าถึง tenant ไม่ผ่าน)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트 멤버가 아닙니다"
}
400BAD_REQUESTtenant ที่ไม่มีอยู่ (tenant.not_found)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트를 찾을 수 없습니다"
}
401UNAUTHORIZEDX-API-Key ขาดหาย ไม่ถูกต้อง หรือหมดอายุ (ใช้ร่วมกับทุก endpoint External)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
Workspaces
POST/workspaces

สร้างเวิร์กสเปซ (tenant ที่มีอยู่)

เส้นทางแบบเบาที่แยกจากการจัดสรร — ไม่สร้าง tenant แต่สร้างเฉพาะเวิร์กสเปซภายใต้ tenant ที่มีอยู่ (tenantId) มี write scope ก็เพียงพอ (ไม่ต้องมี provisioning·key แบบอ่านอย่างเดียวจะได้ 403 SCOPE_FORBIDDEN) บัญชีของ key ต้องเป็น OWNER/ADMIN ของ tenant นั้น หากส่ง externalRef จะเป็น idempotent — เรียกซ้ำด้วย (tenantId, externalRef) เดียวกันจะคืนเวิร์กสเปซเดิมด้วย 200 แทนการสร้างใหม่ (201) หากเว้นว่าง แต่ละครั้งที่เรียกจะสร้างเวิร์กสเปซใหม่ (แนะนำให้ส่งเพื่อการลองใหม่อย่างปลอดภัย) สิ่งที่สร้างเป็นเวิร์กสเปซทีม (ไม่ใช่ส่วนตัว) ⚠️ defaultLocale/accentHue/template ตรวจสอบแบบหลวม (ค่าผ่านไปตามที่ส่ง·template ที่ไม่รู้จักจะถูกข้าม) หากต้องการให้สร้าง tenant อัตโนมัติ ให้ใช้การจัดสรร (POST /provisioning/workspaces)

พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
tenantIdREQUIREDintegerสร้างภายใต้ tenant นี้ (Long, จำเป็น) บัญชีของ key ต้องเป็น OWNER/ADMIN ของ tenant นั้น
externalRefstringคีย์ idempotent (≤100, ไม่บังคับ) เรียกซ้ำด้วย (tenantId, ค่า) เดียวกันจะคืนเวิร์กสเปซเดิม เว้นว่าง → สร้างเวิร์กสเปซใหม่ทุกครั้งที่เรียก
nameREQUIREDstringชื่อเวิร์กสเปซ (≤100, จำเป็น)
slugstringslug เวิร์กสเปซ (≤50, ไม่ซ้ำภายใน tenant·อนุมานจากชื่อหากไม่ระบุ)
descriptionstringคำอธิบายเวิร์กสเปซ (≤500)
defaultLocalestringlocale เริ่มต้น — ko|en|ja|zh|zh-TW|es|vi|th (ผ่านโดยไม่ตรวจสอบ; ส่งค่าที่ถูกต้อง)
accentHueintegerเฉดสีเน้น (0–360, ผ่านโดยไม่ตรวจสอบ)
templatestringพรีเซ็ต — BLANK|DEV|AGENCY|OPS (ค่าที่ไม่รู้จักจะถูกข้ามอย่างเงียบ ๆ)
รหัสการตอบกลับ
201Created200OK400Bad Request401Unauthorized403Forbidden
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

403SCOPE_FORBIDDENพยายามเขียนด้วย key แบบอ่านอย่างเดียว (ไม่มี write scope) — ถูกบล็อกโดยตัวกรองเกตเวย์
{
  "error": "SCOPE_FORBIDDEN",
  "message": "This API key is read-only. A 'write' scope is required for this operation."
}
403FORBIDDENบัญชีที่เรียกไม่ใช่ OWNER/ADMIN ของ tenant tenantId (tenant.admin_required)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "관리자 권한이 필요합니다"
}
403FORBIDDENบัญชีที่เรียกไม่ใช่สมาชิกของ tenant นั้น (รวมถึง tenant ที่ไม่มีอยู่) (tenant.not_member)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "테넌트 멤버가 아닙니다"
}
400VALIDATION_ERRORตรวจสอบไม่ผ่าน (ขาด tenantId/name ฯลฯ) — รายละเอียดรายฟิลด์ใน errors[]
{
  "timestamp": "2026-07-14T20:00:00Z",
  "code": "VALIDATION_ERROR",
  "message": "tenantId: must not be null",
  "errors": [
    { "field": "tenantId", "code": "NotNull", "message": "must not be null" }
  ]
}
401UNAUTHORIZEDX-API-Key ขาดหาย ไม่ถูกต้อง หรือหมดอายุ (ใช้ร่วมกับทุก endpoint External)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces/slug/available

ตรวจสอบ slug ของเวิร์กสเปซซ้ำ

ตรวจสอบว่า slug ของเวิร์กสเปซใช้งานได้ (ยังไม่ถูกใช้) ภายใน tenant หรือไม่ เนื่องจาก slug ไม่ซ้ำกันตาม (tenantId, slug) จึงต้องระบุ tenantId เช่นเดียวกับตอนสร้างเวิร์กสเปซ slug จะถูกทำให้เป็นรูปแบบมาตรฐานเหมือนกฎการบันทึก (ตัดช่องว่างหน้า-หลัง แปลงเป็นตัวพิมพ์เล็ก) ก่อนเปรียบเทียบ และค่าว่างหรือค่าซ้ำจะคืนค่า available:false การอนุญาตใช้เกตเดียวกับการสร้างเวิร์กสเปซ — ผู้เรียกต้องเป็น OWNER/ADMIN ของ tenant นั้น (requireTenantAdmin) ผู้ที่ไม่ใช่สมาชิกและไม่ใช่ผู้ดูแลจะได้ 403 และจะไม่เปิดเผยว่ามี tenant อยู่หรือไม่ เนื่องจากเป็น GET จึงใช้ scope read ก็เพียงพอ ใช้ API นี้เพื่อตรวจสอบความพร้อมใช้งานของ slug ล่วงหน้าก่อนสร้างเวิร์กสเปซ (POST /workspaces)

พารามิเตอร์ query
ชื่อประเภทคำอธิบาย
tenantIdREQUIREDintegerขอบเขต tenant สำหรับการตรวจสอบความไม่ซ้ำ (Long, query จำเป็น) ขอบเขตความไม่ซ้ำของ slug ผู้เรียกต้องเป็น OWNER/ADMIN ของ tenant นี้
slugREQUIREDstringslug ของเวิร์กสเปซที่จะตรวจสอบ (query, จำเป็น) เปรียบเทียบหลังทำให้เป็นมาตรฐาน (trim, ตัวพิมพ์เล็ก)
Response fields
ชื่อประเภทคำอธิบาย
availablebooleantrue = ใช้งานได้ (ยังไม่ถูกใช้), false = ถูกใช้แล้วหรือ slug ว่าง
รหัสการตอบกลับ
200OK401Unauthorized403Forbidden
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

403FORBIDDENผู้เรียกไม่ใช่ OWNER/ADMIN ของ tenant tenantId (รวมถึงผู้ที่ไม่ใช่สมาชิก) — ถูกปิดกั้นโดย requireTenantAdmin (ไม่เปิดเผยว่ามี tenant อยู่หรือไม่)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "관리자 권한이 필요합니다"
}
401UNAUTHORIZEDX-API-Key หายไป ไม่ถูกต้อง หรือหมดอายุ (ใช้ร่วมกันใน External API)
{
  "timestamp": "2026-07-14T20:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces

รายการเวิร์กสเปซ

คืนรายการเวิร์กสเปซที่บัญชี API key เข้าถึงได้

รหัสการตอบกลับ
200OK401Unauthorized429Rate Limited
GET/workspaces/{workspaceId}

ดูเวิร์กสเปซ

คืนเวิร์กสเปซหนึ่งรายการ

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
workspaceIdREQUIREDintegerID เวิร์กสเปซ
รหัสการตอบกลับ
200OK401Unauthorized404Not Found
Projects
GET/projects

รายการโปรเจกต์ (ตามเทนันต์และเวิร์กสเปซ)

คืนรายการโปรเจกต์ของเทนันต์และเวิร์กสเปซที่ระบุ แบบแบ่งหน้า tenantId และ workspaceId จำเป็นต้องระบุ และกรองเพิ่มด้วย status ได้

พารามิเตอร์ query
ชื่อประเภทคำอธิบาย
tenantIdREQUIREDintegerID เทนันต์ (จำเป็น)
workspaceIdREQUIREDintegerID เวิร์กสเปซ (จำเป็น)
statusenumจับคู่สถานะโปรเจกต์แบบตรงตัว (PLANNING, ESTIMATING, WAITING, IN_PROGRESS, ON_HOLD, COMPLETED, CANCELLED) เมื่อระบุจะรวมที่ยกเลิก/เก็บถาวรด้วย
pageintegerหมายเลขหน้า (เริ่มจาก 0)
sizeintegerขนาดหน้า (ค่าเริ่มต้น 20 สูงสุด 100)
รหัสการตอบกลับ
200OK400Bad Request401Unauthorized403Forbidden429Rate Limited
การตอบกลับข้อผิดพลาด

ฟิลด์ message จะถูกส่งกลับตาม locale ของคำขอ (?lang หรือ Accept-Language) ใน 8 ภาษา

400BAD_REQUESTไม่พบเวิร์กสเปซ หรือไม่ได้อยู่ในเทนันต์นั้น (ข้ามเทนันต์จะคืน not_found โดยไม่เปิดเผยการมีอยู่)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "워크스페이스를 찾을 수 없습니다"
}
400BAD_REQUESTส่งค่า status ที่ไม่รองรับ
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "유효하지 않은 프로젝트 상태 값입니다"
}
403FORBIDDENไม่มีสิทธิ์เข้าถึงเวิร์กสเปซนี้ (ไม่ใช่สมาชิก ACTIVE หรือ client/partner ที่ได้รับการยอมรับ — ไม่มี fallback ตามสมาชิกเทนันต์)
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "워크스페이스 접근 권한이 없습니다"
}
401UNAUTHORIZEDX-API-Key หายไป ไม่ถูกต้อง หรือหมดอายุ
{
  "timestamp": "2026-07-14T09:00:00Z",
  "message": "API key is missing, invalid, or expired."
}
GET/workspaces/{workspaceId}/projects

รายการโปรเจกต์

คืนรายการโปรเจกต์ที่ใช้งานอยู่ของเวิร์กสเปซ (ไม่รวมที่ยกเลิก/เก็บถาวร)

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
workspaceIdREQUIREDintegerID เวิร์กสเปซ
รหัสการตอบกลับ
200OK401Unauthorized403Forbidden
POST/projects

สร้างโปรเจกต์ (idempotent)

สร้างโปรเจกต์ หากส่ง externalRef การเรียกจะเป็น idempotent — การส่งซ้ำด้วย (workspaceId, externalRef) เดิมจะคืนโปรเจกต์เดิมพร้อม 200 แทนการสร้างใหม่ (สร้างครั้งแรกคือ 201)

พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
workspaceIdREQUIREDintegerID เวิร์กสเปซ
nameREQUIREDstringชื่อโปรเจกต์
externalRefstringคีย์ idempotency — ส่งซ้ำด้วยค่าเดิมจะคืนโปรเจกต์เดิมพร้อม 200 แทนการสร้างใหม่
codestringรหัสโปรเจกต์ (prefix ของคีย์งาน) หากเว้นว่างจะสร้างอัตโนมัติจากชื่อ
descriptionstringคำอธิบาย
clientIdsarrayอาร์เรย์ของ ID ลูกค้า
managerIdintegerID บัญชีผู้จัดการ
startDatedateวันเริ่ม — ISO 8601 (YYYY-MM-DD)
endDatedateวันสิ้นสุด — ISO 8601 (YYYY-MM-DD)
budgetintegerงบประมาณ
รหัสการตอบกลับ
201Created200OK400Bad Request401Unauthorized
GET/projects/{projectId}

รายละเอียด / ความคืบหน้าโปรเจกต์

คืนรายละเอียดโปรเจกต์ รวมสถานะ ความคืบหน้า (%) กำหนดการตามแผน/จริง และเวลาแก้ไขล่าสุด

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
รหัสการตอบกลับ
200OK404Not Found
PUT/projects/{projectId}

แก้ไขโปรเจกต์

อัปเดตเฉพาะฟิลด์ที่ส่งมา (partial update)

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
namestringชื่อโปรเจกต์
statusenumสถานะ — PLANNING·ESTIMATING·WAITING·IN_PROGRESS·ON_HOLD·COMPLETED·CANCELLED
progressRateintegerความคืบหน้า (%) 0–100
startDatedateวันเริ่ม — ISO 8601 (YYYY-MM-DD)
endDatedateวันสิ้นสุด — ISO 8601 (YYYY-MM-DD)
รหัสการตอบกลับ
200OK400Bad Request404Not Found
DELETE/projects/{projectId}

ลบโปรเจกต์

ลบโปรเจกต์ สำเร็จจะคืน 204 No Content (ไม่มีเนื้อหา)

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
รหัสการตอบกลับ
204No Content403Forbidden404Not Found
GET/projects/{projectId}/timeline

ไทม์ไลน์ (ไมล์สโตน)

รายการไมล์สโตนของโปรเจกต์ — ชื่อ สถานะ (PLANNED/IN_PROGRESS/COMPLETED) กำหนดส่ง วันเสร็จ และความคืบหน้า เรียงตาม sortOrder

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
รหัสการตอบกลับ
200OK403Forbidden404Not Found
GET/projects/{projectId}/activities

กิจกรรม

เหตุการณ์การเปลี่ยนแปลงงานของโปรเจกต์ เรียงจากใหม่สุด — ประเภท ข้อความ ผู้กระทำ และเวลา

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
พารามิเตอร์ query
ชื่อประเภทคำอธิบาย
pageintegerหมายเลขหน้า (เริ่มที่ 0 ค่าเริ่มต้น 0)
sizeintegerขนาดหน้า (ค่าเริ่มต้น 50 สูงสุด 200)
รหัสการตอบกลับ
200OK403Forbidden404Not Found
GET/projects/{projectId}/files

รายการไฟล์

รวมไฟล์แนบจากงานและคอมเมนต์ในโปรเจกต์ เรียงจากใหม่สุด fileUrl เป็น URL แบบคงที่ไม่หมดอายุ

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
พารามิเตอร์ query
ชื่อประเภทคำอธิบาย
limitintegerจำนวนสูงสุด (ค่าเริ่มต้น 100 สูงสุด 500)
รหัสการตอบกลับ
200OK403Forbidden404Not Found
Tasks
GET/projects/{projectId}/tasks

รายการงาน

คืนรายการงานของโปรเจกต์ หากต้องการแบ่งหน้าให้ใช้ /tasks/paged

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
พารามิเตอร์ query
ชื่อประเภทคำอธิบาย
sortBystringเกณฑ์เรียงลำดับ (ค่าเริ่มต้น createdAt)
รหัสการตอบกลับ
200OK403Forbidden404Not Found
POST/tasks

สร้างงาน

สร้างงาน

พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
projectIdREQUIREDintegerID โปรเจกต์ (ตัวเลข)
titleREQUIREDstringหัวข้อ
descriptionstringคำอธิบาย
assigneeIdintegerID บัญชีผู้รับผิดชอบ
statusenumสถานะ — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED
priorityenumความสำคัญ — URGENT·HIGH·MEDIUM·LOW
dueDatedateกำหนดส่ง — ISO 8601
milestoneIdintegerID ไมล์สโตนที่จะเชื่อมโยง
รหัสการตอบกลับ
201Created400Bad Request401Unauthorized
GET/tasks/{taskId}

ดูงาน

คืนงานหนึ่งรายการ

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
taskIdREQUIREDintegerID งาน
รหัสการตอบกลับ
200OK404Not Found
PUT/tasks/{taskId}

แก้ไขงาน

อัปเดตเฉพาะฟิลด์ที่ส่งมา

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
taskIdREQUIREDintegerID งาน
พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
titlestringหัวข้อ
statusenumสถานะ — PENDING·TODO·IN_PROGRESS·IN_REVIEW·BLOCKED·COMPLETED·CANCELLED
priorityenumความสำคัญ — URGENT·HIGH·MEDIUM·LOW
dueDatedateกำหนดส่ง — ISO 8601
รหัสการตอบกลับ
200OK400Bad Request404Not Found
DELETE/tasks/{taskId}

ลบงาน

ลบงาน สำเร็จจะคืน 204 No Content

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
taskIdREQUIREDintegerID งาน
รหัสการตอบกลับ
204No Content403Forbidden404Not Found
GET/tasks/assigned

งานที่มอบหมายให้ฉัน

คืนรายการงานที่มอบหมายให้บัญชี API key

รหัสการตอบกลับ
200OK401Unauthorized
Documents
GET/projects/{projectId}/documents

รายการเอกสาร

คืนรายการเอกสารของโปรเจกต์ หากต้องการแบ่งหน้าให้ใช้ /documents/paged

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
projectIdREQUIREDstringID โปรเจกต์ — ID ตัวเลขหรือ publicId ที่ขึ้นต้นด้วย p_
รหัสการตอบกลับ
200OK403Forbidden404Not Found
GET/documents/{documentId}

ดูเอกสาร

คืนเอกสารหนึ่งรายการ (รวมเนื้อหา)

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
documentIdREQUIREDintegerID เอกสาร
รหัสการตอบกลับ
200OK404Not Found
POST/documents

สร้างเอกสาร

สร้างเอกสาร

พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
workspaceIdREQUIREDintegerID เวิร์กสเปซ
titleREQUIREDstringหัวข้อ
documentTypeREQUIREDenumประเภทเอกสาร (เช่น REQUIREMENT, MEETING_NOTE)
projectIdintegerID โปรเจกต์ (ตัวเลข)
contentstringเนื้อหาเอกสาร
visibilityenumขอบเขตการมองเห็น — PUBLIC·TEAM·PRIVATE
รหัสการตอบกลับ
201Created400Bad Request401Unauthorized
PUT/documents/{documentId}

แก้ไขเอกสาร

อัปเดตเฉพาะฟิลด์ที่ส่งมา

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
documentIdREQUIREDintegerID เอกสาร
พารามิเตอร์ body
ชื่อประเภทคำอธิบาย
titlestringหัวข้อ
contentstringเนื้อหาเอกสาร
visibilityenumขอบเขตการมองเห็น — PUBLIC·TEAM·PRIVATE
รหัสการตอบกลับ
200OK400Bad Request404Not Found
DELETE/documents/{documentId}

ลบเอกสาร

ลบเอกสาร สำเร็จจะคืน 204 No Content

พารามิเตอร์ path
ชื่อประเภทคำอธิบาย
documentIdREQUIREDintegerID เอกสาร
รหัสการตอบกลับ
204No Content403Forbidden404Not Found
ERRORS

รหัสข้อผิดพลาด

การตอบกลับข้อผิดพลาดทุกครั้งมี error.code และ error.message

รหัสชื่อคำอธิบายการดำเนินการ
400Bad Requestrequest body ไม่ถูกต้องตรวจสอบ request body
401UnauthorizedAPI key ไม่ถูกต้องหรือขาดหายไปตรวจสอบ API key อีกครั้ง
403Forbiddenคุณไม่มีสิทธิ์เข้าถึงทรัพยากรนี้ คำขอเขียนด้วยคีย์แบบอ่านอย่างเดียวจะได้รับ SCOPE_FORBIDDENตรวจสอบบทบาท/ขอบเขต
404Not Foundไม่พบทรัพยากรที่ร้องขอตรวจสอบ ID อีกครั้ง
429Rate Limitedคุณเกินขีดจำกัดอัตราดู header Retry-After และชะลอการเรียก
500Server Errorเกิดข้อผิดพลาดขณะเซิร์ฟเวอร์ประมวลผลคำขอลองใหม่หลัง 5 นาที ตรวจสอบ status.pjt.ai
BASE URL
https://api.pjt.ai/api/external/v1
VERSION
v1 · released 2026-07