API สำหรับพันธมิตรเพื่อข้อมูลโรงเรียน
อ่านข้อมูลโรงเรียน บุคลากร ใบแจ้งหนี้ และการมาเรียนจาก SekolahOS ผ่าน REST ที่มีการกำหนดเวอร์ชันและลงลายมือชื่อดิจิทัล
โดเมนที่เปิดให้พันธมิตร
คีย์ API ทุกตัวถูกกำหนดขอบเขตตามโดเมนและตามโรงเรียน ขอบเขตที่คุณไม่ได้ร้องขอจะไม่สามารถอ่านได้
ทะเบียนรายชื่อและบุคลากร
มูลนิธิ โรงเรียน และบุคลากรที่ใช้งานอยู่พร้อม รหัสบุคลากร และสถานะการจ้างงาน เลขประจำตัวประชาชน เฉพาะคีย์ที่มี roster.pii
การเงิน
ใบแจ้งหนี้พร้อมยอดรวม ยอดที่ชำระแล้ว และยอดค้างชำระ จำนวนเงินเป็นสตริงทศนิยม 2 ตำแหน่งพร้อมสกุลเงินเสมอ
การมาเรียน
บันทึกรายวันของนักเรียนแต่ละคนพร้อมสถานะคงที่หกสถานะ ภาพถ่ายที่ประตูจะไม่ถูกส่งออก
เหตุการณ์
เว็บฮุกที่ลงลายมือชื่อหรือการโพลล์สำหรับนักเรียนใหม่ การชำระเงินที่สำเร็จ และการหมุนเวียนคีย์ ใช้กับทุกคีย์
การยืนยันตัวตนที่หมุนเวียนคีย์ได้
คู่ key-id และ secret ต่อมูลนิธิ ลงลายมือชื่อด้วย HMAC-SHA256 ทุกคำขอ หมุนเวียนคีย์ได้โดยไม่มีช่วงหยุดทำงาน
ส่งซ้ำได้อย่างปลอดภัย
ทุกเอนด์พอยต์ที่เปลี่ยนแปลงข้อมูลรับ Idempotency-Key ส่งคำขอเดิมซ้ำแล้วจะได้การตอบกลับเดิม ไม่เกิดผลซ้ำสอง
เว็บฮุก พร้อมระบบสำรองแบบโพลลิง
เว็บฮุกที่ลงลายมือชื่อสำหรับเหตุการณ์ในระบบ พร้อมลองส่งใหม่ 5 ครั้ง — และเอนด์พอยต์เหตุการณ์สำหรับกรณีที่ตัวรับของคุณหยุดทำงาน
เชื่อมต่อผู้ช่วย AI กับข้อมูลโรงเรียนของคุณ
Claude Desktop, Claude Code, Cursor และไคลเอนต์ MCP อื่น ๆ สามารถอ่านข้อมูลโรงเรียนของคุณผ่าน API พันธมิตร เป็นแบบอ่านอย่างเดียว จำกัดตามขอบเขตของคีย์ และทุกการเรียกใช้มีการบันทึก
ออกคีย์
ผู้ดูแลมูลนิธิออกคีย์ในคอนโซล ภายใต้ พันธมิตรและคีย์ API (Partners & API keys) เริ่มต้นด้วยคีย์ ak_test_ ที่มีเฉพาะขอบเขตการอ่าน
ติดตั้งบริดจ์
ดาวน์โหลดไฟล์ Python หนึ่งไฟล์ที่ไม่ต้องพึ่งไลบรารีอื่น ไคลเอนต์ MCP ไม่สามารถสร้างลายเซ็น HMAC ได้ บริดจ์นี้จึงลงลายมือชื่อทุกคำขอบนคอมพิวเตอร์ของคุณ ค่าลับจะไม่ถูกส่งออกไป
เพิ่มลงในไคลเอนต์ของคุณ
วางการตั้งค่าสำหรับไคลเอนต์ของคุณ รีสตาร์ท แล้วถามว่า: คุณอ่านข้อมูลโรงเรียนใดได้บ้าง? คู่มือฉบับเต็มอยู่ในส่วน MCP ของเอกสารประกอบ
ak_test_ จะเข้าถึงเฉพาะข้อมูลสังเคราะห์เสมอ และจะไม่ส่งการแจ้งเตือนไปยังผู้ปกครอง ใช้คีย์นี้สำหรับการพัฒนาทั้งหมด
การยืนยันตัวตน
ทุกคำขอต้องมีเฮดเดอร์ key-id และลายเซ็น HMAC-SHA256 ของ timestamp + method + path + body ระบบจะไม่ส่งค่าลับออกไปเลย คำขอที่มีเวลาเก่ากว่า 300 วินาทีจะถูกปฏิเสธ
X-EduCore-Key-Id: ak_live_7Qp2R9 X-EduCore-Signature: t=1789632650,v1=9f... Idempotency-Key: 4f0a1b2c-...
| กฎ | ข้อกำหนด |
|---|---|
| ขอบเขต | กำหนดโดยมูลนิธิ ตามโดเมนและตามโรงเรียน พันธมิตรไม่สามารถขยายขอบเขตเองได้ |
| การหมุนเวียนคีย์ | มีคีย์ที่ใช้งานได้พร้อมกันไม่เกินสองตัวเป็นเวลา 30 วัน คีย์เก่าจะเป็นแบบอ่านอย่างเดียวในวันที่ 23 |
| IP allow-list | ตั้งค่าได้เป็นรายคีย์ คำขอจากที่อยู่นอกรายการจะถูกปฏิเสธด้วย IP_NOT_ALLOWED |
การกำหนดเวอร์ชันและการเลิกใช้
เวอร์ชันอยู่ในพาธ ไม่ใช่ในเฮดเดอร์ การเปลี่ยนแปลงที่ส่งผลกระทบต่อความเข้ากันได้จะเป็น /api/v2/ ใหม่เสมอ การเพิ่มฟิลด์ที่เป็นทางเลือกไม่ถือเป็นการเปลี่ยนแปลงที่ส่งผลกระทบ เวอร์ชันเก่าจะใช้งานได้อีก 12 เดือนหลังจากเวอร์ชันที่มาแทนที่ออกใช้ และจะส่งเฮดเดอร์ Sunset ตั้งแต่วันแรก
หลักปฏิบัติ
| กฎ | รูปแบบ |
|---|---|
| การแบ่งหน้า | ?cursor=&limit= → {results, next_cursor} |
| จำนวนเงิน | {"amount": "1500000.00", "currency": "IDR"} |
| เวลา | ISO 8601 UTC — 2026-09-17T02:14:00Z |
| ความเป็น idempotent | Idempotency-Key — เก็บไว้ 7 วัน |
จำนวนเงินเป็นสตริงพร้อมสกุลเงินในออบเจกต์ระดับเดียวกัน ห้ามรวมยอดข้ามสกุลเงิน: เอนด์พอยต์แบบรวมยอดจะคืนอาร์เรย์ของยอดรวมแยกตามสกุลเงิน ไม่ใช่ตัวเลขเดียว
Error
ข้อผิดพลาดทั้งหมดเป็น RFC 9457 application/problem+json ให้แยกตรรกะของคุณตาม code ซึ่งเป็นสตริง SCREAMING_SNAKE ที่คงที่ ไม่ใช่ตามข้อความอธิบายใน detail
{
"type": "/errors/scope-denied",
"title": "Scope not granted",
"status": 403,
"detail": "Key lacks roster.pii",
"instance": "/api/v1/partner/_",
"code": "SCOPE_DENIED"
}
| Status | Code |
|---|---|
| 401 | SIGNATURE_INVALID |
| 403 | SCOPE_DENIED |
| 400 | VALIDATION_ERROR |
| 403 | IP_NOT_ALLOWED |
| 404 | NOT_FOUND |
| 409 | IDEMPOTENCY_MISMATCH |
| 429 | RATE_LIMITED |
เว็บฮุกและการโพลล์
เว็บฮุกเป็นช่องทางหลัก ลงทะเบียนเอนด์พอยต์ HTTPS หนึ่งรายการต่อหนึ่งสภาพแวดล้อม รับ POST ที่ลงลายมือชื่อ และตอบกลับด้วย 2xx ภายใน 5 วินาที หากล้มเหลวจะลองใหม่ห้าครั้งภายในสูงสุด 6 ชั่วโมง หลังจากนั้นเหตุการณ์ยังคงดึงได้ด้วยการโพลล์
| เหตุการณ์ | เกิดขึ้นเมื่อ |
|---|---|
roster.student.enrolled | มีนักเรียนใหม่ที่ใช้งานอยู่ในโรงเรียนภายในขอบเขตของคีย์ |
finance.payment.settled | การชำระเงินผ่านบัญชีเสมือนหรือ QRIS ชำระสำเร็จและถูกจัดสรรแล้ว |
integration.key.rotated | มีการหมุนเวียนคีย์ — 30 วันก่อนที่คีย์เก่าจะหมดอายุ |
Endpoint
| เมธอดและพาธ | คำอธิบาย |
|---|---|
GET /partner/foundationsroster.read | มูลนิธิที่ให้สิทธิ์การเข้าถึงแก่คุณ |
GET /partner/schoolsroster.read | โรงเรียนภายในขอบเขตของคีย์ |
GET /partner/staff?school_idroster.read | บุคลากรที่ใช้งานอยู่พร้อม รหัสบุคลากร และสถานะ แบ่งหน้าด้วยเคอร์เซอร์ เลขประจำตัวประชาชน เฉพาะเมื่อมี roster.pii |
GET /partner/invoices?statusfinance.read | ใบแจ้งหนี้และยอดค้างชำระ |
GET /partner/attendance/daily?dateattendance.read | การมาเรียนรายวันของนักเรียนแต่ละคน |
GET /partner/events?since=cursor— | สตรีมเหตุการณ์ — ทางเลือกแทนเว็บฮุก |
POST /partner/mcpต่อเครื่องมือ | เซิร์ฟเวอร์ MCP แบบอ่านอย่างเดียวสำหรับผู้ช่วย AI ดูส่วน MCP |
POST /partner/webhooks— | ลงทะเบียนตัวรับเว็บฮุก |
MCP
เอนด์พอยต์ POST /partner/mcp เป็นเซิร์ฟเวอร์ Model Context Protocol (HTTP โหมด JSON แบบไม่มีเซสชัน) ภายใต้การยืนยันตัวตนและขีดจำกัดอัตราเดียวกับเอนด์พอยต์อื่น มีเฉพาะเครื่องมืออ่านอย่างเดียว คีย์จะเห็นเฉพาะเครื่องมือที่ขอบเขตของตนอนุญาต และแถวที่คืนมาจะเหมือนกับ REST ทุกประการ: จำกัดตามโรงเรียน จำกัดตามมูลนิธิ เลขประจำตัวประชาชน เฉพาะเมื่อมี roster.pii
ก่อนเริ่มต้น
- Python 3.8 หรือใหม่กว่าบนคอมพิวเตอร์ที่รันไคลเอนต์ AI (
python3 --versionบน Windows ใช้python) - ดาวน์โหลด educore_mcp_bridge.py และเก็บไว้ในโฟลเดอร์ถาวร เช่น
~/sekolahos/. - ตรวจสอบไฟล์ก่อนรัน:
shasum -a 256 educore_mcp_bridge.pyต้องแสดงค่า177f51df1cb11dea603f32a03809fca400a4f0e5e5dfbabf378f50d3f3a0c080. - ขอให้ผู้ดูแลมูลนิธิออกคีย์ให้ จดบันทึก key-id และค่าลับไว้ ค่าลับจะแสดงเพียงครั้งเดียว
- เก็บค่าลับไว้ในตัวจัดการรหัสผ่านหรือพวงกุญแจของระบบปฏิบัติการ ไม่ใช่ในไฟล์ที่ซิงก์หรือใน git ขอคีย์ที่มีเฉพาะขอบเขตที่จำเป็น และจำกัดด้วยรายการ IP
| ตัวแปร | ข้อความ |
|---|---|
EDUCORE_API_BASE | https://schoolday.live/api/v1/ |
EDUCORE_KEY_ID | key-id เช่น ak_test_7Qp2R9 |
EDUCORE_KEY_SECRET | ค่าลับที่แสดงตอนออกคีย์ |
คู่มือแยกตามไคลเอนต์
Claude Desktop
- เปิด Settings → Developer → Edit Config ไฟล์
claude_desktop_config.jsonจะเปิดขึ้น - เพิ่มเซิร์ฟเวอร์ต่อไปนี้ โดยแทนที่พาธและข้อมูลประจำตัว:
{
"mcpServers": {
"sekolahos": {
"command": "python3",
"args": ["/Users/anda/sekolahos/educore_mcp_bridge.py"],
"env": {
"EDUCORE_API_BASE": "https://schoolday.live/api/v1/",
"EDUCORE_KEY_ID": "ak_test_...",
"EDUCORE_KEY_SECRET": "..."
}
}
}
}
- ปิด Claude Desktop ให้สนิทแล้วเปิดใหม่ ไอคอนเครื่องมือจะปรากฏในช่องแชตพร้อมเซิร์ฟเวอร์ sekolahos
Claude Code
คำสั่งเดียวในเทอร์มินัล:
claude mcp add sekolahos \ --env EDUCORE_API_BASE=https://schoolday.live/api/v1/ \ --env EDUCORE_KEY_ID=ak_test_... \ --env EDUCORE_KEY_SECRET=... \ -- python3 ~/sekolahos/educore_mcp_bridge.py
ตรวจสอบด้วย claude mcp list หรือพิมพ์ /mcp ภายในเซสชัน
Cursor
สร้าง ~/.cursor/mcp.json (หรือ .cursor/mcp.json ในโปรเจกต์) โดยใช้เนื้อหาเดียวกับ Claude Desktop ข้างต้น จากนั้นเปิดใช้งานเซิร์ฟเวอร์ภายใต้ Settings → MCP
ไคลเอนต์ MCP อื่น ๆ
ไคลเอนต์ใดก็ตามที่รองรับเซิร์ฟเวอร์ MCP ภายในเครื่อง (stdio) ต้องการเพียงคำสั่ง python3 /path/educore_mcp_bridge.py และตัวแปรสภาพแวดล้อมสามตัวข้างต้น หากต้องการทดสอบโดยไม่ใช้ไคลเอนต์ AI ให้ใช้ MCP Inspector:
EDUCORE_API_BASE=https://schoolday.live/api/v1/ \ EDUCORE_KEY_ID=ak_test_... EDUCORE_KEY_SECRET=... \ npx @modelcontextprotocol/inspector python3 educore_mcp_bridge.py
ทดสอบอย่างรวดเร็วจากเทอร์มินัล
ส่งข้อความ JSON-RPC หนึ่งข้อความไปยังบริดจ์ คำตอบจะแสดงรายการเครื่องมือที่คีย์ของคุณใช้ได้:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python3 educore_mcp_bridge.py
เครื่องมือที่ใช้ได้
| เครื่องมือ | ขอบเขต | วัตถุประสงค์ |
|---|---|---|
list_schools | roster.read | โรงเรียนภายในขอบเขตของคีย์ |
list_classes | roster.read | กลุ่มห้องเรียนพร้อมระดับชั้นและปีการศึกษา ตัวกรอง: school_id |
list_students | roster.read roster.pii | นักเรียนพร้อมเลขประจำตัวนักเรียน (เลขประจำตัวนักเรียน) สถานะ และห้องเรียนปัจจุบัน เลขประจำตัวนักเรียน เฉพาะเมื่อมี roster.pii ส่วน เลขประจำตัวประชาชน วันเกิด ที่อยู่ และข้อมูลติดต่อผู้ปกครองจะไม่ถูกส่งเลย ตัวกรอง: school_id, class_group_id, status, q (บางส่วนของชื่อ) |
list_staff | roster.read roster.pii | บุคลากรที่ใช้งานอยู่พร้อม รหัสบุคลากร และสถานะ เลขประจำตัวประชาชน เฉพาะเมื่อมี roster.pii ตัวกรอง: school_id |
list_invoices | finance.read | ใบแจ้งหนี้และยอดค้างชำระ ตัวกรอง: status, school_id, student_id, period, due_from, due_to |
get_daily_attendance | attendance.read | การมาเรียนของนักเรียนหนึ่งวัน จำเป็น: date (YYYY-MM-DD) |
get_attendance_range | attendance.read | การมาเรียนของนักเรียนในช่วงวันที่ (ไม่เกิน 31 วัน) จำเป็น: date_from, date_to ตัวกรอง: school_id, student_id, status |
ทุกเครื่องมือรองรับ limit (สูงสุด 200) และ before_id คำตอบจะมี next_before_id ให้ส่งค่านั้นเพื่อขอหน้าถัดไป ไม่มีเครื่องมือเขียนข้อมูล การลงทะเบียนเว็บฮุกยังคงใช้ผ่าน REST เท่านั้น คีย์หนึ่งเรียกใช้เครื่องมือได้สูงสุด 120 ครั้งต่อนาที (อยู่ภายในขีดจำกัด 600 คำขอ)
หากใช้งานไม่ได้
| อาการ | สาเหตุและวิธีแก้ไข |
|---|---|
| เซิร์ฟเวอร์ไม่ปรากฏในไคลเอนต์ | พาธของไฟล์ไม่ถูกต้อง หรือไม่มี Python ใน PATH ให้รัน command จากเทอร์มินัลเพื่อดูข้อความแสดงข้อผิดพลาด |
SIGNATURE_INVALID | ค่าลับไม่ถูกต้อง คีย์ถูกเพิกถอนหรือหมดอายุแล้ว หรือนาฬิกาของคอมพิวเตอร์คลาดเคลื่อนเกิน 300 วินาที |
IP_NOT_ALLOWED | คีย์ใช้รายการ IP ที่อนุญาต และที่อยู่ของคอมพิวเตอร์คุณไม่อยู่ในรายการ |
SCOPE_DENIED | คีย์ไม่มีขอบเขตสำหรับเครื่องมือนั้น ขอให้ผู้ดูแลมูลนิธิออกคีย์ใหม่ที่มีขอบเขตที่ถูกต้อง |
RATE_LIMITED | ขีดจำกัด 600 คำขอต่อนาทีต่อคีย์ใช้ร่วมกันระหว่าง REST และ MCP |
สำหรับตัวแทนจำหน่ายและผู้เชื่อมต่อระบบ
คีย์ API ทุกคีย์ใช้ได้กับมูลนิธิเดียวเท่านั้น ไม่มีคีย์ใดเข้าถึงหลายมูลนิธิ หากคุณเชื่อมต่อหลายโรงเรียน ให้ขอผู้ดูแลมูลนิธิแต่ละแห่งออกคีย์ให้คุณในคอนโซลที่ พันธมิตรและคีย์ API โดยกำหนดขอบเขตให้แคบที่สุด เก็บรหัสลับแต่ละรายการไว้ในที่เก็บของคุณเอง แยกตามมูลนิธิ
เพื่อช่วยตั้งค่าภายในคอนโซล ผู้ดูแลมูลนิธิจะสร้างบัญชีลงชื่อเข้าใช้ของบุคลากรทั่วไปที่มีเฉพาะบทบาทที่จำเป็น ตัวแทนจำหน่ายจะไม่ได้รับการเข้าถึงข้ามมูลนิธิ
ขีดจำกัดอัตราการเรียกใช้
| ขีดจำกัด | ค่า |
|---|---|
| คำขอต่อคีย์ | 600 ครั้ง / นาที |
| จำนวนแถวสูงสุดต่อหน้าเคอร์เซอร์ | 200 |
| ช่วงเวลาโพลล์ที่เร็วที่สุดที่อนุญาต | 30 วินาที |
การเกินขีดจำกัดจะได้รับ 429 RATE_LIMITED พร้อมเฮดเดอร์ Retry-After