Developer API

เอกสาร Client API

คู่มือการเชื่อมต่อระบบกับ Allwell Smart Care ผ่าน Client API สำหรับนักพัฒนา

การยืนยันตัวตนและความปลอดภัย

การเรียกใช้ 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 จากเก่าไปใหม่เมื่อใช้ตัวกรองนี้

  1. โหลดข้อมูลครั้งแรกโดยไม่ส่ง updatedSince และไล่ให้ครบทุก page
  2. บันทึกค่า updatedAt ที่มากที่สุดหลังโหลดครบทุก page แล้วเท่านั้น
  3. รอบถัดไปส่ง timestamp นั้นเป็น updatedSince เนื่องจากรวมค่าที่ขอบเขตด้วย จึงควรตัดข้อมูลซ้ำด้วย id
Incremental sync
GET /histories?updatedSince=2026-07-30T08:31:00.000Z&page=1&limit=100

Timestamp ต้องเป็น ISO 8601 พร้อม timezone ส่วน from/to แบบวันที่ล้วนหมายถึงทั้งวันตามเวลาไทย (+07:00) และ to รวมถึงสิ้นวัน โดย from/to กรองเวลาที่วัด (summitAt) ส่วน updatedSince กรองเวลาที่ข้อมูลเปลี่ยน (updatedAt)

สิทธิ์การเข้าถึง (Scopes)

Token เรียกได้เฉพาะ endpoint ที่ Client ได้รับ scope เท่านั้น Endpoint ที่ใช้หลาย resource ต้องมี scope ครบทุกรายการ

ScopeAccess
hospital:readGET /hospital
patients:readGET /patients, /patients/:id, /patients/:id/histories
patients:writePOST /patients, /patients/import; PUT /patients/:id/care-team
devices:readGET /devices
histories:readGET /histories, /patients/:id/histories
staff:readGET /staff; PUT /patients/:id/care-team
staff:writePOST /staff, /staff/import

ข้อผิดพลาด

Error ใช้ JSON envelope รูปแบบเดียวกัน โดย 4xx คือปัญหาคำขอหรือสิทธิ์ และควร retry เฉพาะ 429 กับ 5xx ชั่วคราวด้วย exponential backoff

HTTPMeaning
400Parameter หรือ request body ไม่ถูกต้อง
401ไม่มี Token, Token ไม่ถูกต้อง หรือหมดอายุ
403Client ถูกปิดหรือไม่มี scope ที่จำเป็น
404ไม่พบข้อมูลในโรงพยาบาลของ Client
429เรียกเกิน Rate limit
500ข้อผิดพลาดภายในระบบ
ตัวอย่าง Error
{
  "success": false,
  "message": "updatedSince must be a valid ISO date"
}

รายการ Endpoint

POST/token

สร้าง Access Token

ใช้ Username และ Secret key เพื่อขอ Bearer token อายุ 1 ชั่วโมง โดยเรียกจาก backend ของระบบคู่เชื่อมต่อเท่านั้น

Authorization
—
Request Body
{
  "username": "hospital_partner",
  "secret_key": "sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Response Sample
{
  "success": true,
  "data": {
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "hospital:read patients:read devices:read histories:read staff:read"
  }
}
GET/info

ดูข้อมูล Client

ตรวจสอบข้อมูล Client, โรงพยาบาล และ scopes ของ token ที่กำลังใช้งาน

Authorization
Bearer Token
Response Sample
{
  "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" }
  }
}
GET/hospital

ดูโรงพยาบาลและวอร์ด

ดึงข้อมูลโรงพยาบาลและวอร์ดที่ผูกกับ Client ระบบกำหนด hospital scope จาก token อัตโนมัติ

Authorization
Bearer Token • hospital:read
Response Sample
{
  "success": true,
  "data": {
    "id": 101,
    "code": "H101",
    "name": "Allwell General Hospital",
    "allowedDeviceTypes": ["BLOOD_GLUCOSE", "BLOOD_PRESSURE"],
    "Wards": [{ "id": 1, "name": "OPD" }]
  }
}
GET/patients?page=1&limit=20

ดูรายชื่อผู้ป่วย

รายชื่อผู้ป่วยของโรงพยาบาล รองรับ page, limit, search และ status

Authorization
Bearer Token • patients:read
Response Sample
{
  "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" }]
  }]
}
GET/patients/:id

ดูข้อมูลผู้ป่วย

ดึงผู้ป่วยหนึ่งรายพร้อมวอร์ด อุปกรณ์ และทีมผู้ดูแล หลังตรวจสอบว่าอยู่ในโรงพยาบาลของ Client

Authorization
Bearer Token • patients:read
Response Sample
{
  "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" }]
  }
}
POST/patients

สร้างหรืออัปเดตผู้ป่วย

ประมวลผลผู้ป่วยหนึ่งราย หากมี HN นี้ในโรงพยาบาลแล้วจะอัปเดต มิฉะนั้นจะสร้างใหม่

Authorization
Bearer Token • patients:write
Request Body
{
  "hn": "HN-2025-0001",
  "firstName": "Somsak",
  "lastName": "Jai-dee",
  "status": "ACTIVE"
}
Response Sample
{
  "success": true,
  "message": "Patient processed successfully",
  "data": { "row": 1, "status": "created", "hn": "HN-2025-0001" }
}
POST/patients/import

นำเข้าผู้ป่วย

สร้างหรืออัปเดตผู้ป่วยได้สูงสุด 500 รายการต่อครั้ง พร้อมผล created, updated หรือ failed ของแต่ละแถว

Authorization
Bearer Token • patients:write
Request Body
{
  "patients": [
    { "hn": "HN-2025-0001", "firstName": "Somsak", "lastName": "Jai-dee" },
    { "hn": "HN-2025-0002", "firstName": "Kanya", "lastName": "Suk" }
  ]
}
Response Sample
{
  "success": true,
  "data": { "total": 2, "created": 1, "updated": 1, "failed": 0, "errors": [] }
}
GET/devices?page=1&limit=20

ดูอุปกรณ์

ดึงอุปกรณ์ รองรับ patientId, deviceType, isActive, updatedSince, page และ limit

Authorization
Bearer Token • devices:read
Response Sample
{
  "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" }
  }]
}
GET/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
Response Sample
{
  "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" }
  }]
}
GET/patients/:id/histories

ดูประวัติสุขภาพรายบุคคล

ดึงประวัติของผู้ป่วยหนึ่งราย รองรับ from, to, typeDevice และ updatedSince หลังตรวจสอบโรงพยาบาล

Authorization
Bearer Token • patients:read + histories:read
Response Sample
{
  "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"
  }]
}
GET/staff?role=DOCTOR&page=1&limit=20

ดูรายชื่อบุคลากร

ดึงทะเบียนบุคลากร กรองด้วย role, status, search, updatedSince, page และ limit

Authorization
Bearer Token • staff:read
Response Sample
{
  "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"
  }]
}
POST/staff

สร้างหรืออัปเดตบุคลากร

ประมวลผลบุคลากรหนึ่งราย หากมี staffCode จะอัปเดตรายการเดิม มิฉะนั้นจับคู่ด้วยชื่อและ role

Authorization
Bearer Token • staff:write
Request Body
{
  "staffCode": "DR-001",
  "title": "นพ.",
  "firstName": "Somchai",
  "lastName": "Rakdee",
  "role": "DOCTOR",
  "status": "ACTIVE"
}
Response Sample
{
  "success": true,
  "message": "Staff processed successfully",
  "data": { "total": 1, "created": 1, "updated": 0, "failed": 0 }
}
POST/staff/import

นำเข้าบุคลากร

สร้างหรืออัปเดตบุคลากรได้สูงสุด 500 รายการต่อครั้ง แถวที่มี staffCode จะอัปเดตรายการเดิม หากไม่มีจะจับคู่ด้วยชื่อและ role

Authorization
Bearer Token • staff:write
Request Body
{
  "staff": [
    {
      "staffCode": "DR-001",
      "title": "นพ.",
      "firstName": "Somchai",
      "lastName": "Rakdee",
      "role": "DOCTOR",
      "specialty": "Internal Medicine",
      "status": "ACTIVE"
    },
    { "firstName": "Kanya", "lastName": "Suk", "role": "NURSE" }
  ]
}
Response Sample
{
  "success": true,
  "data": { "total": 2, "created": 1, "updated": 1, "failed": 0, "errors": [] }
}
PUT/patients/:id/care-team

กำหนดทีมผู้ดูแลผู้ป่วย

แทนที่รายชื่อผู้ดูแลของผู้ป่วยหนึ่งราย แต่ละรายการต้องมี staffId และ careRole และบุคลากรต้องอยู่โรงพยาบาลเดียวกัน

Authorization
Bearer Token • patients:write + staff:read
Request Body
{
  "careTeam": [
    { "staffId": 7, "careRole": "PRIMARY_DOCTOR" },
    { "staffId": 9, "careRole": "CARE_NURSE", "note": "Day shift" }
  ]
}
Response Sample
{
  "success": true,
  "data": [{
    "id": 31,
    "patientId": 1,
    "staffId": 7,
    "careRole": "PRIMARY_DOCTOR",
    "Staff": { "id": 7, "firstName": "Somchai", "role": "DOCTOR" }
  }]
}