เอกสารสำหรับนักพัฒนา: API, Webhooks และ SCIM
เชื่อม HomeHQ กับระบบ HR / ERP / Payroll เดิมขององค์กร — ดึงรายชื่อพนักงาน การลงเวลา การลา และสรุปเงินเดือนผ่าน REST API รับแจ้งเหตุการณ์ทันทีด้วย Webhooks และให้ Microsoft Entra ID หรือ Okta เพิ่ม/ระงับพนักงานอัตโนมัติด้วย SCIM 2.0
ภาพรวม
| ส่วน | แพ็กเกจ | ที่อยู่ |
|---|---|---|
| REST API (อ่านอย่างเดียว) | Business ขึ้นไป | https://homehqth.com/api/v1 |
| Webhooks | Business ขึ้นไป | HomeHQ ส่ง POST ไปยัง URL ของคุณ |
| SCIM 2.0 (เพิ่ม/ลบผู้ใช้อัตโนมัติ) | Enterprise | https://homehqth.com/scim/v2 |
ตั้งค่าทั้งหมดได้ในแอป HomeHQ ที่เมนู ตั้งค่า → API และการเชื่อมต่อ (เฉพาะเจ้าของและผู้ดูแลองค์กร) — รูปแบบข้อมูลเวอร์ชัน 2026-10-01 ส่งกลับในหัว X-HomeHQ-Api-Version และในทุก webhook
เริ่มใช้งานใน 2 นาที
- เปิดแอป HomeHQ → ตั้งค่า → API และการเชื่อมต่อ → กด สร้าง API key ตั้งชื่อ (เช่น "ระบบเงินเดือน") แล้วเลือกสิทธิ์เท่าที่จำเป็น
- คัดลอก key ที่ขึ้นต้นด้วย
hhq_เก็บในที่ปลอดภัย (เช่น ตัวแปรแวดล้อมของเซิร์ฟเวอร์) — แสดงครั้งเดียว HomeHQ เก็บเฉพาะค่าแฮช - ลองเรียก:
curl https://homehqth.com/api/v1/me \
-H "Authorization: Bearer $HOMEHQ_API_KEY"
// Node.js 18+ (fetch มีในตัว)
const res = await fetch('https://homehqth.com/api/v1/members?limit=100', {
headers: { Authorization: `Bearer ${process.env.HOMEHQ_API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, pagination } = await res.json();
console.log(data.length, pagination.nextCursor);
การยืนยันตัวตน
ส่ง API key ในหัว Authorization: Bearer <key> ทุกคำขอ (ผ่าน HTTPS เท่านั้น) · ห้ามใส่ key ในโค้ดฝั่งเว็บเบราว์เซอร์หรือแอปมือถือ · key ไม่มีวันหมดอายุจนกว่าจะกด เพิกถอน — เพิกถอนแล้วใช้ไม่ได้ทันที · องค์กรมี key ที่ใช้งานอยู่ได้สูงสุด 20 อัน (แยก key ต่อระบบ จะได้เพิกถอนทีละระบบได้)
ถ้าองค์กรลดแพ็กเกจต่ำกว่า Business หรือแพ็กเกจหมดอายุ ทุกคำขอจะได้ 402 จนกว่าจะต่ออายุ (key เดิมยังอยู่ ไม่ต้องสร้างใหม่)
สิทธิ์ของ API key (scopes)
ทุก scope เป็นแบบอ่านอย่างเดียว · เรียก endpoint ที่ key ไม่มีสิทธิ์ จะได้ 403 INSUFFICIENT_SCOPE
| Scope | ใช้กับ | ข้อมูลที่ได้ |
|---|---|---|
org:read | โครงสร้างองค์กร | บริษัท สาขา แผนก และตำแหน่ง |
members:read | รายชื่อพนักงาน | ชื่อ อีเมล รหัสพนักงาน แผนก สาขา ตำแหน่ง สถานะการจ้างงาน (ไม่มีเลขบัตร/บัญชีธนาคาร/เงินเดือน) |
attendance:read | การลงเวลา | เวลาเข้า-ออกงานรายวันตามช่วงวันที่ (ไม่มีรูปเซลฟี่/พิกัด) |
leave:read | การลางาน | ใบลา ประเภท วันที่ จำนวนวัน และสถานะอนุมัติ |
payroll:read | สรุปเงินเดือน | สรุปงวดเงินเดือนและยอดรวมสลิปรายคน (เฉพาะงวดที่ล็อก/จ่ายแล้ว · ไม่มีเลขบัญชีธนาคาร) |
รายการ Endpoint
ที่อยู่หลัก https://homehqth.com/api/v1 · ตอบเป็น JSON (UTF-8) · วันที่ใช้รูปแบบ YYYY-MM-DD ตามเวลาประเทศไทย · เวลาเป็น ISO 8601 (UTC) · เงินเป็น สตางค์ (จำนวนเต็ม เช่น 2500000 = 25,000.00 บาท)
| Method / Path | Scope | คำอธิบาย |
|---|---|---|
GET/me | — | องค์กรและสิทธิ์ของ key นี้ (ใช้ทดสอบการเชื่อมต่อ) |
GET/org | org:read | บริษัท สาขา แผนก ตำแหน่ง |
GET/members | members:read | รายชื่อพนักงาน (กรอง: status, departmentId, branchId, companyId, email) |
GET/members/{id} | members:read | พนักงานหนึ่งคน |
GET/attendance | attendance:read | การลงเวลา — ต้องมี from, to (ช่วงไม่เกิน 93 วัน) · กรอง memberId |
GET/leave-requests | leave:read | ใบลาที่คาบเกี่ยวช่วง from–to · กรอง status, memberId |
GET/payroll/runs | payroll:read | งวดเงินเดือน + ยอดรวม (กรอง status, month=YYYY-MM) |
GET/payroll/runs/{id} | payroll:read | งวดเงินเดือนหนึ่งงวด |
GET/payroll/runs/{id}/payslips | payroll:read | ยอดรวมสลิปรายคน — เฉพาะงวดที่ล็อกหรือจ่ายแล้ว (ไม่งั้น 409 RUN_NOT_FINAL) |
พนักงาน — GET /members
| พารามิเตอร์ | คำอธิบาย |
|---|---|
status | active · suspended · all (ค่าเริ่มต้น = ทุกคนที่ยังอยู่ในองค์กร) — คนที่ลาออกแล้วไม่อยู่ในรายการ (รับแจ้งผ่าน webhook member.left) |
departmentId branchId companyId | กรองตามหน่วยงาน |
email | หาจากอีเมล (ไม่สนตัวพิมพ์) |
limit cursor | ดู การแบ่งหน้า |
{
"data": [
{
"id": "3f2a9c1e-…",
"employeeCode": "EMP-0012",
"name": "สมชาย ใจดี",
"nickname": "ชาย",
"email": "somchai@acme.co.th",
"role": "member",
"employmentStatus": "active",
"resignEffectiveDate": null,
"seatType": "full",
"hasAccount": true,
"company": {
"id": "c-…",
"name": "บริษัท เอซีเอ็มอี จำกัด"
},
"branch": {
"id": "b-…",
"name": "สำนักงานใหญ่"
},
"department": {
"id": "d-…",
"name": "บัญชี"
},
"position": {
"id": "p-…",
"title": "นักบัญชี"
},
"managerId": "m-…",
"joinedAt": "2026-03-01T02:00:00.000Z"
}
],
"pagination": {
"limit": 50,
"hasMore": true,
"nextCursor": "WyIyMDI2LTAzLTAxIDA5OjAwOjAwKzAwIiwiM2YyYTljMWUiXQ"
}
}
การลงเวลา — GET /attendance?from=2026-10-01&to=2026-10-31
{
"data": [
{
"id": "a-…",
"memberId": "m-…",
"workDate": "2026-10-01",
"checkIn": "2026-10-01T01:58:12.000Z",
"checkOut": "2026-10-01T11:03:40.000Z",
"mode": "office",
"branchId": "b-…",
"edited": false
}
],
"pagination": {
"limit": 100,
"hasMore": false,
"nextCursor": null
}
}
mode: office เข้าออฟฟิศ · wfh ทำงานที่บ้าน · onsite นอกสถานที่ · edited = ฝ่ายบุคคลแก้ไขหรือเพิ่มให้ (มีประวัติในแอป)
การลา — GET /leave-requests?from=2026-10-01&to=2026-12-31&status=approved
คืนใบลาที่ช่วงวันลาคาบเกี่ยวกับ from–to · type เป็นรหัสประเภท (เช่น sick personal vacation หรือรหัส c_… ของประเภทที่องค์กรเพิ่มเอง) · portion: full morning afternoon · status: pending, approved, rejected, cancelled
เงินเดือน — GET /payroll/runs และ /payroll/runs/{id}/payslips
{
"data": [
{
"id": "r-…",
"companyId": "c-…",
"month": "2026-09",
"periodStart": "2026-09-01",
"periodEnd": "2026-09-30",
"payDate": "2026-09-30",
"status": "paid",
"lockedAt": "…",
"paidAt": "…",
"publishedAt": "…",
"totals": {
"headcount": 42,
"incomeSatang": 128450000,
"deductionSatang": 9800000,
"netSatang": 118650000,
"taxSatang": 3200000,
"ssoEmployeeSatang": 3675000,
"ssoEmployerSatang": 3675000
}
}
],
"pagination": {
"limit": 50,
"hasMore": false,
"nextCursor": null
}
}
สลิปรายคนให้เฉพาะยอดรวม: รายได้ รายการหัก สุทธิ ภาษี ประกันสังคม กองทุนสำรองเลี้ยงชีพ พร้อมชื่อ/รหัส/แผนก ณ งวดนั้น — ไม่มีเลขบัญชีธนาคารและเลขบัตรประชาชน (ไฟล์โอนธนาคารสร้างในแอปเท่านั้น)
โครงสร้างองค์กร — GET /org
คืน companies branches departments positions ทั้งหมดในครั้งเดียว ใช้จับคู่ id กับระบบของคุณ
การแบ่งหน้า
รายการทุกชนิดใช้ cursor: ส่ง limit (1–200 ค่าเริ่มต้น 50 หรือ 100 สำหรับการลงเวลา/สลิป) แล้วเรียกหน้าถัดไปด้วย cursor=<pagination.nextCursor> จนกว่า hasMore เป็น false · cursor เป็นค่าทึบ อย่าแก้หรือประกอบเอง
async function all(path) {
const out = [];
let cursor = '';
do {
const url = new URL('https://homehqth.com/api/v1' + path);
url.searchParams.set('limit', '200');
if (cursor) url.searchParams.set('cursor', cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.HOMEHQ_API_KEY}` } });
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
out.push(...body.data);
cursor = body.pagination.nextCursor ?? '';
} while (cursor);
return out;
}
ข้อผิดพลาด
ทุกข้อผิดพลาดใช้รูปแบบเดียวกัน ข้อความเป็นภาษาอังกฤษ ให้ตัดสินจาก error.code (คงที่) ไม่ใช่ข้อความ และแนบ requestId เมื่อติดต่อทีมงาน
{
"error": {
"code": "INSUFFICIENT_SCOPE",
"message": "This API key lacks the \"payroll:read\" scope",
"requiredScope": "payroll:read"
},
"requestId": "6c1b…"
}
| HTTP | code | ความหมาย |
|---|---|---|
| 400 | INVALID_REQUEST | พารามิเตอร์ผิด (ดู error.param) |
| 401 | UNAUTHORIZED / INVALID_API_KEY | ไม่ได้ส่ง key หรือ key ผิด/ถูกเพิกถอน |
| 402 | PLAN_FEATURE / ORG_LOCKED | แพ็กเกจต่ำกว่า Business หรือแพ็กเกจหมดอายุ/องค์กรถูกระงับ |
| 403 | INSUFFICIENT_SCOPE | key ไม่มีสิทธิ์ endpoint นี้ (ดู error.requiredScope) |
| 404 | NOT_FOUND | ไม่พบข้อมูล หรือเป็นข้อมูลขององค์กรอื่น |
| 409 | RUN_NOT_FINAL | งวดเงินเดือนยังไม่ล็อก/จ่าย |
| 429 | RATE_LIMITED | เรียกถี่เกินไป — รอตามหัว Retry-After |
| 500 | SERVER_ERROR | ข้อผิดพลาดฝั่ง HomeHQ — ลองใหม่ภายหลัง |
จำกัดความถี่
120 คำขอต่อนาทีต่อ API key · ทุกคำตอบมีหัว X-RateLimit-Limit X-RateLimit-Remaining X-RateLimit-Reset (unix วินาที) · เกินแล้วได้ 429 พร้อม Retry-After · ซิงก์ข้อมูลทั้งหมดวันละครั้ง + ใช้ webhook รับการเปลี่ยนแปลงระหว่างวัน จะไม่ชนเพดาน
Webhooks Business+
เพิ่มปลายทางที่ ตั้งค่า → API และการเชื่อมต่อ → Webhooks ใส่ URL (https เท่านั้น) เลือกเหตุการณ์ แล้วคัดลอก signing secret (whsec_… แสดงครั้งเดียว — หมุนใหม่ได้ทุกเมื่อ) · กด ส่งเหตุการณ์ทดสอบ เพื่อดูว่าระบบของคุณรับได้ และดูประวัติการส่ง (สถานะ HTTP เวลาที่ใช้ ข้อผิดพลาดล่าสุด) ได้ทันที
HomeHQ ส่ง POST แบบ JSON พร้อมหัวต่อไปนี้:
| หัว | ค่า |
|---|---|
X-HomeHQ-Signature | t=<unix>,v1=<hex> — ดู การตรวจลายเซ็น |
X-HomeHQ-Event | ชื่อเหตุการณ์ เช่น leave.approved |
X-HomeHQ-Event-Id | id ของเหตุการณ์ (คงเดิมทุกครั้งที่ส่งซ้ำ) — ใช้กันประมวลผลซ้ำ |
X-HomeHQ-Delivery | id ของการส่งครั้งนี้ |
X-HomeHQ-Attempt | ครั้งที่ส่ง (1–5) |
{
"id": "evt_8mQ2vX…",
"type": "leave.approved",
"apiVersion": "2026-10-01",
"createdAt": "2026-10-11T03:15:20.000Z",
"orgId": "o-…",
"data": {
"leave": {
"id": "l-…",
"memberId": "m-…",
"type": "vacation",
"startDate": "2026-10-20",
"endDate": "2026-10-21",
"portion": "full",
"days": 2,
"status": "approved",
"approverId": "m-…",
"decidedAt": "2026-10-11T03:15:19.000Z",
"createdAt": "2026-10-10T09:00:00.000Z"
},
"member": {
"id": "m-…",
"name": "สมชาย ใจดี",
"employeeCode": "EMP-0012",
"email": "somchai@acme.co.th"
}
}
}
2xx ภายใน 10 วินาที (ควรรับไว้ในคิวแล้วตอบทันที ค่อยประมวลผลทีหลัง) · HomeHQ ไม่ตามการเปลี่ยนเส้นทาง (3xx = ไม่สำเร็จ) · อ่านคำตอบไม่เกิน 64 KB · ปลายทางต้องเป็นที่อยู่สาธารณะ — localhost เครือข่ายภายใน (10.x, 192.168.x ฯลฯ) และที่อยู่ metadata ของคลาวด์ถูกปฏิเสธเหตุการณ์
| เหตุการณ์ | เกิดเมื่อ | data |
|---|---|---|
member.joined | พนักงานเข้าร่วมองค์กร | { member } |
member.left | พนักงานออกจากองค์กร (ลาออก/นำออก) | { member, reason, terminationType, effectiveDate, lastWorkDate } |
member.suspended | ระงับการใช้งานพนักงาน | { member } |
member.reactivated | เปิดใช้งานพนักงานอีกครั้ง | { member } |
attendance.checked_in | ลงเวลาเข้างาน | { attendance, member } |
attendance.checked_out | ลงเวลาออกงาน | { attendance, member } |
leave.requested | ยื่นใบลา | { leave, member } |
leave.approved | อนุมัติใบลา | { leave, member } |
leave.rejected | ไม่อนุมัติใบลา | { leave, member } |
request.approved | อนุมัติคำขอ (ลืมลงเวลา/OT/เบิกเงิน ฯลฯ) | { request, member } |
payroll.published | เผยแพร่สลิปเงินเดือน | { run } (ยอดรวมทั้งงวด ไม่มียอดรายคน) |
announcement.published | ประกาศใหม่ | { announcement } |
member ในเหตุการณ์ member.* มีรูปแบบเดียวกับ GET /members/{id} · ในเหตุการณ์อื่นเป็นข้อมูลย่อ { id, name, employeeCode, email } · member.joined เกิดเมื่อมีรายชื่อใหม่ในองค์กร (ผู้ดูแลเพิ่ม, SCIM, หรือพนักงานเข้าร่วมด้วยรหัสเชิญ) · ปุ่มทดสอบส่งเหตุการณ์ webhook.test
ตรวจลายเซ็น (สำคัญ)
ลายเซ็น = HMAC-SHA256 ของข้อความ <t>.<body ดิบ> ด้วย signing secret แล้วเข้ารหัสเป็น hex · ต้องคิดจาก body ดิบก่อนแปลง JSON · ปฏิเสธลายเซ็นที่ t ห่างจากเวลาปัจจุบันเกิน 5 นาที (กันการส่งซ้ำ) · เทียบแบบเวลาคงที่
// Node.js + Express
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const SECRET = process.env.HOMEHQ_WEBHOOK_SECRET; // whsec_...
const seen = new Set(); // ใช้ฐานข้อมูลจริงในระบบของคุณ
app.post('/homehq/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const header = req.get('X-HomeHQ-Signature') || '';
const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
const t = Number(parts.t);
const expected = crypto.createHmac('sha256', SECRET).update(`${t}.${req.body}`).digest('hex');
const given = Buffer.from(parts.v1 || '', 'hex');
const ok = given.length === 32 && crypto.timingSafeEqual(given, Buffer.from(expected, 'hex'))
&& Math.abs(Date.now() / 1000 - t) < 300;
if (!ok) return res.status(400).send('bad signature');
const event = JSON.parse(req.body);
if (seen.has(event.id)) return res.sendStatus(200); // ส่งซ้ำ — ทำไปแล้ว
seen.add(event.id);
queue.push(event); // ประมวลผลทีหลัง
res.sendStatus(200);
});
<?php // PHP
$secret = getenv("HOMEHQ_WEBHOOK_SECRET");
$body = file_get_contents("php://input");
parse_str(str_replace(",", "&", $_SERVER["HTTP_X_HOMEHQ_SIGNATURE"] ?? ""), $sig);
$expected = hash_hmac("sha256", $sig["t"] . "." . $body, $secret);
if (!hash_equals($expected, $sig["v1"] ?? "") || abs(time() - (int)$sig["t"]) > 300) {
http_response_code(400); exit;
}
$event = json_decode($body, true);
หมุน secret ใหม่แล้ว secret เดิมใช้ไม่ได้ทันที — อัปเดตค่าในระบบของคุณก่อนกดหมุน หรือรับได้ทั้งสองค่าช่วงสั้น ๆ
การส่งซ้ำและการปิดอัตโนมัติ
ไม่ได้ 2xx (รวมหมดเวลา/ต่อไม่ได้) → ส่งซ้ำหลัง 1 นาที, 5 นาที, 30 นาที และ 2 ชั่วโมง (รวม 5 ครั้ง) ด้วย event id เดิม · ล้มเหลวครบทุกครั้งติดกัน 10 เหตุการณ์ → ปิดปลายทางอัตโนมัติและแจ้งผู้ดูแลในแอป แก้ระบบแล้วเปิดใหม่ได้ และกด ส่งอีกครั้ง ในประวัติการส่งได้ · เก็บประวัติการส่ง 30 วัน · ลำดับการมาถึงไม่รับประกัน ให้ใช้ createdAt เรียงเอง
SCIM 2.0 Enterprise
ให้ IdP ขององค์กรสร้างพนักงานใหม่ อัปเดตข้อมูล และระงับคนที่ออกจากบริษัทใน HomeHQ อัตโนมัติ · สร้าง token ที่ ตั้งค่า → API และการเชื่อมต่อ → SCIM (เฉพาะเจ้าของระบบ · ขึ้นต้นด้วย hhqscim_ แสดงครั้งเดียว องค์กรละ 1 token — สร้างใหม่แล้ว token เดิมใช้ไม่ได้ทันที)
| รายการ | ค่า |
|---|---|
| Tenant / Base URL | https://homehqth.com/scim/v2 |
| Authentication | HTTP Header — Bearer token |
| Resources | /Users /Groups /ServiceProviderConfig /ResourceTypes /Schemas |
| รองรับ | GET (filter: eq, ne, co, sw, ew, gt, lt, pr, and/or/not · startIndex/count) · POST · PUT · PATCH · DELETE |
| ไม่รองรับ | Bulk, sort, ETag, เปลี่ยนรหัสผ่าน (พนักงานเข้าระบบด้วย Google/Microsoft หรืออีเมลของตัวเอง) |
| SCIM attribute | HomeHQ |
|---|---|
userName | อีเมล (แนะนำ — ใช้ผูกบัญชีตอนพนักงานเข้าระบบ) หรือชื่อผู้ใช้อื่น เช่น รหัสพนักงาน แล้วส่งอีเมลใน emails · ไม่มีอีเมลเลย = สร้างเป็นพนักงานที่ยังเข้าสู่ระบบไม่ได้ |
name.givenName name.familyName / displayName | ชื่อ-นามสกุล |
active | false = ระงับการใช้งาน (เก็บประวัติลงเวลา/ลา/เงินเดือนครบ ไม่นับที่นั่ง) · true = เปิดใช้อีกครั้ง (ต้องมีที่นั่งว่าง) |
title | ตำแหน่ง (ไม่มีชื่อนี้ = สร้างให้ · ตำแหน่งในแผนกฝ่ายบุคคล = 400) |
…enterprise:2.0:User:department | แผนก (ไม่มี = สร้างให้ · แผนกฝ่ายบุคคล = 400) |
…enterprise:2.0:User:employeeNumber | รหัสพนักงาน |
…enterprise:2.0:User:manager | หัวหน้า (id ของ User ใน HomeHQ) |
phoneNumbers nickName externalId | เบอร์โทร ชื่อเล่น รหัสจาก IdP |
| Group | แผนก — เพิ่มสมาชิกเข้ากลุ่ม = ย้ายเข้าแผนกนั้น (คนหนึ่งอยู่ได้แผนกเดียว) · แผนกที่สร้างในแอป: เพิ่ม/ถอดทีละคนได้ แต่เปลี่ยนชื่อ/แทนที่สมาชิกทั้งชุดไม่ได้ |
409 · สร้างซ้ำพร้อมกัน (IdP ส่งซ้ำ) ได้ 409 uniqueness เพียงคำขอเดียวที่สำเร็จ · POST ด้วย userName ของคนที่ลบไปแล้วจะฟื้นรายชื่อเดิมเฉพาะเมื่ออีเมลหรือ externalId ตรงกัน (ตรงแค่ userName = 409)403 mutability): เจ้าของและผู้ดูแล อ่านได้ แต่แก้ไข ระงับ ลบ หรือย้ายแผนกไม่ได้ (ส่งค่าเดิมซ้ำได้ · ตั้ง externalId ได้) · ฝ่ายบุคคล — SCIM เพิ่มคนเข้า/ย้ายคนออกจากแผนกฝ่ายบุคคล และเปลี่ยนชื่อหรือสมาชิกของกลุ่มที่เป็นแผนกฝ่ายบุคคลไม่ได้ (department/title ที่ตรงกับแผนก/ตำแหน่งฝ่ายบุคคล = 400) · อีเมล ของหัวหน้างานหรือฝ่ายบุคคลที่ยังไม่เคยเข้าสู่ระบบเปลี่ยนผ่าน SCIM ไม่ได้ · PATCH มี Operations ได้ไม่เกิน 100 รายการ และ path ยาวไม่เกิน 512 ตัวอักษร — จัดการเรื่องเหล่านี้ในแอป HomeHQMicrosoft Entra ID (Azure AD)
- Entra admin center → Enterprise applications → New application → Create your own application → ตั้งชื่อ "HomeHQ" เลือก Integrate any other application you don't find in the gallery (Non-gallery)
- เมนู Provisioning → Get started → Provisioning Mode = Automatic
- Tenant URL =
https://homehqth.com/scim/v2· Secret Token = SCIM token จาก HomeHQ → กด Test Connection แล้ว Save - Mappings: ตรวจว่า userPrincipalName หรือ mail →
userName(แนะนำอีเมลจริงที่พนักงานใช้ · ถ้าเป็นรหัสพนักงาน ให้ map mail →emails[type eq "work"].valueด้วย), Switch([IsSoftDeleted]…) →active, department →…:department, jobTitle →title— ลบ mapping ที่ไม่ใช้ได้ - Users and groups → เพิ่มคน/กลุ่มที่จะใช้ HomeHQ → กลับไปที่ Provisioning ตั้ง Provisioning Status = On (Entra ซิงก์ทุก ~40 นาที หรือกด Provision on demand เพื่อทดสอบทีละคน)
Okta
- Okta Admin → Applications → Create App Integration → SWA หรือ SAML 2.0 (ใช้เฉพาะเพื่อ provisioning ก็ได้) → แท็บ General → App Settings → Provisioning = SCIM
- แท็บ Provisioning → Integration: SCIM connector base URL =
https://homehqth.com/scim/v2· Unique identifier field =userName· เลือก Push New Users, Push Profile Updates, Push Groups · Authentication Mode = HTTP Header แล้ววาง token → Test Connector Configuration - To App → เปิด Create Users, Update User Attributes, Deactivate Users
- แท็บ Assignments เพิ่มคน/กลุ่ม · แท็บ Push Groups เพื่อสร้างแผนกจากกลุ่ม Okta
Google Workspace
ต้องการความช่วยเหลือในการเชื่อมระบบ?
ทีมงานช่วยวางแผนการเชื่อม API/SCIM กับระบบเดิมได้ — ลูกค้า Enterprise มีผู้ดูแลบัญชีเฉพาะองค์กร
ติดต่อทีมงาน