Pendahuluan

Partner API Performance Hub memungkinkan platform mitra eksternal terintegrasi dengan mulus dengan modul inti Performance Hub. API ini mendukung computer vision, analitik, pencatatan akses anggota, dan wawasan fasilitas.

Format Permintaan

API menerima isi permintaan yang dienkode JSON dan mengembalikan respons yang dienkode JSON.

Pembatasan Laju

Untuk memastikan penggunaan yang adil dan stabilitas sistem, akun Partner API dimulai dengan batas default:

  • 5 permintaan per detik per endpoint
  • Disarankan: maksimum 1000 item per permintaan batch untuk kinerja optimal
  • Maksimum 10MB untuk ukuran payload

Batas laju dapat disesuaikan dan dikonfigurasi kasus per kasus oleh manajer akun mitra Performance Hub Anda. Jika integrasi Anda membutuhkan throughput yang lebih tinggi untuk peluncuran, migrasi, pengisian ulang (backfill) pelaporan, atau fasilitas bervolume tinggi, sampaikan hal ini selama orientasi atau sebelum jendela perubahan yang direncanakan.

URL Dasar

https://partner-api.performancehub.co/partner/v1/

Autentikasi

Akses ke Partner API memerlukan autentikasi menggunakan kunci rahasia API. Buat dan kelola kunci Anda melalui Partner Console.

Kunci API berfungsi sebagai kredensial Anda untuk mengakses sumber daya mitra. Setiap kunci memiliki akses terbatas ke data organisasi tertentu dan dapat dinonaktifkan secara instan bila diperlukan.

Tangani kunci API Anda dengan hati-hati—kunci ini memberikan akses penuh ke akun Anda! Jangan pernah mengekspos kunci ini di repositori publik, aplikasi sisi klien, atau di tempat mana pun yang dapat membuatnya disalahgunakan.

Autentikasikan permintaan menggunakan HTTP Basic Auth dengan mengirimkan kunci API Anda sebagai nama pengguna. Biarkan kata sandi kosong.

API hanya menerima koneksi HTTPS yang aman. Permintaan HTTP biasa ditolak, begitu pula permintaan apa pun yang tidak memiliki kredensial autentikasi yang benar.

Contoh Permintaan

curl https://partner-api.performancehub.co/partner/v1/organisations \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:
# The colon prevents curl from asking for a password.

Memverifikasi Kunci Rahasia

curl https://partner-api.performancehub.co/partner/v1/auth/ping \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:
# Returns { "message": "You are successfully authorised as <PartnerName>" }

Daftar Periksa Go-Live

Gunakan daftar periksa ini sebelum mengaktifkan integrasi mitra untuk fasilitas produksi.

Penyiapan Partner Console

  • Profil mitra Anda sudah lengkap.
  • URL logo, situs web, kategori, dan deskripsi Anda sudah akurat.
  • Metode penautan data Anda sudah dikonfigurasi: Direct Link atau Linking Identifier.
  • Penautan fasilitas telah diuji dengan setidaknya satu fasilitas nyata.
  • Jenis kunci yang digunakan sudah tepat:
    • Dryrun untuk pengujian tulis yang tidak merusak.
    • Read-only untuk konsumsi data yang aman.
    • Live hanya saat Anda siap memengaruhi data produksi.

Autentikasi dan pengelolaan kunci

  • Kunci rahasia hanya disimpan di sisi server.
  • Kunci tidak disematkan di aplikasi sisi klien, aplikasi seluler, repositori publik, atau tiket dukungan.
  • Rotasi dan pencabutan kunci telah diuji.
  • Tim Anda mengetahui kunci mana yang digunakan oleh setiap lingkungan.

Validasi data

  • Bidang wajib tersedia untuk setiap endpoint yang Anda panggil.
  • Pengidentifikasi fasilitas sesuai dengan metode penautan yang Anda konfigurasi.
  • ID dari sistem Anda stabil dan tidak berubah di antara sinkronisasi.
  • Impor besar dibagi menjadi batch di bawah batas yang didokumentasikan.
  • Item batch yang gagal dapat diidentifikasi dan dikirim ulang.

Pengujian endpoint

Sebelum peluncuran, uji setiap endpoint yang menjadi tumpuan integrasi Anda:

  • Organisasi dan fasilitas dapat dibaca.
  • Anggota dapat disimpan dan diperbarui.
  • Paket keanggotaan, zona akses, dan jam akses tersinkronisasi dengan benar.
  • Check-in diterima dan dapat dikaitkan kembali ke sistem Anda.
  • Snapshot laporan menggunakan periode pelaporan dan metrik yang diharapkan.
  • Alur Door/Gate Controller telah diuji pada perangkat keras nyata jika berlaku.

Kesiapan Access Time Window

Jika integrasi menyediakan Access Time Windows:

  • Contoh absolut dan mingguan lolos daftar periksa sertifikasi produsen.
  • Epoch berupa bilangan bulat detik Unix tanpa tanda kutip; batas [from, to) yang tepat telah diuji.
  • Default UTC, zona waktu IANA kustom integrasi, dan transisi waktu musim panas yang relevan telah diverifikasi.
  • Satu aliran revisi anggota/sumber yang tahan lama dan monoton mengoordinasikan pembaruan inkremental, rekonsiliasi, dan percobaan ulang.
  • Operator memahami perilaku untuk nilai yang dihilangkan, penggantian lengkap, idempoten, bertentangan, usang, dan [] eksplisit.
  • Setiap scope_key, termasuk default, memiliki pemetaan Performance Hub yang disetujui; kunci yang tidak dikenal telah diuji untuk memastikan akses ditolak.
  • Frekuensi pembaruan yang diharapkan, usia sumber maksimum, perilaku saat sumber usang, dan peringatan untuk integrasi telah dikonfigurasi.
  • Telah dibuktikan bahwa kegagalan pengambilan dari upstream tidak menghasilkan snapshot kosong atau parsial.
  • Konvergensi aliran staging, pembatalan/pencabutan, serta batas awal/akhir pada pintu fisik memenuhi target yang disepakati.
  • Aturan reguler dan izin permanen telah diverifikasi sebagai jalur cadangan, dan jendela tidak dapat melewati penonaktifan pengguna, blockAllAccess, pemeliharaan, atau geofencing.

Kesiapan kontrol akses

Untuk integrasi kontrol akses:

  • Sistem Anda membuat keputusan akses sebelum memanggil Performance Hub.
  • Integrasi menangani device_offline, maintenance_mode_active, dan unlock_confirmation_timeout.
  • Operator memahami bahwa batas waktu berarti pembukaan kunci tidak dikonfirmasi.
  • Log Anda menyimpan event_id dan command_id yang dikembalikan.
  • Anda memiliki proses cadangan manual untuk staf fasilitas.

Penanganan kesalahan dan percobaan ulang

  • Respons 400, 401, 403, 404, 409, dan 422 ditampilkan kepada operator atau tim dukungan, bukan dicoba ulang secara membabi buta.
  • Respons 429, 500, 502, 503, dan 504 menggunakan logika percobaan ulang terbatas dengan backoff.
  • Kegagalan berulang memicu peringatan di sistem Anda.
  • Integrasi tidak pernah membuang rekaman yang gagal secara diam-diam.

Observabilitas

  • Log Anda mencakup endpoint, stempel waktu, pengidentifikasi fasilitas, ID rekaman sumber, hasil permintaan, dan isi respons.
  • Tim dukungan Anda dapat mencari berdasarkan ID anggota, ID fasilitas, ID check-in, atau ID peristiwa buka kunci.
  • Anda memiliki cara untuk memutar ulang atau merekonsiliasi sinkronisasi yang gagal.

Peluncuran produksi

  • Performance Hub telah mengonfirmasi akses produksi Anda.
  • Setidaknya satu fasilitas produksi telah mengaktifkan integrasi Anda.
  • Kunci produksi Anda aktif.
  • Kontak operasional dan teknis Anda sudah diperbarui.
  • Proses dukungan Anda telah didokumentasikan untuk pelanggan.

Setelah pemeriksaan ini selesai, integrasi yang telah Anda konfigurasi akan muncul di direktori mitra Performance Hub di dalam platform inti Performance Hub.

Praktik Terbaik

Gunakan pola-pola ini agar integrasi mitra tetap dapat diprediksi, dapat dipantau, dan aman bagi fasilitas.

Identifikasi fasilitas secara konsisten

Pilih metode penautan yang dikonfigurasi untuk akun mitra Anda dan gunakan secara konsisten:

  • Direct Link - gunakan facility_id Performance Hub yang dikembalikan oleh endpoint facilities.
  • Linking Identifier - gunakan pengidentifikasi lokasi Anda sendiri, seperti ID cabang, kode lokasi, atau nomor toko.

Jangan mengirimkan kedua pengidentifikasi dalam permintaan yang sama. Performance Hub memproses permintaan menggunakan metode penautan yang dikonfigurasi untuk akun mitra Anda.

Lihat Metode Penautan Mitra untuk panduan penyiapan.

Lakukan penulisan batch dengan hati-hati

Partner API menerima isi permintaan JSON dan dirancang untuk alur kerja sinkronisasi berbasis batch jika didokumentasikan. Jaga agar batch tetap terbatas dan dapat dicoba ulang.

Panduan default:

  • Gunakan hingga 1000 item per permintaan batch untuk kinerja optimal.
  • Jaga payload tetap di bawah 10MB.
  • Tetap dalam batas 5 permintaan per detik per endpoint.

Batas laju dapat disesuaikan dan dikonfigurasi kasus per kasus oleh manajer akun mitra Performance Hub Anda. Jika Anda memperkirakan impor bervolume tinggi, lalu lintas peluncuran, atau pengisian ulang (backfill) pelaporan, sepakati throughput yang diperlukan sebelum jendela perubahan.

Jika Anda perlu menyinkronkan kumpulan data yang besar, bagi menjadi potongan-potongan yang deterministik dan catat ID setiap potongan di sisi Anda. Ini memudahkan penelusuran percobaan ulang yang gagal.

Coba ulang dengan aman

Gunakan exponential backoff untuk kegagalan sementara seperti 429, 500, 502, 503, dan 504.

Hindari loop percobaan ulang yang rapat. Titik awal yang baik adalah:

  1. Coba ulang setelah 1 detik.
  2. Coba ulang setelah 2 detik.
  3. Coba ulang setelah 4 detik.
  4. Hentikan dan kirim peringatan jika operasi masih gagal.

Untuk kegagalan validasi seperti 400 atau 422, perbaiki permintaan sebelum mencoba ulang.

Gunakan idempotensi jika didukung

Endpoint unlock Door/Gate Controller mendukung idempotency_key opsional. Menggunakan kembali kunci yang sama untuk mitra, fasilitas, dan pintu yang sama akan mengembalikan hasil yang sudah ada jika tersedia.

Gunakan kunci yang stabil untuk tindakan yang dilakukan, misalnya ID check-in atau ID peristiwa akses dari sistem Anda.

Jangan berasumsi bahwa setiap endpoint tulis mendukung idempotensi kecuali hal itu didokumentasikan untuk endpoint tersebut.

Jaga data sumber tetap bersih

Kirimkan nilai yang stabil dan dinormalisasi jika memungkinkan:

  • Gunakan ID anggota, paket, fasilitas, dan check-in yang konsisten dari sistem sumber Anda.
  • Gunakan stempel waktu ISO 8601 untuk tanggal dan waktu.
  • Kirimkan nomor telepon dalam format internasional jika tersedia.
  • Kirimkan mata uang menggunakan bidang yang didokumentasikan untuk setiap endpoint.
  • Hindari membebani bidang teks bebas dengan data yang seharusnya berada di bidang terstruktur.

Rancang untuk sinkronisasi inkremental dan penuh

Sebagian besar integrasi mitra membutuhkan keduanya:

  • Sinkronisasi inkremental untuk perubahan sehari-hari.
  • Sinkronisasi rekonsiliasi penuh untuk memperbaiki peristiwa yang terlewat, impor historis, atau penyimpangan data.

Integrasi Anda harus dapat mengirim ulang status terkini untuk anggota, paket keanggotaan, atau snapshot laporan tanpa bergantung pada keberhasilan permintaan sebelumnya.

Publikasikan Access Time Windows dengan aman

Perlakukan nilai access_time_windows setiap anggota sebagai snapshot lengkap dengan revisi yang independen:

  • Koordinasikan satu aliran access_time_windows_revision yang terus meningkat secara monoton di seluruh worker inkremental dan rekonsiliasi.
  • Coba ulang pengiriman yang tidak pasti atau sementara gagal dengan revisi dan payload ternormalisasi yang sama.
  • Hilangkan access_time_windows jika Anda tidak memperbaruinya.
  • Kirim [] hanya setelah pengambilan dari sumber otoritatif yang berhasil membuktikan bahwa tidak ada jendela yang tersisa. Jangan pernah mengubah batas waktu upstream, hasil parsial, atau kegagalan parsing menjadi pencabutan.
  • Jaga agar external_id dan scope_key tetap stabil, dan sertifikasi setiap pemetaan cakupan sebelum produksi.
  • Pantau usia data sumber terhadap kebijakan kesegaran yang disepakati untuk integrasi tersebut.

Lihat panduan produsen Access Time Windows yang otoritatif untuk snapshot lengkap, zona waktu, DST, pembatalan, dan vektor uji.

Perlakukan kontrol akses sebagai hal yang kritis bagi keselamatan

Untuk pembukaan kunci Door/Gate Controller:

  • Sistem Anda harus memutuskan apakah orang tersebut diizinkan masuk sebelum memanggil Performance Hub.
  • Performance Hub mengembalikan 200 hanya setelah pengontrol di lokasi mengonfirmasi bahwa relai secara fisik telah membuka kunci.
  • Sebagian besar konfirmasi selesai dalam 3-5 detik.
  • Batas waktu adalah buka kunci yang gagal secara eksplisit, bukan keberhasilan di latar belakang.
  • Coba ulang hanya sesuai dengan aturan akses dan keselamatan Anda sendiri.

Selalu catat event_id dan command_id yang dikembalikan oleh endpoint unlock.

Pantau integrasi Anda

Gunakan log permintaan Partner Console selama pengembangan dan peluncuran. Di produksi, kelola juga log Anda sendiri yang berisi:

  • Stempel waktu permintaan.
  • Endpoint.
  • ID rekaman sumber.
  • Pengidentifikasi fasilitas.
  • Kode status HTTP.
  • Isi respons atau pesan kesalahan Performance Hub.

Bidang-bidang ini membuat dukungan dan rekonsiliasi jauh lebih cepat saat pelanggan menanyakan apa yang terjadi.

Organisasi

Mewakili entitas bisnis tingkat teratas yang mengoperasikan satu atau beberapa fasilitas yang terintegrasi dengan platform Performance Hub.

Endpoint

GET /partner/v1/organisations - List all organisations

Objek Organisasi

Atribut

  • org_id string wajib

    Pengidentifikasi unik untuk organisasi.

  • name string wajib

    Nama organisasi.

Objek Organisasi

{
  "org_id": "00000000-0000-0000-0000-000000000050",
  "name": "Harbourside Group"
}

Menampilkan daftar semua organisasi

Mengembalikan daftar organisasi yang dapat diakses oleh akun mitra Anda.

Hasil

Mengembalikan objek JSON dengan properti data yang berisi array objek Organisasi.

Permintaan

curl https://partner-api.performancehub.co/partner/v1/organisations \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Respons

{
  "data": [
    {
      "org_id": "00000000-0000-0000-0000-000000000050",
      "name": "Harbourside Group"
    },
    {
      "org_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
      "name": "Wellness Studios Network"
    }
  ]
}

Fasilitas

Mewakili lokasi fisik, seperti kantor, toko, tempat acara, kampus, klinik, atau pusat kebugaran, tempat anggota dapat mengakses layanan.

Endpoint

GET /partner/v1/facilities - List all facilities

Objek Fasilitas

Atribut

  • facility_id string wajib

    Pengidentifikasi unik untuk fasilitas.

  • org_id string wajib

    Pengidentifikasi unik untuk organisasi induk.

  • name string wajib

    Nama fasilitas.

  • brand string opsional

    Nama merek yang digunakan oleh fasilitas.

  • website_url string opsional

    URL situs web fasilitas.

  • place_data object opsional

    Data lokasi dari Google Places API yang berisi negara, alamat berformat, Google Place ID, provinsi, dan kota.

  • social_links object opsional

    Tautan media sosial untuk fasilitas.

  • timezone string opsional

    Pengidentifikasi zona waktu IANA (misalnya, "Australia/Sydney", "America/New_York").

Objek Fasilitas

{
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "org_id": "00000000-0000-0000-0000-000000000050",
  "name": "Harbourside Central",
  "brand": "Harbourside",
  "website_url": "https://example.com/central",
  "social_links": {
    "instagram": {
      "handle": "@harbourside.central"
    },
    "facebook": {
      "handle": "HarboursideCentral"
    }
  },
  "place_data": {
    "country": {
      "iso_code": "AU",
      "full_name": "Australia"
    },
    "formatted_address": "123 Main Street, Suite 100, Sydney NSW 2000, Australia",
    "google_place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "province": {
      "abbreviation": "NSW",
      "full_name": "New South Wales"
    },
    "city": {
      "short_name": "Sydney",
      "full_name": "Sydney"
    }
  },
  "timezone": "Australia/Sydney"
}

Menampilkan daftar semua fasilitas

Mengembalikan daftar fasilitas yang dapat diakses oleh akun mitra Anda.

Hasil

Mengembalikan objek JSON dengan properti data yang berisi array objek Fasilitas.

Permintaan

curl https://partner-api.performancehub.co/partner/v1/facilities \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Respons

{
  "data": [
    {
      "facility_id": "550e8400-e29b-41d4-a716-446655440000",
      "org_id": "00000000-0000-0000-0000-000000000050",
      "name": "Harbourside Central",
      "brand": "Harbourside",
      "website_url": "https://example.com/central",
      "place_data": {
        "country": {
          "iso_code": "AU",
          "full_name": "Australia"
        },
        "formatted_address": "123 Main Street, Sydney NSW 2000, Australia",
        "google_place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
        "province": {
          "abbreviation": "NSW",
          "full_name": "New South Wales"
        },
        "city": {
          "short_name": "Sydney",
          "full_name": "Sydney"
        }
      },
      "timezone": "Australia/Sydney"
    }
  ]
}

Paket Keanggotaan

Mendefinisikan penawaran yang dapat dibeli dari organisasi atau fasilitas, termasuk layanan, hak, jadwal, dan harga.

Endpoint

POST /partner/v1/membership-plans - Save a membership plan

Objek Membership Plan

Atribut

  • membership_plan_id string wajib

    Pengidentifikasi unik untuk paket keanggotaan.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi unik fasilitas dari Performance Hub.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Nilai pengidentifikasi unik untuk setiap lokasi yang digunakan mitra (misalnya, "Branch ID", "Location Code", "Store Number"). Pelajari lebih lanjut

  • name string wajib

    Nama paket yang mudah dibaca (misalnya, "Office tenant – business hours", "Student – term access", "Hotel guest", "10 Class Pack").

  • billing_cycle string opsional

    Frekuensi penagihan. Salah satu dari weekly, fortnightly, monthly, annually, atau one_time.

  • price integer opsional

    Biaya dasar dalam satuan mata uang terkecil (sen untuk USD/AUD).

  • currency string opsional

    Kode mata uang ISO 4217 (misalnya, "AUD", "USD").

  • description string opsional

    Deskripsi pemasaran atau internal opsional.

  • active_members integer opsional

    Jumlah anggota aktif yang menggunakan paket keanggotaan ini

  • is_recurring boolean opsional

    Apakah paket diperpanjang secara otomatis.

  • is_trial boolean opsional

    Apakah ini merupakan penawaran uji coba.

  • visible_to_public boolean opsional

    Apakah paket tersedia untuk pembelian mandiri.

  • duration_days integer opsional

    Jumlah hari masa berlaku paket keanggotaan.

  • access_zones array opsional

    Array zona akses yang termasuk dalam paket keanggotaan. Setiap zona dapat menentukan jam aksesnya sendiri. Lihat Zona Akses untuk detailnya.

  • class_limit integer opsional

    Jumlah maksimum kelas yang diizinkan (null untuk tanpa batas).

Objek Membership Plan

Contoh ini menggunakan facility_id. Untuk integrasi linking-identifier, kirimkan "linking_identifier": "branch_downtown" sebagai gantinya.

{
  "membership_plan_id": "plan_99999",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Office tenant – business hours",
  "description": "Weekday access to the level 3 tenancy and the end-of-trip facilities",
  "billing_cycle": "monthly",
  "price": 8900,
  "currency": "AUD",
  "duration_days": 30,
  "is_recurring": true,
  "is_trial": false,
  "visible_to_public": false,
  "active_members": 245,
  "access_zones": [
    {
      "name": "Level 3 Tenancy",
      "description": "Lift lobby, offices and meeting rooms on level 3",
      "access_hours": {
        "mon": [["07:00", "19:00"]],
        "tue": [["07:00", "19:00"]],
        "wed": [["07:00", "19:00"]],
        "thu": [["07:00", "19:00"]],
        "fri": [["07:00", "19:00"]]
      }
    },
    {
      "name": "End-of-trip Facilities",
      "description": "Bike storage, lockers and showers",
      "access_hours": {
        "mon": [["06:00", "20:00"]],
        "tue": [["06:00", "20:00"]],
        "wed": [["06:00", "20:00"]],
        "thu": [["06:00", "20:00"]],
        "fri": [["06:00", "20:00"]]
      }
    }
  ],
  "class_limit": null
}

Zona Akses

Zona akses menentukan area tertentu di dalam fasilitas tempat paket keanggotaan memberikan akses. Setiap zona dapat memiliki jam aksesnya sendiri, sehingga memungkinkan batasan waktu yang berbeda per area.

Struktur

Setiap zona akses mencakup:

  • name string wajib

    Nama zona (misalnya, "Level 3 Tenancy", "Library", "Guest Floors", "Main Gym Floor").

  • description string opsional

    Deskripsi tentang apa saja yang termasuk dalam zona tersebut.

  • access_hours object opsional

    Jam akses khusus untuk zona ini. Lihat Jam Akses untuk format rentang waktu.

Contoh

Gedung perkantoran dengan pusat kebugaran untuk para penyewanya: akses ke area sewa selama jam kerja, dan ke pusat kebugaran dari pagi buta hingga larut malam.

{
  "access_zones": [
    {
      "name": "Level 3 Tenancy",
      "description": "Lift lobby, offices and meeting rooms on level 3",
      "access_hours": {
        "mon": [["07:00", "19:00"]],
        "tue": [["07:00", "19:00"]],
        "wed": [["07:00", "19:00"]],
        "thu": [["07:00", "19:00"]],
        "fri": [["07:00", "19:00"]]
      }
    },
    {
      "name": "Tenant Gym",
      "description": "Ground-floor gym and change rooms for building tenants",
      "access_hours": {
        "mon": [["05:00", "22:00"]],
        "tue": [["05:00", "22:00"]],
        "wed": [["05:00", "22:00"]],
        "thu": [["05:00", "22:00"]],
        "fri": [["05:00", "22:00"]],
        "sat": [["07:00", "18:00"]],
        "sun": [["07:00", "18:00"]]
      }
    }
  ]
}

Jam Akses

Jam akses menentukan kapan anggota dapat mengakses zona tertentu pada setiap hari dalam seminggu. Jam akses ditentukan per zona akses, sehingga memungkinkan batasan waktu yang berbeda untuk area fasilitas yang berbeda.

Struktur

{
  "mon": [["start_time", "end_time"]],
  "tue": [["start_time", "end_time"]],
  "wed": [["start_time", "end_time"]],
  "thu": [["start_time", "end_time"]],
  "fri": [["start_time", "end_time"]],
  "sat": [["start_time", "end_time"]],
  "sun": [["start_time", "end_time"]]
}

Setiap hari berupa array rentang waktu dalam format HH:MM (format 24 jam). Array kosong [] berarti tidak ada akses pada hari itu. Hari yang dihilangkan diperlakukan sama seperti array kosong.

Contoh Kasus Penggunaan

Penyewa kantor – jam kerja: akses selama jam kerja pada hari kerja saja.

{
  "access_hours": {
    "mon": [["07:00", "19:00"]],
    "tue": [["07:00", "19:00"]],
    "wed": [["07:00", "19:00"]],
    "thu": [["07:00", "19:00"]],
    "fri": [["07:00", "19:00"]]
  }
}

Mahasiswa – akses semester: perpustakaan kampus yang buka pada hari kerja, dengan jeda di tengah hari, dan pada Sabtu pagi.

{
  "access_hours": {
    "mon": [["08:00", "12:30"], ["13:30", "21:00"]],
    "tue": [["08:00", "12:30"], ["13:30", "21:00"]],
    "wed": [["08:00", "12:30"], ["13:30", "21:00"]],
    "thu": [["08:00", "12:30"], ["13:30", "21:00"]],
    "fri": [["08:00", "12:30"], ["13:30", "17:00"]],
    "sat": [["09:00", "13:00"]]
  }
}

Pusat kebugaran – pagi hari: akses hanya pada pagi hari di hari kerja.

{
  "access_hours": {
    "mon": [["04:00", "12:00"]],
    "tue": [["04:00", "12:00"]],
    "wed": [["04:00", "12:00"]],
    "thu": [["04:00", "12:00"]],
    "fri": [["04:00", "12:00"]]
  }
}

Tamu hotel – 24/7: akses tanpa henti, kasus penggunaan yang paling umum.

{
  "access_hours": {
    "mon": [["00:00", "23:59"]],
    "tue": [["00:00", "23:59"]],
    "wed": [["00:00", "23:59"]],
    "thu": [["00:00", "23:59"]],
    "fri": [["00:00", "23:59"]],
    "sat": [["00:00", "23:59"]],
    "sun": [["00:00", "23:59"]]
  }
}

Contoh Per Zona

Paket tamu hotel dengan akses sepanjang waktu ke lantai tamu dan jam yang lebih singkat untuk kolam renang:

{
  "access_zones": [
    {
      "name": "Guest Floors",
      "description": "Lifts and corridors on the guest room levels",
      "access_hours": {
        "mon": [["00:00", "23:59"]],
        "tue": [["00:00", "23:59"]],
        "wed": [["00:00", "23:59"]],
        "thu": [["00:00", "23:59"]],
        "fri": [["00:00", "23:59"]],
        "sat": [["00:00", "23:59"]],
        "sun": [["00:00", "23:59"]]
      }
    },
    {
      "name": "Swimming Pool",
      "description": "Access to the swimming pool and change rooms",
      "access_hours": {
        "mon": [["06:00", "20:00"]],
        "tue": [["06:00", "20:00"]],
        "wed": [["06:00", "20:00"]],
        "thu": [["06:00", "20:00"]],
        "fri": [["06:00", "20:00"]],
        "sat": [["08:00", "18:00"]],
        "sun": [["08:00", "18:00"]]
      }
    }
  ]
}

Menyimpan paket keanggotaan

Membuat atau memperbarui catatan paket keanggotaan. API menentukan apakah akan membuat atau memperbarui berdasarkan membership_plan_id.

Parameter

  • membership_plans array wajib

    Array objek Membership Plan yang akan disimpan. Maksimum yang disarankan: 1000 item per permintaan untuk kinerja optimal. API secara otomatis mengelompokkan item ke dalam batch untuk diproses. Setiap item harus menyertakan facility_id (wajib jika tidak menggunakan linking_identifier) atau linking_identifier (wajib jika tidak menggunakan facility_id).

Hasil

Mengembalikan pesan sederhana yang mengonfirmasi operasi sinkronisasi.

Permintaan

Contoh ini menggunakan facility_id. Untuk integrasi linking-identifier, kirimkan "linking_identifier": "branch_downtown" sebagai gantinya.

curl -X POST https://partner-api.performancehub.co/partner/v1/membership-plans \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "membership_plans": [
      {
        "membership_plan_id": "plan_99999",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Student – term access",
        "description": "Library and student hub access for one teaching term",
        "billing_cycle": "one_time",
        "price": 4500,
        "currency": "AUD",
        "duration_days": 84,
        "is_recurring": false,
        "is_trial": false,
        "visible_to_public": true,
        "active_members": 245,
        "access_zones": [
          {
            "name": "Library",
            "description": "Reading rooms, study spaces and bookable rooms",
            "access_hours": {
              "mon": [["08:00", "21:00"]],
              "tue": [["08:00", "21:00"]],
              "wed": [["08:00", "21:00"]],
              "thu": [["08:00", "21:00"]],
              "fri": [["08:00", "17:00"]],
              "sat": [["09:00", "13:00"]]
            }
          },
          {
            "name": "Student Hub",
            "description": "Common room, kitchen and lockers",
            "access_hours": {
              "mon": [["07:00", "22:00"]],
              "tue": [["07:00", "22:00"]],
              "wed": [["07:00", "22:00"]],
              "thu": [["07:00", "22:00"]],
              "fri": [["07:00", "22:00"]]
            }
          }
        ],
        "class_limit": null
      }
    ]
  }'

Respons

Mengembalikan pesan keberhasilan beserta metadata tentang operasi sinkronisasi.

{
  "message": "Membership plan sync successful.",
  "metadata": {
    "success": 98,
    "skipped": 2,
    "skipped_items": [
      {
        "membership_plan_id": "plan_456",
        "facility_id": null,
        "reason": "Missing facility_id"
      }
    ]
  }
}

Bidang metadata:

  • success - Jumlah paket keanggotaan yang berhasil diproses
  • skipped - Jumlah paket yang dilewati (jika ada)
  • skipped_items - Array paket yang dilewati beserta alasannya (jika ada)
  • dry-run - Penanda boolean jika menggunakan jenis kunci dryrun (jika berlaku)

Anggota

Mewakili pelanggan perorangan dari suatu fasilitas. Dapat berupa lead, prospek, pelanggan berulang, anggota yang kedaluwarsa, atau pengguna yang diblokir.

Upsert anggota juga dapat membawa snapshot access_time_windows yang lengkap dan berrevisi, berisi akses absolut dan mingguan berulang. Lihat Access Time Windows sebelum menghasilkan bidang-bidang ini. Bidang ini merupakan izin tambahan dan tidak menggantikan aturan reguler atau izin permanen fasilitas.

Endpoint

POST /partner/v1/members - Save a member

Objek Member

Atribut

  • member_id string wajib

    Pengidentifikasi unik untuk anggota.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi unik fasilitas dari Performance Hub.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Nilai pengidentifikasi unik untuk setiap lokasi yang digunakan mitra (misalnya, "Branch ID", "Location Code", "Store Number"). Pelajari lebih lanjut

  • first_name string wajib

    Nama depan anggota.

  • last_name string wajib

    Nama belakang anggota.

  • email string opsional

    Alamat email.

  • mobile_phone string opsional

    Nomor ponsel dalam format E.123 (misalnya, "+1 415 555 2671").

  • address object opsional

    Objek alamat fisik dengan properti berikut:

    • address_line_1 (string) - Alamat jalan utama
    • address_line_2 (string, opsional) - Baris alamat kedua
    • city (string) - Nama kota
    • state (string) - Kode negara bagian/provinsi
    • postal_code (string) - Kode pos/ZIP
    • country (string) - Kode negara ISO 3166-1 alpha-2 (misalnya, "AU", "US")
    • country_name (string, opsional) - Nama lengkap negara
  • date_of_birth string opsional

    Tanggal lahir dalam format YYYY-MM-DD.

  • gender string opsional

    Salah satu dari male, female, non_binary, prefer_not_to_say, atau unknown.

  • type string opsional

    Jenis anggota (misalnya staff, member, prospect).

  • tags array opsional

    String atau teks bantu singkat untuk mengategorikan dan mengidentifikasi anggota tertentu (misalnya ["vip", "personal-training", "student"]).

  • membership_status string opsional

    Status keanggotaan saat ini (misalnya, active, expired, on_hold).

  • membership_plans array opsional

    Array paket keanggotaan yang terkait dengan anggota.

  • profile_picture string opsional

    Foto profil yang dienkode Base64 (opsional).

  • created string opsional

    Stempel waktu ISO 8601 saat anggota dibuat.

  • updated string opsional

    Stempel waktu ISO 8601 saat anggota terakhir diperbarui.

  • access_time_windows array opsional

    Snapshot lengkap milik sumber berisi Access Time Windows absolut dan/atau mingguan berulang. Hilangkan bidang ini agar snapshot tidak berubah; kirim array kosong dengan revisi yang lebih baru untuk mencabutnya. Lihat Access Time Windows untuk bentuk, validasi, pemetaan cakupan, dan semantik penggantiannya.

  • access_time_windows_revision integer wajib bersama access_time_windows

    Bilangan bulat non-negatif yang aman untuk JSON dan terus meningkat secara monoton untuk aliran anggota/sumber ini. Wajib setiap kali access_time_windows ada.

Objek Member

{
  "member_id": "member_11111",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "first_name": "John",
  "last_name": "Smith",
  "email": "john.smith@example.com",
  "mobile_phone": "+61 412 345 678",
  "date_of_birth": "1985-06-15",
  "gender": "male",
  "type": "member",
  "tags": ["vip", "personal-training"],
  "profile_picture": "/9j/4AAQSkZJRgABAQAAAQ...",
  "membership_status": "current",
  "created": "2024-01-15T10:30:00Z",
  "updated": "2024-01-20T14:45:00Z",
  "access_time_windows_revision": 1842,
  "access_time_windows": [
    {
      "external_id": "access-4b1782",
      "kind": "absolute",
      "from": 1792053000,
      "to": 1792058400,
      "timezone": "Australia/Perth",
      "scope_key": "after_hours_entry",
      "label": "Temporary site access"
    }
  ],
  "address": {
    "address_line_1": "456 Bourke Street",
    "address_line_2": "Apt 12",
    "city": "Melbourne",
    "state": "VIC",
    "postal_code": "3000",
    "country": "AU",
    "country_name": "Australia"
  },
  "membership_plans": [
    {
      "membership_plan_id": "plan_99999",
      "name": "Unlimited Monthly",
      "start_date": "2024-01-01T00:00:00Z",
      "status": "current",
      "is_current": true,
      "end_date": null
    }
  ]
}

Jendela Waktu Akses

Access Time Windows memungkinkan Partner Member membawa akses sementara atau berulang yang disediakan oleh sistem eksternal. Halaman ini adalah panduan produsen otoritatif untuk access_time_windows dan access_time_windows_revision.

Access Time Windows adalah izin tambahan yang hanya bersifat mengizinkan. Jendela yang aktif dapat mengizinkan akses, tetapi jendela yang tidak aktif, kedaluwarsa, usang, atau tidak dipetakan tidak menolak akses yang sudah diizinkan oleh aturan reguler atau izin permanen. Penonaktifan pengguna, pemblokiran pintu secara eksplisit, mode pemeliharaan, geofencing, batas laju, dan ketersediaan pengontrol tetap berlaku.

Implementasi untuk sistem upstream tertentu merupakan adaptor terpisah. Adaptor tersebut harus menerjemahkan data sumbernya ke dalam kontrak netral vendor ini tanpa mengubah makna bidangnya.

Bidang snapshot anggota

  • access_time_windows array opsional

    Snapshot Access Time Window lengkap untuk anggota dan sumber mitra ini. Satu snapshot dapat menggabungkan jendela absolute dan weekly. Hilangkan bidang ini agar snapshot yang tersimpan tidak berubah; kirim [] untuk mencabut setiap jendela yang dimiliki sumber ini.

  • access_time_windows_revision integer wajib bersama access_time_windows

    Bilangan bulat non-negatif yang aman untuk JSON dan terus meningkat secara monoton untuk aliran revisi anggota/sumber ini. Bidang ini wajib setiap kali access_time_windows ada dan tidak boleh melebihi 9007199254740991.

Setiap snapshot menerima paling banyak 50 jendela. external_id, scope_key, dan label menerima paling banyak 120 karakter. Jendela absolut dapat mencakup paling lama 90 hari. Satu hari mingguan menerima paling banyak delapan blok yang tidak tumpang tindih. Data yang tidak valid ditolak, bukan dipotong atau ditebak.

Bentuk jendela

Jendela absolut mengidentifikasi satu interval yang tepat:

Permintaan gabungan lengkap

Permintaan ini mengganti snapshot milik sumber sebelumnya untuk anggota tersebut dengan satu jendela absolut dan satu jendela mingguan:

Aturan waktu dan batas

from, to, active_from, dan active_until adalah bilangan bulat JSON berupa detik Unix yang mengidentifikasi instan UTC:

  • Kirim bilangan bulat JSON tanpa tanda kutip. String numerik, bilangan float, string RFC 3339, dan milidetik Unix ditolak.
  • Setiap interval bersifat setengah terbuka: [from, to). Akses dapat dimulai tepat pada from; akses tidak lagi aktif tepat pada to.
  • from harus lebih kecil dari to. Jika kedua batas mingguan ada, active_from harus lebih kecil dari active_until.
  • Jangan menurunkan epoch dari tanggal/waktu lokal tanpa zona waktu. Selesaikan terlebih dahulu waktu sumber menjadi instan UTC, lalu bagi milidetik Unix dengan 1000 dan pastikan hasilnya berupa bilangan bulat.

Zona waktu dan waktu musim panas

timezone harus berupa zona waktu IANA yang valid seperti UTC, Australia/Perth, atau America/New_York. Nilai default-nya adalah UTC jika dihilangkan.

  • Jendela absolut: from dan to sudah mengidentifikasi instan UTC yang tepat. timezone hanya merupakan metadata tampilan dan audit; mengubahnya tidak pernah menggeser kedua instan tersebut.
  • Jendela mingguan: timezone menentukan jam dinding lokal dan aturan waktu musim panas yang digunakan untuk mengevaluasi access_hours. Jangan mengonversi blok mingguan ke UTC terlebih dahulu.
  • Saat perubahan maju (spring-forward), waktu lokal yang dilewati oleh zona waktu tidak pernah terjadi.
  • Saat perubahan mundur (fall-back), kedua instan nyata yang memiliki waktu lokal berulang tersebut cocok dengan blok mingguan.
  • active_from dan active_until tetap merupakan instan UTC meskipun jendela mingguan menggunakan zona waktu selain UTC.

access_hours menggunakan huruf kecil sun hingga sat. Setiap nilai berupa array pasangan [start, end] dengan format 24 jam HH:mm yang diawali nol. Blok tidak boleh kosong, harus berurutan, dan tidak boleh tumpang tindih. end bersifat eksklusif. Blok tidak boleh melewati tengah malam; pisahkan interval sumber semalam menjadi blok larut pada hari pertama dan blok pagi pada hari berikutnya.

ID stabil dan pemetaan cakupan

external_id harus stabil selama masa berlaku jendela logis dan unik di dalam snapshot anggota. Pertahankan agar tetap stabil saat waktu atau label berubah sehingga operator dan catatan audit dapat menghubungkan revisi. Jangan menggunakannya kembali untuk jendela yang tidak terkait.

scope_key adalah target akses logis Anda yang stabil. Nilai default-nya adalah default. Administrator fasilitas memetakan setiap kunci yang diizinkan ke target di seluruh fasilitas, pintu, atau Ruang Lingkup Akses di Performance Hub:

Snapshot lengkap dan revisi

Perlakukan kedua bidang ini sebagai partisi berversi terpisah di dalam upsert Member:

Input Hasil
access_time_windows dihilangkan Snapshot yang ada tetap tidak berubah; revisi tidak diperlukan
Ada dengan revisi yang lebih baru Seluruh snapshot tersimpan untuk anggota/sumber ini diganti
Revisi sama dan payload ternormalisasi sama Pemutaran ulang idempoten; snapshot tidak berubah
Revisi sama dan payload ternormalisasi berbeda Konflik; alokasikan revisi baru setelah rekonsiliasi
Revisi lebih lama Snapshot usang dilewati; tidak dapat menimpa status yang lebih baru
access_time_windows: [] dengan revisi yang lebih baru Secara eksplisit mencabut semua jendela milik sumber

Snapshot bersifat lengkap, bukan patch. Jika revisi 1842 memiliki jendela A dan B, maka revisi 1843 yang hanya berisi B akan menghapus A.

Kelola satu aliran revisi terkoordinasi per mitra/anggota di seluruh worker webhook, polling, pemutaran ulang, dan rekonsiliasi penuh. Sekuens database yang tahan lama lebih disarankan. Nilai milidetik Unix dapat digunakan sebagai revisi hanya jika setiap penulis berkoordinasi dan menjamin urutan serta keunikan yang ketat; nilai ini adalah nilai revisi, bukan bidang epoch.

Simpan permintaan dan revisi yang persis sama hingga respons API diketahui. Coba ulang snapshot ternormalisasi yang sama dengan revisi yang sama setelah batas waktu atau kesalahan sementara. Jangan mengalokasikan revisi baru hanya karena pengiriman transport tidak pasti.

Pembatalan, kedaluwarsa, dan kegagalan upstream

  • Membatalkan satu jendela: berhasil mengambil status sumber otoritatif, hapus jendela tersebut, dan kirim snapshot lengkap yang tersisa dengan revisi yang lebih baru.
  • Membatalkan semua jendela: kirim access_time_windows: [] dengan revisi yang lebih baru.
  • Membiarkan jendela absolut kedaluwarsa: jendela berhenti mengizinkan pada to; kirim rekonsiliasi berikutnya tanpa entri yang kedaluwarsa agar snapshot tetap bersih.
  • Mengakhiri jendela mingguan: hapus jendela tersebut dalam snapshot yang lebih baru, atau gunakan active_until jika sumber memiliki instan akhir yang diketahui.
  • Pengambilan sumber gagal atau tidak lengkap: jangan kirim [] dan jangan memublikasikan snapshot parsial. Kirim peringatan dan coba ulang pengambilan. Mengubah kegagalan upstream menjadi snapshot kosong merupakan pencabutan akses yang tidak disengaja.
  • Permintaan Partner API gagal validasi: perbaiki data dan kirim revisi yang lebih baru hanya jika snapshot ternormalisasi berubah. Coba ulang kegagalan sementara dengan revisi aslinya.

Kesegaran sumber dikonfigurasi per integrasi berdasarkan frekuensi pengiriman dan rekonsiliasi yang dijanjikan. Sebelum aktivasi, sepakati usia sumber maksimum, apa yang terjadi jika batas tersebut terlampaui, ambang peringatan, dan apakah operator boleh menyetujui untuk hanya mengandalkan batas masing-masing jendela. Jendela sumber yang usang tidak pernah menjadi aturan penolakan; aturan reguler dan izin permanen tetap menjadi jalur cadangan.

Algoritma produsen

Gunakan alur kerja yang netral bahasa ini untuk setiap pembaruan anggota:

Daftar periksa sertifikasi

Selesaikan pemeriksaan ini di fasilitas staging menggunakan pemetaan scope_key final:

  • Jendela absolut diterima dengan zona waktu dihilangkan dan dievaluasi sebagai UTC.
  • Jendela absolut dengan IANA kustom mempertahankan instan from/to yang sama.
  • Jendela mingguan dengan IANA kustom mengikuti waktu jam dinding lokal melewati transisi maju (spring-forward) dan mundur (fall-back).
  • Snapshot gabungan absolut/mingguan mengganti snapshot sebelumnya sepenuhnya.
  • Akses dimulai tepat pada from dan berhenti tepat pada to; akhir blok mingguan juga bersifat eksklusif.
  • Memperbarui waktu di bawah external_id yang sama dengan revisi yang lebih baru akan berlaku.
  • Menghilangkan access_time_windows mengubah bidang Member lainnya tanpa mengubah jendela.
  • Memutar ulang revisi/payload yang sama bersifat idempoten.
  • Revisi sama/payload berbeda mengembalikan konflik dan tidak mengubah snapshot.
  • Revisi lama yang datang tidak berurutan dilaporkan usang dan tidak dapat mengembalikan status ke belakang.
  • [] yang lebih baru mencabut jendela milik sumber; kegagalan pengambilan upstream tidak mengirimkan apa pun.
  • scope_key yang tidak dikenal atau tidak dipetakan tidak memberikan akses apa pun dan memunculkan peringatan yang terlihat oleh operator.
  • Peringatan usia sumber dan kebijakan sumber usang yang dikonfigurasi berfungsi pada ambang yang disepakati.
  • Jalur webhook dan rekonsiliasi penuh menghasilkan snapshot dan urutan revisi yang sama.
  • Pengiriman aliran mencapai Door & Gate Access dalam target yang disepakati.
  • Jendela aktif dapat mengizinkan pintu fisik yang dipetakan, tetapi tidak dapat melewati penonaktifan pengguna, blockAllAccess, pemeliharaan, atau geofencing.
  • Sebelum, di luar, dan setelah jendela, aturan reguler dan izin permanen tetap mengizinkan pengguna yang memenuhi syarat.

Panduan terkait

{
  "external_id": "access-4b1782",
  "kind": "absolute",
  "from": 1792053000,
  "to": 1792058400,
  "timezone": "Australia/Perth",
  "scope_key": "after_hours_entry",
  "label": "Temporary site access"
}

Bidang wajib adalah external_id, kind, from, dan to. timezone, scope_key, dan label bersifat opsional.

Jendela mingguan mengidentifikasi interval waktu jam dinding lokal yang berulang, yang secara opsional dibatasi oleh instan UTC:

{
  "external_id": "weekly-early-access",
  "kind": "weekly",
  "timezone": "America/New_York",
  "access_hours": {
    "sun": [],
    "mon": [["06:00", "08:30"]],
    "tue": [["06:00", "08:30"]],
    "wed": [["06:00", "08:30"]],
    "thu": [["06:00", "08:30"]],
    "fri": [["06:00", "08:30"]],
    "sat": []
  },
  "active_from": 1790812800,
  "active_until": 1796083200,
  "scope_key": "main_entry",
  "label": "Weekday early access"
}

Bidang wajib adalah external_id, kind, dan access_hours. timezone, active_from, active_until, scope_key, dan label bersifat opsional.

curl -X POST https://partner-api.performancehub.co/partner/v1/members \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      {
        "member_id": "member_11111",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        "first_name": "John",
        "last_name": "Smith",
        "access_time_windows_revision": 1842,
        "access_time_windows": [
          {
            "external_id": "access-4b1782",
            "kind": "absolute",
            "from": 1792053000,
            "to": 1792058400,
            "timezone": "Australia/Perth",
            "scope_key": "after_hours_entry",
            "label": "Temporary site access"
          },
          {
            "external_id": "weekly-early-access",
            "kind": "weekly",
            "timezone": "America/New_York",
            "access_hours": {
              "sun": [],
              "mon": [["06:00", "08:30"]],
              "tue": [["06:00", "08:30"]],
              "wed": [["06:00", "08:30"]],
              "thu": [["06:00", "08:30"]],
              "fri": [["06:00", "08:30"]],
              "sat": []
            },
            "active_from": 1790812800,
            "active_until": 1796083200,
            "scope_key": "main_entry",
            "label": "Weekday early access"
          }
        ]
      }
    ]
  }'

Gunakan facility_id atau linking_identifier sesuai dengan metode penautan yang Anda konfigurasi. Jangan kirim keduanya.

Konversi epoch

2026-10-15T08:30:00Z dikonversi menjadi 1792053000:

UTC instant                 Unix milliseconds   Unix seconds sent
2026-10-15T08:30:00Z        1792053000000        1792053000

Konversi yang netral bahasa:

instant = parse_source_timestamp_with_explicit_zone(source_timestamp)
milliseconds = instant.to_unix_milliseconds()
assert milliseconds modulo 1000 equals 0
seconds = milliseconds / 1000
assert seconds is a JSON-safe nonnegative integer

Jika sumber memiliki presisi di bawah satu detik, tetapkan kebijakan pembulatan awal/akhir yang disengaja sebelum pengujian integrasi. Jangan pernah mengirimkan milidetik dan mengandalkan API untuk menebak satuannya.

Partner scope_key           Performance Hub mapping
default                     Facility's configured default target
main_entry                  Access Scope "Main entrances"
after_hours_entry           Doors approved for after-hours entry

Mitra tidak mengirimkan ID fasilitas, pintu, atau Ruang Lingkup Akses Performance Hub di dalam jendela. Untuk scope_key yang tidak dikenal, dinonaktifkan, atau tidak dipetakan, jendela tersebut tidak memberikan akses apa pun; kunci tersebut tidak memperluas akses. Sepakati dan uji pemetaan sebelum peluncuran.

function publish_member(member_key):
    source_result = fetch_authoritative_access_state(member_key)

    if source_result.failed or source_result.incomplete:
        record_failure(member_key)
        schedule_retry(member_key)
        return without sending access_time_windows

    windows = []
    for source_window in source_result.current_windows:
        if source_window.is_absolute:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "absolute",
                from: to_integer_unix_seconds(source_window.start_instant),
                to: to_integer_unix_seconds(source_window.end_instant),
                timezone: source_window.display_timezone or "UTC",
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })
        else:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "weekly",
                timezone: valid_iana_zone(source_window.timezone) or "UTC",
                access_hours: split_validate_and_sort_weekly_blocks(source_window),
                active_from: optional_integer_unix_seconds(source_window.active_start),
                active_until: optional_integer_unix_seconds(source_window.active_end),
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })

    normalized_snapshot = validate_sort_and_deduplicate(windows)
    revision = next_durable_member_revision(member_key)
    request = member_upsert_with(normalized_snapshot, revision)
    persist_for_retry(member_key, request)

    response = post_request(request)
    if response.is_transient_or_unknown:
        retry_exact_request_with_same_revision(request)
    else if response.is_revision_conflict:
        reconcile_with_latest_committed_source_state(member_key)
    else if response.is_stale_skip:
        stop_replaying_this_revision_and_reconcile(member_key)

Vektor uji minimum

[
  {
    "name": "absolute-half-open",
    "window": {
      "external_id": "tv-absolute",
      "kind": "absolute",
      "from": 1792053000,
      "to": 1792058400
    },
    "expect": {
      "1792052999": "inactive",
      "1792053000": "active",
      "1792058399": "active",
      "1792058400": "inactive"
    }
  },
  {
    "name": "weekly-dst",
    "window": {
      "external_id": "tv-weekly-dst",
      "kind": "weekly",
      "timezone": "America/New_York",
      "access_hours": {
        "sun": [["01:00", "03:30"]],
        "mon": [],
        "tue": [],
        "wed": [],
        "thu": [],
        "fri": [],
        "sat": []
      }
    },
    "expect": "Evaluate local wall time: skipped times do not occur; both repeated 01:30 instants qualify."
  }
]

Kirimkan juga vektor negatif untuk milidetik Unix, string numerik, bilangan float, zona IANA yang tidak valid, from >= to, external_id duplikat, blok yang tumpang tindih, blok semalam, lebih dari delapan blok dalam sehari, lebih dari 50 jendela, dan kunci cakupan yang tidak dipetakan.

Menyimpan anggota

Membuat atau memperbarui catatan anggota. API menentukan apakah akan membuat atau memperbarui berdasarkan member_id.

Parameter

  • members array wajib

    Array objek Member yang akan disimpan. Maksimum yang disarankan: 1000 item per permintaan untuk kinerja optimal. API secara otomatis mengelompokkan item ke dalam batch untuk diproses. Setiap item harus menyertakan facility_id (wajib jika tidak menggunakan linking_identifier) atau linking_identifier (wajib jika tidak menggunakan facility_id).

    Jika anggota menyertakan access_time_windows, anggota tersebut juga harus menyertakan access_time_windows_revision. Array ini merupakan snapshot sumber yang lengkap, bukan patch. Hilangkan untuk mempertahankan snapshot yang ada, atau kirim [] dengan revisi yang lebih baru untuk mencabut semua jendela milik sumber. Baca panduan Access Time Windows sebelum mengaktifkan bidang ini.

Hasil

Mengembalikan pesan sederhana yang mengonfirmasi operasi sinkronisasi.

Bidang profil anggota tetap diproses sebagai upsert biasa meskipun snapshot jendela dilaporkan sebagai pemutaran ulang idempoten atau dilewati karena usang. Snapshot yang bertentangan (revisi sama/payload berbeda) tidak dapat dicoba ulang tanpa perubahan; rekonsiliasikan status sumber dan kirim revisi yang lebih baru.

Permintaan

curl -X POST https://partner-api.performancehub.co/partner/v1/members \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      {
        "member_id": "member_11111",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "first_name": "John",
        "last_name": "Smith",
        "email": "john.smith@example.com",
        "mobile_phone": "+61 412 345 678",
        "date_of_birth": "1985-06-15",
        "gender": "male",
        "type": "member",
        "tags": ["vip", "personal-training"],
        "profile_picture": "/9j/4AAQSkZJRgABAQAAAQ...",
        "membership_status": "current",
        "created": "2024-01-15T10:30:00Z",
        "updated": "2024-01-20T14:45:00Z",
        "access_time_windows_revision": 1842,
        "access_time_windows": [
          {
            "external_id": "access-4b1782",
            "kind": "absolute",
            "from": 1792053000,
            "to": 1792058400,
            "timezone": "Australia/Perth",
            "scope_key": "after_hours_entry",
            "label": "Temporary site access"
          }
        ],
        "address": {
          "address_line_1": "456 Bourke Street",
          "address_line_2": "Apt 12",
          "city": "Melbourne",
          "state": "VIC",
          "postal_code": "3000",
          "country": "AU",
          "country_name": "Australia"
        },
        "membership_plans": [
          {
            "membership_plan_id": "plan_99999",
            "name": "Unlimited Monthly",
            "start_date": "2024-01-01T00:00:00Z",
            "status": "current",
            "is_current": true,
            "end_date": null
          }
        ]
      }
    ]
  }'

Respons

Mengembalikan pesan keberhasilan beserta metadata tentang operasi sinkronisasi.

{
  "message": "Member sync successful.",
  "metadata": {
    "success": 245,
    "skipped": 5,
    "skipped_items": [
      {
        "member_id": "member_123",
        "facility_id": null,
        "reason": "Facility integration is disabled in facility-partner-config"
      }
    ]
  }
}

Bidang metadata:

  • success - Jumlah anggota yang berhasil diproses
  • skipped - Jumlah anggota yang dilewati (jika ada)
  • skipped_items - Array anggota yang dilewati beserta alasannya (jika ada)
  • dry-run - Penanda boolean jika menggunakan jenis kunci dryrun (jika berlaku)

Check-In

Mewakili catatan kehadiran seseorang di fasilitas, kelas, atau aktivitas. Digunakan untuk melacak kehadiran, analitik penggunaan, dan meningkatkan akurasi deteksi visual.

Endpoint

POST /partner/v1/check-ins - Save check-ins

Objek Check-In

Atribut

  • check_in_id string opsional

    Pengidentifikasi unik untuk check-in. Opsional - dibuat otomatis dari pasangan member_id dan timestamp jika tidak diberikan.

  • member_id string wajib

    Pengidentifikasi unik anggota.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi unik fasilitas dari Performance Hub.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Nilai pengidentifikasi unik untuk setiap lokasi yang digunakan mitra (misalnya, "Branch ID", "Location Code", "Store Number"). Pelajari lebih lanjut

  • check_in_type string opsional

    Jenis kunjungan. Salah satu dari member, class, staff, guest, atau trial.

  • source string opsional

    Cara check-in direkam. Nilai umum meliputi manual, tag, rfid, kiosk, app. Nilai tambahan seperti door_reader atau booking juga dapat digunakan.

  • class_id string opsional

    Opsional. Jika terkait dengan pemesanan atau kehadiran kelas.

  • timestamp string wajib

    Stempel waktu berformat ISO 8601 yang menunjukkan kapan check-in terjadi.

Objek Check-In

{
  // "check_in_id": "checkin_abc123",  // Optional - auto-generated from member_id + timestamp if not provided
  "member_id": "mem_12345",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "check_in_type": "member",
  "source": "rfid",
  "timestamp": "2025-01-20T08:45:30Z"
}

Menyimpan check-in

Membuat catatan check-in. API secara otomatis menghapus duplikat berdasarkan anggota, fasilitas, dan stempel waktu.

Parameter

  • check_ins array wajib

    Array objek Check-In yang akan disimpan. Maksimum yang disarankan: 1000 item per permintaan untuk kinerja optimal. API secara otomatis mengelompokkan item ke dalam batch untuk diproses. Setiap item harus menyertakan facility_id (wajib jika tidak menggunakan linking_identifier) atau linking_identifier (wajib jika tidak menggunakan facility_id).

Hasil

Mengembalikan pesan sederhana yang mengonfirmasi operasi sinkronisasi.

Permintaan

curl -X POST https://partner-api.performancehub.co/partner/v1/check-ins \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "check_ins": [
      {
        // "check_in_id": "checkin_abc123",  // Optional - auto-generated from member_id + timestamp if not provided
        "member_id": "mem_12345",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "check_in_type": "member",
        "source": "rfid",
        "timestamp": "2025-01-20T08:45:30Z"
      }
    ]
  }'

Respons

Mengembalikan pesan keberhasilan beserta metadata tentang operasi sinkronisasi.

{
  "message": "Check-in sync successful.",
  "metadata": {
    "success": 523,
    "skipped": 3,
    "skipped_items": [
      {
        "member_id": "member_789",
        "facility_id": null,
        "reason": "No matching facility_id for the linking_identifier"
      }
    ]
  }
}

Bidang metadata:

  • success - Jumlah check-in yang berhasil diproses
  • skipped - Jumlah check-in yang dilewati (jika ada)
  • skipped_items - Array check-in yang dilewati beserta alasannya (jika ada)
  • dry-run - Penanda boolean jika menggunakan jenis kunci dryrun (jika berlaku)

Kontrol Akses

Partner API dapat memicu perangkat keras Door/Gate Controller Performance Hub untuk fasilitas yang mengaktifkan integrasi Anda.

Gunakan API ini ketika sistem manajemen anggota Anda telah memutuskan bahwa seseorang diizinkan masuk. Performance Hub tidak mengevaluasi status keanggotaan, jam akses, aturan zona pintu, pemeriksaan penipuan, atau logika penangguhan. Sistem Anda tetap menjadi penentu untuk keputusan-keputusan tersebut.

Permintaan buka kunci bersifat sinkron. Performance Hub mengirimkan perintah ke pengontrol di lokasi secara real time dan mengembalikan 200 hanya setelah perangkat mengonfirmasi bahwa relai secara fisik telah membuka kunci. Sebagian besar konfirmasi seharusnya selesai dalam 3-5 detik. Jika tidak ada konfirmasi yang diterima dalam jangka waktu batas waktu, API mengembalikan kegagalan secara eksplisit.

Anda juga dapat mencatat upaya akses atau penolakan yang tidak pernah mencapai pengontrol. Panggilan tersebut tidak membuka kunci pintu. Panggilan itu menulis peristiwa ke Access Logs Door & Gate Access.

Endpoint

GET /partner/v1/access-control/doors - List available Door/Gate Controllers
GET /partner/v1/access-control/doors/{door_id} - Get Door/Gate Controller status
POST /partner/v1/access-control/doors/{door_id}/unlock - Unlock a Door/Gate Controller
POST /partner/v1/access-control/doors/{door_id}/access-events - Record an access attempt or denial

Objek Door/Gate Controller

Atribut

  • door_id string wajib

    Pengidentifikasi unik untuk Door/Gate Controller. Simpan ini di sistem Anda setelah penemuan dan gunakan saat memanggil endpoint unlock.

  • facility_id string wajib

    ID fasilitas Performance Hub.

  • linking_identifier string opsional

    Pengidentifikasi fasilitas mitra jika integrasi Anda menggunakan linking identifier. Pelajari lebih lanjut

  • name string wajib

    Nama perangkat yang mudah dibaca, yang dikonfigurasi di Performance Hub.

  • zone string opsional

    Zona atau lokasi pintu, seperti Entrance.

  • status string wajib

    online atau offline.

  • relay_state string opsional

    Status relai terbaru yang diketahui, seperti locked atau unlocked.

  • maintenance_mode string wajib

    Mode pemeliharaan saat ini. Salah satu dari off, force-open, atau force-closed.

  • hold_time_seconds integer wajib

    Waktu tahan buka kunci default yang dikonfigurasi untuk pintu.

  • last_seen string opsional

    Stempel waktu ISO untuk pembaruan metadata perangkat terbaru.

Objek Door/Gate Controller

{
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "linking_identifier": "branch_downtown",
  "name": "Front Door",
  "zone": "Entrance",
  "status": "online",
  "online": true,
  "relay_state": "locked",
  "maintenance_mode": "off",
  "hold_time_seconds": 10,
  "last_seen": "2026-05-01T04:30:00.000Z"
}

Menampilkan daftar Door/Gate Controller

Mengembalikan Door/Gate Controller yang tersedia untuk integrasi Anda.

Jika facility_id maupun linking_identifier tidak diberikan, API mengembalikan Door/Gate Controller di semua fasilitas yang tertaut ke akun mitra Anda.

Recommended: Include a facility identifier whenever possible. Requests without `facility_id` or `linking_identifier` may take longer to load for partners with hundreds or thousands of Door/Gate Controllers.

Parameter

  • facility_id string opsional salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    ID fasilitas Performance Hub. Gunakan ini untuk integrasi direct-link.

  • linking_identifier string opsional salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi fasilitas/lokasi milik Anda sendiri. Gunakan ini jika integrasi Anda dikonfigurasi untuk linking identifier.

Hasil

Mengembalikan array objek Door/Gate Controller.

Permintaan

curl -X GET "https://partner-api.performancehub.co/partner/v1/access-control/doors?facility_id=550e8400-e29b-41d4-a716-446655440000" \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Respons

{
  "data": [
    {
      "door_id": "00000000000000000000000000000007",
      "facility_id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Front Door",
      "zone": "Entrance",
      "status": "online",
      "relay_state": "locked",
      "maintenance_mode": "off",
      "hold_time_seconds": 10,
      "last_seen": "2026-05-01T04:30:00.000Z"
    }
  ]
}

Mendapatkan status Door/Gate Controller

Mengambil status terbaru yang diketahui dan konfigurasi dasar untuk satu Door/Gate Controller.

Berikan pengidentifikasi fasilitas agar Performance Hub dapat memverifikasi bahwa pintu tersebut milik fasilitas yang dapat diakses integrasi Anda.

Parameter

  • door_id string wajib

    ID Door/Gate Controller yang dikembalikan oleh endpoint list.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    ID fasilitas Performance Hub. Wajib untuk integrasi direct-link.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi fasilitas mitra. Wajib untuk integrasi linking-identifier.

Hasil

Mengembalikan objek Door/Gate Controller.

Permintaan

curl -X GET "https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007?facility_id=550e8400-e29b-41d4-a716-446655440000" \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Respons

{
  "data": {
    "door_id": "00000000000000000000000000000007",
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Front Door",
    "zone": "Entrance",
    "status": "online",
    "relay_state": "locked",
    "maintenance_mode": "off",
    "hold_time_seconds": 10,
    "last_seen": "2026-05-01T04:30:00.000Z"
  }
}

Membuka kunci Door/Gate Controller

Mengirimkan perintah buka kunci ke Door/Gate Controller dan menunggu relai fisik mengonfirmasi bahwa kunci telah terbuka.

Sistem Anda harus memutuskan apakah orang tersebut berwenang sebelum memanggil endpoint ini. Performance Hub hanya memverifikasi kunci mitra, akses fasilitas, kepemilikan pintu, dan status perangkat.

Parameter

  • door_id string wajib

    ID Door/Gate Controller yang dikembalikan oleh endpoint list.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    ID fasilitas Performance Hub. Wajib untuk integrasi direct-link.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi fasilitas mitra. Wajib untuk integrasi linking-identifier.

  • member_id string wajib

    ID anggota mitra. Ini digunakan untuk pencatatan audit dan penautan data selanjutnya.

  • first_name string wajib

    Nama depan orang yang membuka pintu.

  • last_name string wajib

    Nama belakang orang yang membuka pintu.

  • full_name string opsional

    Opsional. Jika dihilangkan, Performance Hub menggabungkan first_name dan last_name.

  • check_in_id string opsional

    ID check-in opsional dari sistem Anda untuk korelasi.

  • idempotency_key string opsional

    Kunci perlindungan pemutaran ulang opsional. Menggunakan kembali kunci yang sama untuk mitra, fasilitas, dan pintu yang sama akan mengembalikan hasil yang sudah ada jika tersedia.

Hasil

Mengembalikan 200 hanya jika perangkat mengonfirmasi bahwa relai secara fisik telah membuka kunci. Pintu menggunakan waktu tahan yang dikonfigurasi di Manajemen Perangkat Performance Hub; mitra tidak dapat mengganti pengaturan waktu relai per permintaan. Sebagian besar konfirmasi seharusnya selesai dalam 3-5 detik. Perlakukan batas waktu yang terdokumentasi sebagai buka kunci yang gagal secara eksplisit, dan coba ulang hanya sesuai dengan aturan keselamatan Anda sendiri.

Kegagalan umum:

  • 403 integration_not_enabled - integrasi Anda tidak diaktifkan untuk fasilitas tersebut.
  • 409 maintenance_mode_active - staf fasilitas telah mengaktifkan mode pemeliharaan untuk pintu tersebut.
  • 503 device_offline - Door/Gate Controller sedang offline atau datanya usang.
  • 504 unlock_confirmation_timeout - perintah telah dikirim tetapi tidak ada konfirmasi yang cocok diterima sebelum batas waktu.

Permintaan

curl -X POST https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007/unlock \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "member_id": "mem_12345",
    "first_name": "Jane",
    "last_name": "S.",
    "full_name": "Jane S.",
    "source": "door_reader",
    "idempotency_key": "unlock_20260501_0001"
  }'

Respons

{
  "status": "unlocked",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "command_id": "00000000-0000-0000-0000-000000000049",
  "hold_time_seconds": 10,
  "confirmed_at": "2026-05-01T04:30:00.000Z"
}

Respons kegagalan

{
  "status": "failed",
  "reason": "device_offline",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045"
}

Mencatat upaya akses atau penolakan

Mencatat upaya akses atau penolakan yang telah diputuskan oleh sistem Anda. Door/Gate Controller tidak dihubungi, dan pintu tidak terbuka.

Gunakan ini ketika sistem Anda menolak masuk, atau ketika suatu upaya perlu muncul di Access Logs Door & Gate Access tanpa pembukaan kunci. Performance Hub tidak mengevaluasi status keanggotaan, jam akses, atau aturan akses lainnya.

Peristiwa yang ditolak muncul di Access Logs Door & Gate Access dengan hasil Denied, nama mitra Anda, pintunya, pengidentifikasi anggota jika Anda mengirimkannya, dan kode alasan dalam bentuk yang mudah dibaca. Misalnya, membership_expired ditampilkan sebagai "Membership Expired". reason_display_text dan user_email disimpan bersama peristiwa tersebut.

Parameter

  • door_id string wajib

    ID Door/Gate Controller yang dikembalikan oleh endpoint list.

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    ID fasilitas Performance Hub. Wajib untuk integrasi direct-link.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi fasilitas mitra. Wajib untuk integrasi linking-identifier.

  • outcome string wajib

    denied atau attempted.

  • reason string opsional

    Kode alasan dalam snake_case huruf kecil, hingga 64 karakter. Wajib jika outcome bernilai denied. Contoh: membership_expired.

  • reason_display_text string opsional

    Alasan yang mudah dibaca, hingga 256 karakter. Contoh: Membership expired on 2026-04-01.

  • member_id string opsional

    ID anggota mitra. Hilangkan jika kredensial tidak cocok dengan anggota mana pun, misalnya kartu yang tidak dikenal.

  • user_email string opsional

    Email orang yang mencoba mengakses.

  • timestamp string opsional

    Waktu terjadinya upaya, dalam format ISO 8601 dengan zona waktu. Contoh: 2026-05-18T10:15:30Z. Default-nya adalah waktu permintaan diterima. Tidak boleh lebih dari 5 menit di masa depan atau lebih lama dari 30 hari.

  • idempotency_key string opsional

    Kunci perlindungan pemutaran ulang, hingga 128 karakter. Menggunakan kembali kunci yang sama untuk mitra, fasilitas, dan pintu yang sama akan mengembalikan hasil aslinya.

Hasil

Mengembalikan 201 saat peristiwa dicatat. Memutar ulang idempotency_key yang sama mengembalikan 200 dengan idempotent bernilai true dan tidak membuat peristiwa lain.

Kunci dry-run mengembalikan 200 dengan dry_run bernilai true. Tidak ada yang dicatat.

Kegagalan umum:

  • 400 - isi permintaan tidak valid, penolakan tidak memiliki reason, stempel waktu di luar rentang, atau facility_id / linking_identifier tidak cocok dengan fasilitas yang tertaut.
  • 403 - kunci bersifat read-only.
  • 403 integration_not_enabled - integrasi Anda tidak diaktifkan untuk fasilitas tersebut. message memberikan alasannya.
  • 404 - Door/Gate Controller tidak ditemukan untuk fasilitas yang tertaut.

Permintaan

curl -X POST https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007/access-events \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "outcome": "denied",
    "reason": "membership_expired",
    "reason_display_text": "Membership expired on 2026-04-01",
    "member_id": "mem_12345",
    "user_email": "member@example.com",
    "timestamp": "2026-05-18T10:15:30Z",
    "idempotency_key": "evt_abc12345"
  }'

Respons

{
  "status": "recorded",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "outcome": "denied",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-05-18T10:15:30.000Z"
}

Pemutaran ulang idempoten

{
  "status": "recorded",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "outcome": "denied",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-05-18T10:15:30.000Z",
  "idempotent": true
}

Laporan Fasilitas

Catatan pada satu titik waktu yang merekam metrik operasional dan keuangan utama suatu fasilitas selama periode tertentu.

Endpoint

POST /partner/v1/report-snapshots - Save report snapshots

Objek Report Snapshot

Atribut

  • facility_id string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Pengidentifikasi unik fasilitas dari Performance Hub.

  • linking_identifier string salah satuBerikan jenis pengidentifikasi fasilitas yang dikonfigurasi untuk integrasi Anda: gunakan facility_id untuk integrasi direct-link, atau linking_identifier untuk integrasi linking-identifier. Jangan kirim keduanya; API menggunakan jenis pengidentifikasi yang dikonfigurasi untuk akun mitra Anda dan mengabaikan yang lainnya. Pelajari lebih lanjut

    Nilai pengidentifikasi unik untuk setiap lokasi yang digunakan mitra (misalnya, "Branch ID", "Location Code", "Store Number"). Pelajari lebih lanjut

  • start_date string wajib

    Tanggal mulai periode snapshot dalam format YYYY-MM-DD.

  • end_date string wajib

    Tanggal akhir periode snapshot dalam format YYYY-MM-DD.

  • metrics object wajib

    Objek metrik yang berisi data anggota dan pendapatan untuk periode tersebut.

Objek Report Snapshot

{
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "start_date": "2025-01-01",
  "end_date": "2025-01-31",
  "metrics": {
    "members": {
      "active": 1200,
      "new": 45,
      "cancelled": 12
    },
    "revenue": {
      "total_payments": 289000.00,
      "total_payments_count": 1200,
      "currency": "AUD"
    }
  }
}

Menyimpan snapshot laporan

Mengirimkan metrik operasional dan keuangan untuk suatu fasilitas selama periode tertentu.

Parameter

  • snapshots array wajib

    Array objek Report Snapshot yang akan disimpan. Maksimum 25 item per permintaan. Setiap item harus menyertakan facility_id (wajib jika tidak menggunakan linking_identifier) atau linking_identifier (wajib jika tidak menggunakan facility_id).

Hasil

Mengembalikan pesan sederhana yang mengonfirmasi operasi sinkronisasi.

Permintaan

curl -X POST https://partner-api.performancehub.co/partner/v1/report-snapshots \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "snapshots": [
      {
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "start_date": "2025-01-01",
        "end_date": "2025-01-31",
        "metrics": {
          "members": {
            "active": 1200,
            "new": 45,
            "cancelled": 12
          },
          "revenue": {
            "total_payments": 289000.00,
            "currency": "AUD"
          }
        }
      }
    ]
  }'

Respons

{
  "message": "Report snapshot sync successful."
}

Kesalahan

Partner API menggunakan kode status HTTP standar dan isi respons JSON untuk menjelaskan mengapa suatu permintaan gagal.

Bentuk respons kesalahan

Sebagian besar kesalahan API mengembalikan isi JSON dengan pesan dan, jika tersedia, detail terstruktur.

Kode status

Kegagalan Access Time Window

Validasi jendela gagal sebelum snapshot yang tidak valid ditulis. Penyebab umum yang tidak dapat dicoba ulang meliputi:

  • access_time_windows_revision tidak ada padahal access_time_windows ada.
  • Nilai epoch berupa string, bilangan floating-point, atau kemungkinan dalam milidetik.
  • Zona waktu IANA yang tidak valid, interval terbalik, external_id duplikat, blok mingguan yang tumpang tindih, atau blok semalam yang tidak dipisah.
  • Nilai di luar batas jumlah, panjang, atau rentang yang didokumentasikan.

Revisi berulang dengan konten ternormalisasi yang berbeda menghasilkan 409 Conflict. Lakukan rekonsiliasi dengan status otoritatif terbaru dan alokasikan revisi yang lebih baru; jangan terus mencoba ulang pasangan yang bertentangan. Revisi yang lebih lama dilaporkan sebagai snapshot usang yang dilewati, bukan dibiarkan menimpa status yang lebih baru. Untuk scope_key yang tidak dikenal atau tidak dipetakan, otorisasi ditolak sehingga tidak ada akses yang diberikan, dan hal ini harus diperlakukan sebagai peringatan konfigurasi.

Jika pengiriman melewati batas waktu atau menerima 5xx sementara, coba ulang snapshot ternormalisasi yang sama persis dengan revisi yang sama. Jika pengambilan dari sumber upstream gagal, hilangkan bidang jendela sepenuhnya; jangan pernah menggantinya dengan array kosong.

Panduan percobaan ulang

Coba ulang respons berikut dengan exponential backoff yang terbatas:

  • 429
  • 500
  • 502
  • 503
  • 504

Jangan mencoba ulang respons berikut secara membabi buta:

  • 400
  • 401
  • 403
  • 404
  • 409
  • 422

Untuk kontrol akses, selalu perlakukan respons batas waktu dan offline sebagai buka kunci yang gagal, kecuali aturan akses dan proses keselamatan Anda sendiri menentukan lain.

Detail yang perlu disertakan untuk dukungan

Saat menghubungi dukungan, sertakan:

  • Endpoint dan metode HTTP.
  • Stempel waktu dan zona waktu.
  • ID kunci mitra, bukan kunci rahasianya.
  • Pengidentifikasi fasilitas yang digunakan.
  • ID rekaman sumber dari sistem Anda.
  • Status dan isi respons.
  • event_id atau command_id jika tersedia.
{
  "success": false,
  "message": "Request body.members[0].member_id is required"
}

Beberapa endpoint khusus domain mengembalikan status dan alasan secara eksplisit. Misalnya, kegagalan kontrol akses menyertakan bidang seperti reason, door_id, facility_id, dan event_id.

{
  "status": "failed",
  "reason": "device_offline",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045"
}

400 Bad Request

Permintaan salah format atau tidak memiliki bidang yang wajib. Perbaiki permintaan sebelum mencoba ulang.

401 Unauthorized

Autentikasi gagal. Pastikan Anda menggunakan HTTP Basic Auth dengan kunci rahasia API sebagai nama pengguna dan kata sandi kosong.

403 Forbidden

Kunci valid, tetapi operasi tidak diizinkan. Penyebab umum meliputi penggunaan kunci read-only untuk operasi tulis atau upaya mengakses fasilitas yang tidak mengaktifkan integrasi Anda.

404 Not Found

Sumber daya yang diminta tidak ditemukan atau tidak tersedia untuk integrasi Anda.

409 Conflict

Permintaan bertentangan dengan status sumber daya saat ini. Untuk kontrol akses, hal ini dapat mencakup Door/Gate Controller yang sedang dalam mode pemeliharaan.

422 Unprocessable Entity

Permintaan berupa JSON yang valid tetapi gagal dalam validasi semantik. Perbaiki data sebelum mencoba ulang.

429 Too Many Requests

Integrasi melampaui batas laju yang didokumentasikan. Coba ulang dengan exponential backoff.

500 Internal Server Error

Performance Hub tidak dapat menyelesaikan permintaan karena kesalahan internal. Coba ulang dengan backoff. Jika masalah berlanjut, hubungi dukungan dengan menyertakan endpoint, stempel waktu, dan isi respons.

503 Service Unavailable

Layanan atau perangkat yang dibutuhkan tidak tersedia. Untuk pembukaan kunci Door/Gate Controller, ini dapat berarti pengontrol sedang offline.

504 Gateway Timeout

Operasi melewati batas waktu. Untuk pembukaan kunci Door/Gate Controller, ini berarti pembukaan kunci tidak dikonfirmasi sebelum jangka waktu batas waktu berakhir.

Pembuatan Versi

Versi Partner API ditentukan di URL. Versi saat ini adalah:

Kebijakan perubahan

Performance Hub berupaya membuat perubahan yang bersifat tambahan dan kompatibel ke belakang bila memungkinkan.

Contoh perubahan yang kompatibel ke belakang:

  • Menambahkan bidang opsional baru ke permintaan.
  • Menambahkan bidang baru ke respons.
  • Menambahkan endpoint baru.
  • Menambahkan nilai enum baru jika klien diharapkan dapat menangani nilai yang tidak dikenal.
  • Memperbaiki pesan validasi tanpa mengubah kontrak kode status.

access_time_windows dan access_time_windows_revision adalah bidang permintaan Member yang bersifat tambahan. Klien yang ada dan tidak menyertakannya akan mempertahankan snapshot Access Time Window yang tersimpan tanpa perubahan. Aturan penghilangan ini menjaga kompatibilitas upsert parsial; menghilangkan bidang tidak sama dengan mengirimkan array kosong.

Contoh perubahan yang merusak kompatibilitas:

  • Menghapus atau mengganti nama bidang.
  • Mengubah tipe bidang.
  • Menjadikan bidang permintaan opsional sebagai wajib.
  • Menghapus endpoint.
  • Mengubah makna kode status yang ada atau reason khusus domain.

Penghentian

Jika perubahan yang merusak kompatibilitas diperlukan, Performance Hub sebisa mungkin akan menghindari mengubah versi yang ada secara langsung. Sebagai gantinya, kami akan memperkenalkan versi atau jalur migrasi baru dan mengomunikasikan perubahan tersebut kepada mitra yang terdampak.

Pemberitahuan penghentian dapat mencakup:

  • Entri log perubahan.
  • Komunikasi langsung dengan mitra.
  • Catatan di Partner Console.
  • Panduan migrasi di dokumentasi.

Rekomendasi untuk klien

Bangun klien yang toleran terhadap perubahan tambahan:

  • Abaikan bidang respons yang tidak Anda gunakan.
  • Perlakukan nilai enum yang tidak dikenal sebagai tidak didukung, alih-alih membuat aplikasi mogok.
  • Hindari pemeriksaan kesamaan respons yang ketat.
  • Catat nilai yang tidak dikenali agar Anda dapat memperbarui integrasi secara terencana.

Untuk partisi Member berrevisi seperti Access Time Windows, simpan revisi yang dikirimkan dan payload ternormalisasi hingga hasilnya diketahui. Menggunakan kembali revisi untuk konten yang berubah merupakan konflik, sedangkan memutar ulang konten yang sama bersifat idempoten. Lihat Access Time Windows.

Spesifikasi OpenAPI

Gunakan spesifikasi OpenAPI yang dipublikasikan untuk membuat klien, memvalidasi permintaan, dan melacak perubahan bentuk API dari waktu ke waktu.

Lihat Spesifikasi OpenAPI.

https://partner-api.performancehub.co/partner/v1/

Log Perubahan

Log perubahan ini mencatat perubahan penting pada Partner API dan Partner Console yang memengaruhi perilaku integrasi.

2026-09-09

2026-05-06

2026-05-01

Kategori perubahan

Entri mendatang menggunakan kategori berikut:

  • Added - endpoint, bidang, panduan, atau kemampuan baru.
  • Changed - perilaku atau dokumentasi berubah tanpa menghapus dukungan.
  • Deprecated - fitur tetap tersedia tetapi memiliki rencana jalur migrasi.
  • Removed - fitur atau endpoint dihapus.
  • Fixed - perbaikan bug atau koreksi dokumentasi.
  • Security - perubahan autentikasi, otorisasi, penanganan data, atau pengelolaan kunci.

Ditambahkan

  • Menambahkan snapshot access_time_windows Member yang netral vendor dengan gabungan jendela absolut dan jendela mingguan berulang.
  • Menambahkan semantik pengurutan access_time_windows_revision, pemutaran ulang idempoten, konflik, lewati-data-usang, dan pencabutan eksplisit.
  • Menambahkan panduan zona waktu IANA, waktu musim panas, pemetaan scope_key logis, kesegaran sumber, implementasi produsen, dan sertifikasi.

Ditambahkan

  • Menambahkan dokumentasi program mitra yang mencakup jenis mitra, orientasi, praktik terbaik, kesiapan go-live, kesalahan, pembuatan versi, dan dukungan.
  • Menambahkan alur pertanyaan Menjadi Mitra khusus untuk calon mitra teknis dan komersial.
  • Menambahkan dokumentasi tentang cara integrasi mitra yang disetujui ditampilkan di direktori mitra Performance Hub di dalam platform inti Performance Hub.

Ditambahkan

  • Menambahkan dokumentasi kontrol akses Door/Gate Controller, termasuk operasi list, status, dan unlock.
  • Menambahkan dokumentasi perilaku buka kunci sinkron: API mengembalikan keberhasilan hanya setelah pengontrol di lokasi mengonfirmasi bahwa relai secara fisik telah membuka kunci.
  • Menambahkan dokumentasi dukungan idempotency_key opsional untuk permintaan unlock Door/Gate Controller.