การยืนยันตัวตนและความปลอดภัย
การเรียกใช้ API ทุกครั้ง (ยกเว้นการขอ Token) จะต้องแนบ Access Token ใน Header เอกสารนี้อธิบายวิธีขอ Token และดึงข้อมูลต่างๆ
Authorization: Bearer <your_token>- Base URL
https://api-backend.allwellsmartcare.com/api/client/v1- Rate limit
- Rate limit: กำหนดแยกต่อ Client / 1 นาที
ทุก protected request ส่งมาตรฐาน RateLimit headers กลับไป หากเกินโควตาจะได้รับ HTTP 429 กรุณารอรอบเวลาถัดไปก่อน retry และใช้ exponential backoff
การซิงก์ข้อมูลกับ HIS
Patients, devices, staff และ histories รองรับ updatedSince สำหรับ incremental sync โดยเรียง updatedAt และ id จากเก่าไปใหม่เมื่อใช้ตัวกรองนี้
- โหลดข้อมูลครั้งแรกโดยไม่ส่ง updatedSince และไล่ให้ครบทุก page
- บันทึกค่า updatedAt ที่มากที่สุดหลังโหลดครบทุก page แล้วเท่านั้น
- รอบถัดไปส่ง timestamp นั้นเป็น updatedSince เนื่องจากรวมค่าที่ขอบเขตด้วย จึงควรตัดข้อมูลซ้ำด้วย id
GET /histories?updatedSince=2026-07-30T08:31:00.000Z&page=1&limit=100Timestamp ต้องเป็น ISO 8601 พร้อม timezone ส่วน from/to แบบวันที่ล้วนหมายถึงทั้งวันตามเวลาไทย (+07:00) และ to รวมถึงสิ้นวัน โดย from/to กรองเวลาที่วัด (summitAt) ส่วน updatedSince กรองเวลาที่ข้อมูลเปลี่ยน (updatedAt)
สิทธิ์การเข้าถึง (Scopes)
Token เรียกได้เฉพาะ endpoint ที่ Client ได้รับ scope เท่านั้น Endpoint ที่ใช้หลาย resource ต้องมี scope ครบทุกรายการ
| Scope | Access |
|---|---|
| hospital:read | GET /hospital |
| patients:read | GET /patients, /patients/:id, /patients/:id/histories |
| patients:write | POST /patients, /patients/import; PUT /patients/:id/care-team |
| devices:read | GET /devices |
| histories:read | GET /histories, /patients/:id/histories |
| staff:read | GET /staff; PUT /patients/:id/care-team |
| staff:write | POST /staff, /staff/import |
ข้อผิดพลาด
Error ใช้ JSON envelope รูปแบบเดียวกัน โดย 4xx คือปัญหาคำขอหรือสิทธิ์ และควร retry เฉพาะ 429 กับ 5xx ชั่วคราวด้วย exponential backoff
| HTTP | Meaning |
|---|---|
| 400 | Parameter หรือ request body ไม่ถูกต้อง |
| 401 | ไม่มี Token, Token ไม่ถูกต้อง หรือหมดอายุ |
| 403 | Client ถูกปิดหรือไม่มี scope ที่จำเป็น |
| 404 | ไม่พบข้อมูลในโรงพยาบาลของ Client |
| 429 | เรียกเกิน Rate limit |
| 500 | ข้อผิดพลาดภายในระบบ |
{
"success": false,
"message": "updatedSince must be a valid ISO date"
}รายการ Endpoint
/tokenสร้าง Access Token
ใช้ Username และ Secret key เพื่อขอ Bearer token อายุ 1 ชั่วโมง โดยเรียกจาก backend ของระบบคู่เชื่อมต่อเท่านั้น
- Authorization
- —
{
"username": "hospital_partner",
"secret_key": "sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "hospital:read patients:read devices:read histories:read staff:read"
}
}/infoดูข้อมูล Client
ตรวจสอบข้อมูล Client, โรงพยาบาล และ scopes ของ token ที่กำลังใช้งาน
- Authorization
- Bearer Token
{
"success": true,
"data": {
"id": 1,
"username": "hospital_partner",
"name": "Hospital Data Warehouse",
"status": "ACTIVE",
"rateLimitPerMinute": 120,
"scopes": ["hospital:read", "patients:read", "devices:read", "histories:read", "staff:read"],
"Hospital": { "id": 101, "code": "H101", "name": "Allwell General Hospital" }
}
}/hospitalดูโรงพยาบาลและวอร์ด
ดึงข้อมูลโรงพยาบาลและวอร์ดที่ผูกกับ Client ระบบกำหนด hospital scope จาก token อัตโนมัติ
- Authorization
- Bearer Token • hospital:read
{
"success": true,
"data": {
"id": 101,
"code": "H101",
"name": "Allwell General Hospital",
"allowedDeviceTypes": ["BLOOD_GLUCOSE", "BLOOD_PRESSURE"],
"Wards": [{ "id": 1, "name": "OPD" }]
}
}/patients?page=1&limit=20ดูรายชื่อผู้ป่วย
รายชื่อผู้ป่วยของโรงพยาบาล รองรับ page, limit, search และ status
- Authorization
- Bearer Token • patients:read
{
"success": true,
"meta": { "page": 1, "limit": 20, "total": 150, "totalPages": 8 },
"data": [{
"id": 1,
"hn": "HN-2025-0001",
"hospitalId": 101,
"firstName": "Somsak",
"lastName": "Jai-dee",
"status": "ACTIVE",
"Wards": [{ "id": 1, "name": "OPD" }]
}]
}/patients/:idดูข้อมูลผู้ป่วย
ดึงผู้ป่วยหนึ่งรายพร้อมวอร์ด อุปกรณ์ และทีมผู้ดูแล หลังตรวจสอบว่าอยู่ในโรงพยาบาลของ Client
- Authorization
- Bearer Token • patients:read
{
"success": true,
"data": {
"id": 1,
"hn": "HN-2025-0001",
"firstName": "Somsak",
"lastName": "Jai-dee",
"Wards": [{ "id": 1, "name": "OPD" }],
"Devices": [{ "id": 12, "snDevice": "DEMO-BP-001", "deviceType": "BLOOD_PRESSURE" }]
}
}/patientsสร้างหรืออัปเดตผู้ป่วย
ประมวลผลผู้ป่วยหนึ่งราย หากมี HN นี้ในโรงพยาบาลแล้วจะอัปเดต มิฉะนั้นจะสร้างใหม่
- Authorization
- Bearer Token • patients:write
{
"hn": "HN-2025-0001",
"firstName": "Somsak",
"lastName": "Jai-dee",
"status": "ACTIVE"
}{
"success": true,
"message": "Patient processed successfully",
"data": { "row": 1, "status": "created", "hn": "HN-2025-0001" }
}/patients/importนำเข้าผู้ป่วย
สร้างหรืออัปเดตผู้ป่วยได้สูงสุด 500 รายการต่อครั้ง พร้อมผล created, updated หรือ failed ของแต่ละแถว
- Authorization
- Bearer Token • patients:write
{
"patients": [
{ "hn": "HN-2025-0001", "firstName": "Somsak", "lastName": "Jai-dee" },
{ "hn": "HN-2025-0002", "firstName": "Kanya", "lastName": "Suk" }
]
}{
"success": true,
"data": { "total": 2, "created": 1, "updated": 1, "failed": 0, "errors": [] }
}/devices?page=1&limit=20ดูอุปกรณ์
ดึงอุปกรณ์ รองรับ patientId, deviceType, isActive, updatedSince, page และ limit
- Authorization
- Bearer Token • devices:read
{
"success": true,
"meta": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 },
"data": [{
"id": 12,
"snDevice": "DEMO-BP-001",
"deviceType": "BLOOD_PRESSURE",
"isActive": true,
"Patient": { "id": 1, "hn": "HN-2025-0001" }
}]
}/histories?hn=HN-2025-0001&from=2026-07-01&to=2026-07-31ดูประวัติสุขภาพ
ดึงประวัติ รองรับ hn แบบตรงตัว, patientId, typeDevice, from, to, updatedSince, page และ limit พร้อมข้อมูลอุปกรณ์และหน่วย
- Authorization
- Bearer Token • histories:read
{
"success": true,
"meta": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 },
"data": [{
"id": 501,
"typeDevice": "BLOOD_PRESSURE",
"value": { "systolic": 128, "diastolic": 78, "pulse": 72 },
"units": { "systolic": "mmHg", "diastolic": "mmHg", "pulse": "bpm" },
"summitAt": "2026-07-30T08:30:00.000Z",
"updatedAt": "2026-07-30T08:31:00.000Z",
"Patient": { "id": 1, "hn": "HN-2025-0001" },
"Device": { "id": 12, "snDevice": "DEMO-BP-001", "deviceType": "BLOOD_PRESSURE" }
}]
}/patients/:id/historiesดูประวัติสุขภาพรายบุคคล
ดึงประวัติของผู้ป่วยหนึ่งราย รองรับ from, to, typeDevice และ updatedSince หลังตรวจสอบโรงพยาบาล
- Authorization
- Bearer Token • patients:read + histories:read
{
"success": true,
"meta": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 },
"data": [{
"typeDevice": "BLOOD_GLUCOSE",
"value": { "value": 115, "typeGen": "AC" },
"summitAt": "2026-07-30T07:30:00.000Z"
}]
}/staff?role=DOCTOR&page=1&limit=20ดูรายชื่อบุคลากร
ดึงทะเบียนบุคลากร กรองด้วย role, status, search, updatedSince, page และ limit
- Authorization
- Bearer Token • staff:read
{
"success": true,
"meta": { "page": 1, "limit": 20, "total": 2, "totalPages": 1 },
"data": [{
"id": 7,
"hospitalId": 101,
"staffCode": "DR-001",
"title": "นพ.",
"firstName": "Somchai",
"lastName": "Rakdee",
"role": "DOCTOR",
"specialty": "Internal Medicine",
"status": "ACTIVE"
}]
}/staffสร้างหรืออัปเดตบุคลากร
ประมวลผลบุคลากรหนึ่งราย หากมี staffCode จะอัปเดตรายการเดิม มิฉะนั้นจับคู่ด้วยชื่อและ role
- Authorization
- Bearer Token • staff:write
{
"staffCode": "DR-001",
"title": "นพ.",
"firstName": "Somchai",
"lastName": "Rakdee",
"role": "DOCTOR",
"status": "ACTIVE"
}{
"success": true,
"message": "Staff processed successfully",
"data": { "total": 1, "created": 1, "updated": 0, "failed": 0 }
}/staff/importนำเข้าบุคลากร
สร้างหรืออัปเดตบุคลากรได้สูงสุด 500 รายการต่อครั้ง แถวที่มี staffCode จะอัปเดตรายการเดิม หากไม่มีจะจับคู่ด้วยชื่อและ role
- Authorization
- Bearer Token • staff:write
{
"staff": [
{
"staffCode": "DR-001",
"title": "นพ.",
"firstName": "Somchai",
"lastName": "Rakdee",
"role": "DOCTOR",
"specialty": "Internal Medicine",
"status": "ACTIVE"
},
{ "firstName": "Kanya", "lastName": "Suk", "role": "NURSE" }
]
}{
"success": true,
"data": { "total": 2, "created": 1, "updated": 1, "failed": 0, "errors": [] }
}/patients/:id/care-teamกำหนดทีมผู้ดูแลผู้ป่วย
แทนที่รายชื่อผู้ดูแลของผู้ป่วยหนึ่งราย แต่ละรายการต้องมี staffId และ careRole และบุคลากรต้องอยู่โรงพยาบาลเดียวกัน
- Authorization
- Bearer Token • patients:write + staff:read
{
"careTeam": [
{ "staffId": 7, "careRole": "PRIMARY_DOCTOR" },
{ "staffId": 9, "careRole": "CARE_NURSE", "note": "Day shift" }
]
}{
"success": true,
"data": [{
"id": 31,
"patientId": 1,
"staffId": 7,
"careRole": "PRIMARY_DOCTOR",
"Staff": { "id": 7, "firstName": "Somchai", "role": "DOCTOR" }
}]
}