{"openapi":"3.1.0","info":{"title":"SPK School Extension API","version":"1.0.0","description":"Read-only API สำหรับระบบเสริม ใช้ field minimization, explicit scopes และ section scope"},"externalDocs":{"description":"คู่มือนักพัฒนาสำหรับคนและ AI","url":"/developers/api"},"servers":[{"url":"/api/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key ที่ขึ้นต้นด้วย spk_live_"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","request_id"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string","format":"uuid"}}}}},"Student":{"type":"object","required":["id","student_code","status"],"properties":{"id":{"type":"string","format":"uuid"},"student_code":{"type":"string"},"full_name":{"type":["string","null"]},"display_name":{"type":["string","null"]},"status":{"type":"string","enum":["studying","on_leave","graduated","resigned","transferred"]},"entered_year":{"type":["string","null"]},"updated_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"StudentStatus":{"type":"object","required":["id","status","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["studying","on_leave","graduated","resigned","transferred"]},"entered_year":{"type":["string","null"]},"updated_at":{"type":"string","format":"date-time"}}},"Enrollment":{"type":"object","required":["id","academic_year_id","section_id","status"],"properties":{"id":{"type":"string","format":"uuid"},"academic_year_id":{"type":"string","format":"uuid"},"academic_year_name":{"type":["string","null"]},"section_id":{"type":"string","format":"uuid"},"section_name":{"type":["string","null"]},"roll_number":{"type":["integer","null"]},"status":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ConductRecord":{"type":"object","required":["id","label","points","occurred_on"],"properties":{"id":{"type":"string","format":"uuid"},"label":{"type":"string"},"points":{"type":"number"},"occurred_on":{"type":"string","format":"date"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"AttendanceRecord":{"type":"object","required":["id","event_id","section_id","event_date","event_type","status"],"properties":{"id":{"type":"string","format":"uuid","description":"รหัส attendance record"},"event_id":{"type":"string","format":"uuid","description":"รหัส attendance event"},"section_id":{"type":"string","format":"uuid"},"event_date":{"type":"string","format":"date"},"event_type":{"type":"string"},"period_no":{"type":["integer","null"]},"subject_id":{"type":["string","null"],"format":"uuid"},"title":{"type":["string","null"]},"status":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"label":{"type":"string"},"counts_as":{"type":"string"}}},"recorded_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Section":{"type":"object","required":["id","academic_year_id","grade_level_id","name"],"properties":{"id":{"type":"string","format":"uuid"},"academic_year_id":{"type":"string","format":"uuid"},"grade_level_id":{"type":"string","format":"uuid"},"grade_level_name":{"type":["string","null"]},"name":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"RosterStudent":{"type":"object","required":["id","student_code","status","roll_number"],"properties":{"id":{"type":"string","format":"uuid"},"student_code":{"type":["string","null"]},"full_name":{"type":["string","null"]},"display_name":{"type":["string","null"]},"status":{"type":["string","null"]},"roll_number":{"type":["integer","null"]}}},"ExtensionIdentity":{"type":"object","required":["subject","username","full_name","roles","extension"],"properties":{"subject":{"type":"string","format":"uuid"},"username":{"type":"string"},"full_name":{"type":"string"},"display_name":{"type":["string","null"]},"roles":{"type":"array","items":{"type":"string"}},"extension":{"type":"string"}}},"CursorMeta":{"type":"object","required":["next_cursor"],"properties":{"next_cursor":{"type":["string","null"]}}}}},"paths":{"/students":{"get":{"summary":"รายชื่อนักเรียน","operationId":"listStudents","parameters":[{"name":"limit","in":"query","description":"จำนวนรายการต่อหน้า (ค่าเริ่มต้น 50)","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"section_id","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["studying","on_leave","graduated","resigned","transferred"]}},{"name":"updated_since","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Student"}},"meta":{"$ref":"#/components/schemas/CursorMeta"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง"},"403":{"description":"scope/section ไม่อนุญาต"},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit"},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"students:read"}},"/students/{id}":{"get":{"summary":"โปรไฟล์นักเรียนแบบลดฟิลด์","operationId":"getStudent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Student"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"students:read"}},"/students/{id}/status":{"get":{"summary":"สถานะนักเรียน","operationId":"getStudentStatus","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/StudentStatus"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"students:read"}},"/students/{id}/enrollments":{"get":{"summary":"ประวัติ enrollment","operationId":"getStudentEnrollments","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Enrollment"}}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"enrollments:read"}},"/students/{id}/conduct":{"get":{"summary":"คะแนนพฤติกรรม","operationId":"getStudentConduct","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ConductRecord"}},"meta":{"$ref":"#/components/schemas/CursorMeta"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"conduct:read"}},"/students/{id}/attendance":{"get":{"summary":"การมาเรียน","operationId":"getStudentAttendance","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AttendanceRecord"}},"meta":{"$ref":"#/components/schemas/CursorMeta"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"attendance:read"}},"/sections":{"get":{"summary":"ห้องเรียน","operationId":"listSections","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"academic_year_id","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Section"}},"meta":{"$ref":"#/components/schemas/CursorMeta"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"sections:read"}},"/sections/{id}/students":{"get":{"summary":"Roster ห้อง","operationId":"getSectionStudents","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["section","students"],"properties":{"section":{"$ref":"#/components/schemas/Section"},"students":{"type":"array","items":{"$ref":"#/components/schemas/RosterStudent"}}}}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"คีย์ไม่ถูกต้อง หมดอายุ หรือถูกระงับ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-required-scope":"sections:read"}},"/extensions/exchange":{"post":{"summary":"แลก one-time launch token","operationId":"exchangeExtensionLaunch","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token","extension_slug","client_secret"],"properties":{"token":{"type":"string"},"extension_slug":{"type":"string"},"client_secret":{"type":"string","writeOnly":true}}}}}},"responses":{"200":{"description":"สำเร็จ","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ExtensionIdentity"}}}}}},"400":{"description":"คำขอหรือพารามิเตอร์ไม่ถูกต้อง","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"token หมดอายุหรือถูกใช้แล้ว"},"403":{"description":"scope, origin หรือขอบเขตห้องไม่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"ไม่พบข้อมูลในขอบเขตที่อนุญาต","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"เกิน rate limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"เกิดข้อผิดพลาดภายใน","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"แพลตฟอร์ม API ไม่พร้อมชั่วคราว","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}