Integrasikan API produksi untuk pengiriman jadwal dengan kunci API yang terikat ke langganan berbayar Anda. Default penyewa dapat disimpan dengan PATCH /v1/schedule-defaults; harian mingguan per staf dibaca atau diganti penuh dengan GET/PUT /v1/staff/{staffId}/weekly-shift-wish. Penagihan mengikuti paket dan kontrak Anda (bukan bayar per panggilan API). Halaman ini mendokumentasikan hak, aturan validasi, dan kode error — gunakan bilah sisi untuk melompat ke setiap field.
Halaman ini hanya mencakup API REST produk di API Gateway ({stage}/v1/*, autentikasi x-api-key).
Rute Next.js /api/* (webhook Stripe, gambar OG, Web Vitals, dll.) bersifat internal untuk aplikasi web dan bukan bagian dari API pengembang ini. Jangan gunakan untuk integrasi eksternal.
GET /v1/processing-history tidak disediakan (dihapus bersama UI lama) dan tidak tercantum dalam daftar endpoint di halaman ini.
API HTTP ini merupakan bagian produk berbayar: akses memerlukan perjanjian komersial aktif dan kunci diterbitkan ke organisasi Anda setelah onboarding.
Penagihan berdasarkan langganan dan kontrak. Untuk paket berbayar, biaya biasanya mengikuti halaman harga (mis. per staf terdaftar per bulan).
Batas playground / tingkat gratis tidak berlaku untuk kunci API berbayar. Batas efektif seperti rentang jadwal, jumlah staf, dan granularitas 15 menit ditentukan oleh hak berbayar Anda. Lihat Batas & default di halaman ini.
Permintaan harus menyertakan kunci API yang valid yang diterbitkan untuk langganan berbayar Anda. Buat, putar, dan cabut kunci dari area akun setelah masuk.
Kirim kunci di header x-api-key. Kunci terikat ke organisasi Anda untuk identifikasi penyewa dan batas akses berdasarkan paket.
Kelola kunci: Manajemen API
Kirim kondisi jadwal sebagai JSON. Ini adalah permukaan integrasi berbayar; URL dasar pasti diberikan per lingkungan setelah akses API disediakan.
Gunakan URL dasar yang diberikan saat akses API disediakan atau oleh kontak operasi Anda.
Ganti **BASE_URL** dengan URL dasar API (awalan jalur) yang diberikan saat akses Anda disediakan.
Kirim kunci API di header **x-api-key**. Organisasi (penyewa) Anda diidentifikasi dari kunci — Anda tidak perlu mengirim ID penyewa terpisah di query string.
Pembacaan dan pembaruan perusahaan (GET/PATCH /v1/company) memerlukan langganan berbayar yang aktif. Anda dapat menerima **503** (mis. kode **STRIPE_NOT_CONFIGURED**) bila penagihan belum dikonfigurasi untuk penyewa Anda.
Windows PowerShell: `\` di akhir baris **bukan** kelanjutan baris. Tulis satu baris, atau akhiri setiap baris dengan backtick (`) untuk melanjutkan.
curl -sS -D - \ -H "x-api-key: YOUR_API_KEY" \ "BASE_URL/v1/schedule-results?limit=10" curl -sS -D - \ -H "x-api-key: YOUR_API_KEY" \ "BASE_URL/v1/company"
URL dasar dan kunci API yang sama seperti POST /v1/schedule. Query opsional: limit (1–100, bawaan 50), cursor (token buram dari field nextCursor respons sebelumnya).
GET /v1/company dan pembaruan perusahaan memerlukan langganan berbayar yang aktif. Anda dapat menerima **503 / STRIPE_NOT_CONFIGURED** bila penagihan belum dikonfigurasi.
| Metode | Jalur | Deskripsi |
|---|---|---|
| GET | {baseUrl}/v1/schedule-results | Mendaftar baris induk SCHEDULE_RESULT: conditionId, status, candidateCount, createdAt/updatedAt, dll. Paginasi baris induk DynamoDB. |
| GET | {baseUrl}/v1/schedule-results/history | Pencarian riwayat hasil jadwal (sama seperti browser). from / to (ISO 8601, default awal layanan hingga sekarang), keyword, eventName (INSERT,MODIFY,REMOVE dipisah koma), limit, cursor. Menggabungkan data terbaru dan arsip otomatis; hanya items / nextCursor. |
| GET | {baseUrl}/v1/schedule-results/{conditionId} | Mengambil satu baris induk SCHEDULE_RESULT menurut conditionId (atribut JSON; PK/SK dihilangkan). |
| GET | {baseUrl}/v1/schedule-results/{conditionId}/resolution | Output optimasi terselesaikan: status, candidates, confirmedAssignments jika ada. Jika status completed dan belum dikonfirmasi, rank-1 dapat dikonfirmasi otomatis pada GET ini (efek samping). Gunakan POST …/confirm-assignments untuk konfirmasi manual. |
| GET | {baseUrl}/v1/schedule-results/{conditionId}/review | Payload tinjauan untuk konfirmasi manual (kandidat, requiredByCellKey, allowedCellKeys staf, dll.). |
| GET | {baseUrl}/v1/schedule-results/{conditionId}/emergency-shift-context | Konteks shift darurat (tanggal kalender, staf, slot). Langganan berbayar diperlukan; null jika kondisi tidak ada. |
| GET | {baseUrl}/v1/schedule-conditions | Daftar baris induk SCHEDULE_CONDITION (conditionId, tanggal, publicApiCancelledAt opsional). |
| GET | {baseUrl}/v1/schedule-conditions/{conditionId} | Baris induk kondisi plus reqDays dan staffSnapshots (tanpa PK/SK). |
| GET | {baseUrl}/v1/audit-logs | Daftar entri audit log (terbaru dulu; paginasi cursor). |
| GET | {baseUrl}/v1/schedule-defaults | Baris default jadwal penyewa (SCHEDULE_DEFAULTS) atau null jika belum disimpan. |
| GET | {baseUrl}/v1/schedule-actual/{conditionId} | Baris SCHEDULE_ACTUAL penugasan aktual, atau null jika tidak ada. |
| GET | {baseUrl}/v1/staff/{staffId}/weekly-shift-wish | Baris keinginan shift mingguan staf, atau null jika tidak ada. |
| GET | {baseUrl}/v1/company | Mengembalikan field Stripe Customer (nama, email, telepon, alamat) untuk customerId pada kunci API Anda. |
| GET | {baseUrl}/v1/users | Mendaftar pengguna penyewa (opsional: limit, cursor, userName, permissionProfileId, scope fullAccess|nonFullAccess). |
| GET | {baseUrl}/v1/users/{userId} | Mendapatkan satu pengguna berdasarkan userId di path. |
| GET | {baseUrl}/v1/staff | Mendaftar staf aktif penyewa (diurut menurut nama tampilan). |
| GET | {baseUrl}/v1/staff/{staffId} | Mengambil satu anggota staf menurut staffId termasuk detail ketenagakerjaan (laborLawCompliance, laborFlsaExempt, batas pribadi, laborConstraintMask). Soft delete → 404. |
Gunakan kunci API yang sama dengan body JSON. PATCH /v1/company menolak string kosong untuk field seperti nama perusahaan (selaras dengan aplikasi web). PATCH /v1/schedule-defaults menyimpan default penyewa (requirementsByCellKey, horizon perencanaan, dll.); field berbayar mengikuti langganan Anda. PUT /v1/staff/{staffId}/weekly-shift-wish mengganti seluruh grid keinginan mingguan staf tersebut (lihat catatan validasi). DELETE /v1/users/{userId} mengembalikan 409 jika organisasi tidak akan memiliki pengguna atau aturan admin terakhir berlaku. POST /v1/staff mengembalikan 409 STAFF_LIMIT jika daftar melebihi batas kontrak.
POST /v1/users membutuhkan userName, email, permissionProfileId; opsional: locale, password. PATCH pengguna: hanya field yang berubah. POST /v1/staff: JSON { "displayName": "..." } saja. PATCH /v1/staff/{staffId}: displayName, laborLawCompliance, laborFlsaExempt, personalMaxWeeklyMinutes / personalMaxMonthlyMinutes / personalMaxThreeMonthMinutes (bilangan bulat atau null), laborConstraintMask (objek atau null jika laborLawCompliance true) — field ketenagakerjaan berbayar. POST /v1/schedule-results/{conditionId}/emergency-shift: absentStaffIds, absentDatesYmd dan/atau absentSlots (berbayar, jadwal sumber selesai). POST …/confirm-assignments: array assignments dan relaxAvailability opsional. PATCH /v1/schedule-defaults: PUBLIC_API_SCHEDULE_REQUEST_BODY.md §12. PUT /v1/staff/{staffId}/weekly-shift-wish: scheduleStartDate, scheduleEndDate, timeRangeStart, timeRangeEnd, wishByCellKey.
| Metode | Jalur | Deskripsi |
|---|---|---|
| PATCH | {baseUrl}/v1/company | Memperbarui field profil perusahaan (pelanggan penagihan). |
| PATCH | {baseUrl}/v1/schedule-defaults | Menyimpan default jadwal penyewa (body selaras saveSchema di schedule-defaults-actions). Field berbayar mengikuti langganan Anda. |
| POST | {baseUrl}/v1/users | Membuat pengguna. Mengembalikan 201 dengan JSON user. |
| PATCH | {baseUrl}/v1/users/{userId} | Memperbarui field pengguna (userName, email, permissionProfileId, locale). |
| DELETE | {baseUrl}/v1/users/{userId} | Menghapus pengguna. 409 jika tidak ada pengguna tersisa atau aturan admin terakhir. |
| POST | {baseUrl}/v1/staff | Membuat anggota staf (displayName). Mengembalikan 201 dengan JSON staff. |
| POST | {baseUrl}/v1/schedule-results/{conditionId}/emergency-shift | Mengkloning jadwal sumber yang selesai dengan absensi diterapkan; mengembalikan 201 dengan conditionId. Langganan berbayar diperlukan. |
| POST | {baseUrl}/v1/schedule-results/{conditionId}/confirm-assignments | Memvalidasi dan menyimpan penugasan yang diedit manual (200 dengan { ok: true }). |
| PATCH | {baseUrl}/v1/staff/{staffId} | Memperbarui displayName dan detail ketenagakerjaan (laborLawCompliance, laborFlsaExempt, batas pribadi, laborConstraintMask). |
| DELETE | {baseUrl}/v1/staff/{staffId} | Soft delete anggota staf (mengatur deletedAt). |
| DELETE | {baseUrl}/v1/schedule-conditions/{conditionId} | Menandai kondisi dibatalkan (publicApiCancelledAt); tidak menghapus baris anak. |
| PUT | {baseUrl}/v1/schedule-actual/{conditionId} | Menyimpan penugasan aktual JSON { "assignments": [ ... ] } (divalidasi terhadap grid kondisi). |
| PUT | {baseUrl}/v1/staff/{staffId}/weekly-shift-wish | Mengganti keinginan mingguan: grid penuh (1–7 hari), wishByCellKey per sel (NONE|LOW|HIGH); granularitas dari default penyewa. |
| POST | {baseUrl}/v1/users/{userId}/restore | Memulihkan pengguna yang dihapus secara logis. |
| Header | Deskripsi |
|---|---|
| x-api-key | Kunci API terikat ke langganan berbayar Anda (mengidentifikasi penyewa dan batas paket). |
| Content-Type | application/json |
Beberapa header respons (seperti ID permintaan) adalah metadata pelacakan, bukan kunci API Anda. Anggap **body** JSON bersifat rahasia bila berisi data perusahaan atau pengguna.
Batas validasi tipikal untuk kontrak Anda (granularitas 15 menit, rentang jadwal, jumlah staf terdaftar, dan batas terkait).
| Pengaturan | API berbayar (tipikal) |
|---|---|
| Model penagihan | Langganan Stripe; biaya produk biasanya mengikuti jumlah kursi staf terdaftar sesuai halaman harga (bukan tagihan per panggilan API). |
| maxScheduleDays | Hingga 14 hari kalender per pengiriman untuk perencanaan detail dua minggu standar (rentang lebih lebar hanya jika kontrak mengizinkan). |
| maxStaffPerSchedule | Hingga 500 baris staff per POST /v1/schedule (PUBLIC_SCHEDULE_MAX_STAFF; staffId inline di body). |
| maxRosterStaff | Hingga 30 staf aktif via POST /v1/staff (STAFF_ROSTER_MAX_PAID); 409 STAFF_LIMIT jika terlampaui. |
| allowedGranularities | [60, 15] — slot 15 menit adalah fitur berbayar; 60 menit juga didukung. |
| maxPayloadBytes | 524288 (512 KiB) UTF-8 kecuali batas lebih tinggi diberikan. |
| strictUnknownRootKeys | true — kunci tingkat atas atau di staff yang tidak dikenal ditolak |
Kebutuhan kepala per sel tetap bilangan bulat 0 hingga 15. Melebihi batas frekuensi permintaan dapat mengembalikan respons error.
Saat mode ketat aktif, hanya kunci tingkat atas berikut yang diterima. Kunci lain mengembalikan UNKNOWN_FIELD.
Payload mengikuti model permintaan jadwal publik berbayar: tanggal kalender, zona waktu, grid slot (60 atau 15 menit di API berbayar), kebutuhan per sel, dan ketersediaan staf. Yurisdiksi hukum kerja, flag optimasi berbayar, dan field hukum kerja tingkat staf bukan bagian JSON — server menulis default pada baris induk SCHEDULE_CONDITION saat menyimpan (lihat «Hukum kerja & flag berbayar»). Jangan sertakan kunci DynamoDB atau tipe entitas internal di body.
| Field | Tipe | Wajib | Catatan |
|---|---|---|---|
| timeZone | string | Ya | Zona waktu IANA untuk menafsirkan tanggal dan slot. |
| scheduleStartDate / scheduleEndDate | string (YYYY-MM-DD) | Ya | Rentang kalender inklusif; mulai ≤ akhir. |
| timeRangeStart / timeRangeEnd | string (HH:mm) | Ya | Rentang jam dinding yang mendefinisikan kolom slot; harus menghasilkan setidaknya satu slot. |
| slotGranularityMinutes | 60 | 15 | Ya | API berbayar: 60 (per jam) atau 15 (15 menit). Harus ada di allowedGranularities. |
| requirementsByCell | object | Ya | Kunci = cellKey di grid yang dihitung; nilai = bilangan bulat 0–15. |
| staff | array | Ya | Tidak kosong; ukuran maks. sesuai batas; setiap item: staffId, displayName, availableCells opsional. |
Bagian berikut mencerminkan validator di `app/lib/public-schedule-api/validate.ts` dan sanitiser di `sanitize.ts`, dengan default berbayar dari `PUBLIC_SCHEDULE_SUBMIT_DEFAULTS` kecuali opsi diberikan. Kirim angka JSON sebagai angka sebenarnya (bukan string). Setelah validasi, `build-schedule-transact-items.ts` menambahkan field baris induk (salinan optimasi berbayar, yurisdiksi hukum kerja, versi model) yang bukan kunci permintaan — lihat «Hukum kerja & flag berbayar».
string | dihilangkan · Wajib: Tidak — opsional
Nilai yang diizinkan
Perilaku
Error umum
TYPE_ERRORNilai apiVersion tidak didukung.string · Wajib: Ya
Nilai yang diizinkan
Perilaku
Error umum
INVALID_TIME_ZONEHilang, kosong, atau zona IANA tidak valid.string, string · Wajib: Ya — keduanya
Nilai yang diizinkan
Perilaku
Error umum
INVALID_DATE_RANGEFormat buruk, tanggal tidak valid, atau rentang kosong.SCHEDULE_SPAN_TOO_LONGLebih dari maxScheduleDays hari.string, string · Wajib: Ya — keduanya
Nilai yang diizinkan
Perilaku
Error umum
INVALID_TIME_RANGENilai hilang atau nol slot untuk rentang.number (angka JSON) · Wajib: Ya
Nilai yang diizinkan
Perilaku
Error umum
INVALID_GRANULARITYBukan 60/15, atau tidak diizinkan untuk paket.Record<string, number> · Wajib: Ya
Nilai yang diizinkan
Perilaku
Error umum
INVALID_REQUIREMENTSBukan objek atau nilai numerik tidak valid untuk kunci.UNKNOWN_CELL_KEYKunci tidak dalam grid tanggal × slot yang dihitung.array · Wajib: Ya — array tidak kosong
Nilai yang diizinkan
Perilaku
Error umum
INVALID_STAFFArray kosong, terlalu banyak baris, objek buruk, atau sanitasi gagal.UNKNOWN_FIELDKunci ekstra pada objek staff dalam mode ketat.DUPLICATE_STAFF_IDstaffId yang sama dua kali.string[] | dihilangkan · Wajib: Tidak — opsional
Nilai yang diizinkan
Pemeriksaan SHORTFALL
Error umum
INVALID_AVAILABLE_CELLKunci sel tidak dikenal atau entri kosong.SHORTFALL_CELLSStaf tidak cukup untuk kebutuhan sel.t/a — disimpan di server · Dalam permintaan: Tidak — jangan kirim kunci ini
Yang disimpan API pada baris induk
Dokumentasi
Jika mengirim kunci yang dilarang
UNKNOWN_FIELDMode ketat menolak properti root atau staff yang tidak dikenal.Diterapkan sebelum atau selama validasi seperti di `sanitize.ts`. Menjelaskan penolakan INVALID_STAFF.
staffId
displayName
Kunci sel (requirements / availableCells)
202 Accepted
Body lolos validasi dan kondisi ditulis; optimasi dapat berlanjut secara asinkron. Handler dapat mengembalikan JSON dengan conditionId dan field terkait.
Error validasi mengembalikan informasi terstruktur dengan `code` yang stabil. Parsing sebelum validasi (INVALID_JSON, PAYLOAD_TOO_LARGE). Kegagalan persistensi dapat muncul sebagai DYNAMODB_ERROR. PATCH /v1/schedule-defaults dapat mengembalikan SCHEDULE_DEFAULTS_SAVE_FAILED (HTTP 400) dengan detail.
| Kode | Arti |
|---|---|
| INVALID_JSON | Body bukan JSON yang valid. |
| PAYLOAD_TOO_LARGE | Panjang byte UTF-8 melebihi maxPayloadBytes (default 512 KiB). |
| TYPE_ERROR | Tipe JSON salah atau string apiVersion tidak didukung. |
| UNKNOWN_FIELD | Mode ketat: properti tidak diizinkan pada root atau objek staff. |
| INVALID_TIME_ZONE | timeZone hilang atau bukan nama IANA yang valid. |
| INVALID_DATE_RANGE | Tanggal bukan YYYY-MM-DD, rentang tidak valid, atau enumerasi kosong. |
| SCHEDULE_SPAN_TOO_LONG | Terlalu banyak hari antara mulai dan akhir (lihat maxScheduleDays). |
| INVALID_TIME_RANGE | Rentang waktu hilang atau menghasilkan nol slot. |
| INVALID_GRANULARITY | slotGranularityMinutes bukan 60/15 atau tidak diizinkan paket. |
| INVALID_REQUIREMENTS | requirementsByCell bukan objek atau hitungan bukan bilangan bulat 0–15. |
| UNKNOWN_CELL_KEY | Kunci tidak dalam grid jadwal yang dihitung. |
| INVALID_STAFF | staff kosong, terlalu besar, baris buruk, atau sanitasi gagal. |
| DUPLICATE_STAFF_ID | Nilai staffId duplikat. |
| INVALID_AVAILABLE_CELL | Entri kosong atau tidak dikenal di availableCells. |
| SHORTFALL_CELLS | Ketersediaan staf tidak cukup vs kebutuhan. |
| DYNAMODB_ERROR | Error sementara atau persistensi setelah validasi (tergantung handler). |
| SCHEDULE_DEFAULTS_SAVE_FAILED | PATCH /v1/schedule-defaults: validasi atau aturan bisnis gagal (lihat error.details). |
| LABOR_COMPLIANCE_REQUIRED | PATCH /v1/staff/{staffId}: laborConstraintMask dikirim saat laborLawCompliance false. |
{
"apiVersion": "2026-04-01",
"timeZone": "Asia/Tokyo",
"scheduleStartDate": "2026-04-07",
"scheduleEndDate": "2026-04-13",
"timeRangeStart": "08:00",
"timeRangeEnd": "20:00",
"slotGranularityMinutes": 60,
"requirementsByCell": {
"2026-04-07__slot-0": 2
},
"staff": [
{
"staffId": "550e8400-e29b-41d4-a716-446655440000",
"displayName": "Example",
"availableCells": ["2026-04-07__slot-0"]
}
]
}Bacaan lanjutan. Paket & fitur berbayar: docs/architecture/NURSE_SCHEDULING_SERVICE_SPECIFICATION.md. Isi permintaan POST /v1/schedule: docs/data-and-api/PUBLIC_API_SCHEDULE_REQUEST_BODY.md §1–§11. Isi permintaan PATCH default penyewa: berkas yang sama §12. Kode: app/lib/public-schedule-api/, app/features/schedule-settings/schedule-defaults-actions.ts, app/lib/public-api-write/weekly-shift-wish-tenant.ts. Penerapan: docs/aws/CDK_DEPLOY.md.