Introduzione
La Partner API del Performance Hub consente alle piattaforme dei partner esterni di integrarsi senza difficoltà con i moduli principali del Performance Hub. L'API supporta computer vision, analisi, registrazione degli accessi dei membri e insight sulle strutture.
Formato delle richieste
L'API accetta corpi di richiesta codificati in JSON e restituisce risposte codificate in JSON.
Limitazione della frequenza
Per garantire un uso equo e la stabilità del sistema, gli account della Partner API partono con questi limiti predefiniti:
- 5 richieste al secondo per endpoint
- Consigliato: massimo 1000 elementi per richiesta batch, per prestazioni ottimali
- Dimensione del payload di massimo 10MB
I limiti di frequenza sono modificabili e possono essere configurati caso per caso dal tuo account manager partner del Performance Hub. Se la tua integrazione ha bisogno di un throughput più elevato per il lancio, le migrazioni, i backfill di report o strutture con volumi elevati, segnalalo durante l'onboarding o prima della finestra di modifica prevista.
URL di base
https://partner-api.performancehub.co/partner/v1/
Autenticazione
L'accesso alla Partner API richiede l'autenticazione con chiavi segrete API. Genera e gestisci le tue chiavi tramite la Partner Console.
Le chiavi API sono le tue credenziali per accedere alle risorse dei partner. Ogni chiave ha un accesso limitato ai dati di organizzazioni specifiche e può essere disattivata all'istante quando necessario.
Gestisci con cura le tue chiavi API: danno accesso completo al tuo account! Non esporre mai queste chiavi in repository pubblici, applicazioni lato client o in qualsiasi altro luogo in cui potrebbero essere compromesse.
Autentica le richieste con HTTP Basic Auth, passando la tua chiave API come nome utente. Lascia vuota la password.
L'API accetta solo connessioni HTTPS sicure. Le richieste HTTP non cifrate vengono rifiutate, così come tutte le richieste prive di credenziali di autenticazione valide.
Esempio di richiesta
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.
Verificare la chiave segreta
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>" }
Elenco di controllo per il go-live
Usa questo elenco di controllo prima di attivare un'integrazione partner per le strutture in produzione.
Configurazione della Partner Console
- Il tuo profilo partner è completo.
- URL del logo, sito web, categoria e descrizione sono corretti.
- Il metodo di collegamento dei dati è configurato: Direct Link o Linking Identifier.
- Il collegamento delle strutture è stato testato con almeno una struttura reale.
- Viene usato il tipo di chiave corretto:
- Dryrun per testare le scritture senza effetti distruttivi.
- Read-only per un consumo sicuro dei dati.
- Live solo quando sei pronto a modificare i dati di produzione.
Autenticazione e gestione delle chiavi
- Le chiavi segrete sono conservate solo lato server.
- Le chiavi non sono incorporate in applicazioni lato client, app mobili, repository pubblici o ticket di assistenza.
- La rotazione e la revoca delle chiavi sono state testate.
- Il tuo team sa quale chiave viene usata in ciascun ambiente.
Convalida dei dati
- I campi obbligatori sono presenti per ogni endpoint che chiami.
- Gli identificatori delle strutture corrispondono al metodo di collegamento configurato.
- Gli ID del tuo sistema sono stabili e non cambiano tra una sincronizzazione e l'altra.
- Le importazioni di grandi dimensioni sono suddivise in batch entro i limiti documentati.
- Gli elementi dei batch non riusciti possono essere identificati e inviati di nuovo.
Test degli endpoint
Prima del lancio, testa ogni endpoint da cui dipende la tua integrazione:
- Le organizzazioni e le strutture possono essere lette.
- I membri possono essere salvati e aggiornati.
- Piani di abbonamento, zone di accesso e orari di accesso si sincronizzano correttamente.
- I check-in vengono accettati e possono essere ricondotti al tuo sistema.
- Le istantanee dei report usano il periodo di riferimento e le metriche previsti.
- I flussi dei Door/Gate Controller sono testati su hardware reale, ove applicabile.
Preparazione per le Access Time Windows
Se l'integrazione fornisce Access Time Windows:
- Gli esempi assoluti e settimanali superano l'elenco di controllo per la certificazione dei produttori.
- Gli epoch sono secondi Unix interi senza virgolette; i limiti esatti
[from, to)sono stati testati. - Sono stati verificati i valori predefiniti UTC, i fusi orari IANA personalizzati dell'integrazione e i relativi passaggi all'ora legale.
- Un unico flusso di revisioni per membro/fonte, persistente e monotono, coordina aggiornamenti incrementali, riconciliazione e nuovi tentativi.
- Gli operatori comprendono il comportamento nei casi di campo omesso, sostituzione completa, idempotenza, conflitto, dati obsoleti e
[]esplicito. - Ogni
scope_key, compresodefault, ha una mappatura approvata nel Performance Hub; è stato verificato che le chiavi sconosciute neghino l'accesso per impostazione predefinita. - La frequenza di aggiornamento prevista dall'integrazione, l'età massima dei dati di origine, il comportamento con dati di origine obsoleti e gli avvisi sono configurati.
- È stato dimostrato che un errore di recupero a monte non genera un'istantanea vuota o parziale.
- La convergenza del flusso in staging, l'annullamento/la revoca e i limiti di inizio e fine sulle porte fisiche rispettano gli obiettivi concordati.
- Le regole ordinarie e le concessioni permanenti sono state verificate come percorsi di riserva, e le finestre non possono aggirare la disattivazione dell'utente,
blockAllAccess, la manutenzione o il geofencing.
Preparazione per il controllo degli accessi
Per le integrazioni di controllo degli accessi:
- Il tuo sistema prende la decisione sull'accesso prima di chiamare il Performance Hub.
- L'integrazione gestisce
device_offline,maintenance_mode_activeeunlock_confirmation_timeout. - Gli operatori sanno che un timeout significa che lo sblocco non è stato confermato.
- I tuoi log memorizzano l'
event_ide ilcommand_idrestituiti. - Hai una procedura di riserva manuale per il personale della struttura.
Gestione degli errori e nuovi tentativi
- Le risposte
400,401,403,404,409e422vengono segnalate agli operatori o ai team di assistenza invece di essere ripetute alla cieca. - Le risposte
429,500,502,503e504usano una logica di nuovi tentativi limitata, con backoff. - Gli errori ripetuti generano un avviso nel tuo sistema.
- L'integrazione non scarta mai in modo silenzioso i record non riusciti.
Osservabilità
- I tuoi log includono endpoint, timestamp, identificatore della struttura, ID del record di origine, esito della richiesta e corpo della risposta.
- Il tuo team di assistenza può cercare per ID del membro, ID della struttura, ID del check-in o ID dell'evento di sblocco.
- Hai un modo per ripetere o riconciliare le sincronizzazioni non riuscite.
Lancio in produzione
- Il Performance Hub ha confermato il tuo accesso alla produzione.
- Almeno una struttura in produzione ha attivato la tua integrazione.
- La tua chiave di produzione è attiva.
- I tuoi referenti operativi e tecnici sono aggiornati.
- La tua procedura di assistenza è documentata per i clienti.
Una volta completate queste verifiche, la tua integrazione configurata comparirà nella directory dei partner del Performance Hub, all'interno della piattaforma principale del Performance Hub.
Best practice
Segui questi schemi per mantenere le integrazioni partner prevedibili, osservabili e sicure per le strutture.
Identificare le strutture in modo coerente
Scegli il metodo di collegamento configurato per il tuo account partner e usalo in modo coerente:
- Direct Link - usa il
facility_iddel Performance Hub restituito dall'endpoint delle strutture. - Linking Identifier - usa il tuo identificatore di sede, ad esempio un ID filiale, un codice di sede o un numero di negozio.
Non inviare entrambi gli identificatori nella stessa richiesta. Il Performance Hub risolve le richieste con il metodo di collegamento configurato per il tuo account partner.
Consulta Metodi di collegamento dei partner per le indicazioni sulla configurazione.
Scritture in batch con attenzione
La Partner API accetta corpi di richiesta JSON ed è progettata, dove documentato, per flussi di sincronizzazione basati su batch. Mantieni i batch di dimensioni limitate e ripetibili.
Indicazioni predefinite:
- Usa fino a 1000 elementi per richiesta batch per prestazioni ottimali.
- Mantieni i payload sotto i 10MB.
- Resta entro 5 richieste al secondo per endpoint.
I limiti di frequenza sono modificabili e possono essere configurati caso per caso dal tuo account manager partner del Performance Hub. Se prevedi importazioni ad alto volume, traffico di lancio o backfill di report, concorda il throughput necessario prima della finestra di modifica.
Se devi sincronizzare un set di dati di grandi dimensioni, suddividilo in blocchi deterministici e registra l'ID di ogni blocco dal tuo lato. In questo modo è più facile analizzare i tentativi non riusciti.
Ripetere i tentativi in sicurezza
Usa un backoff esponenziale per gli errori temporanei, come 429, 500, 502, 503 e 504.
Evita cicli di tentativi ravvicinati. Un buon punto di partenza è:
- Riprova dopo 1 secondo.
- Riprova dopo 2 secondi.
- Riprova dopo 4 secondi.
- Interrompi e invia un avviso se l'operazione continua a non riuscire.
Per gli errori di convalida, come 400 o 422, correggi la richiesta prima di riprovare.
Usare l'idempotenza dove supportata
L'endpoint di sblocco del Door/Gate Controller supporta una idempotency_key facoltativa. Riutilizzando la stessa chiave per lo stesso partner, la stessa struttura e la stessa porta si ottiene il risultato esistente, se disponibile.
Usa una chiave stabile per l'azione eseguita, ad esempio un ID di check-in o un ID di evento di accesso del tuo sistema.
Non dare per scontato che ogni endpoint di scrittura supporti l'idempotenza, a meno che non sia documentato per quell'endpoint.
Mantenere puliti i dati di origine
Invia, ove possibile, valori stabili e normalizzati:
- Usa ID coerenti per membri, piani, strutture e check-in provenienti dal tuo sistema di origine.
- Usa timestamp ISO 8601 per date e orari.
- Invia i numeri di telefono in formato internazionale, se disponibili.
- Invia le valute usando i campi documentati per ciascun endpoint.
- Evita di sovraccaricare i campi di testo libero con dati che appartengono a campi strutturati.
Progettare per sincronizzazioni incrementali e complete
La maggior parte delle integrazioni partner ha bisogno di entrambe:
- Sincronizzazioni incrementali per le modifiche quotidiane.
- Sincronizzazioni di riconciliazione complete per correggere eventi mancati, importazioni storiche o disallineamenti dei dati.
La tua integrazione deve essere in grado di inviare di nuovo lo stato attuale di un membro, di un piano di abbonamento o di un'istantanea di report senza dipendere dall'esito positivo di una richiesta precedente.
Pubblicare le Access Time Windows in sicurezza
Tratta il valore access_time_windows di ogni membro come un'istantanea completa con una revisione indipendente:
- Coordina un unico flusso monotonicamente crescente di
access_time_windows_revisiontra i worker incrementali e quelli di riconciliazione. - Ripeti una consegna incerta o non riuscita temporaneamente con la stessa revisione e lo stesso payload normalizzato.
- Ometti
access_time_windowsquando non lo aggiorni. - Invia
[]solo dopo che un recupero riuscito dalla fonte autorevole dimostra che non restano finestre. Non trasformare mai un timeout a monte, un risultato parziale o un errore di parsing in una revoca. - Mantieni stabili
external_idescope_keye certifica ogni mappatura degli ambiti prima della produzione. - Monitora l'età dei dati di origine rispetto ai criteri di aggiornamento concordati per quell'integrazione.
Consulta la guida autorevole per i produttori di Access Time Windows per istantanee complete, fusi orari, ora legale, annullamento e vettori di test.
Considerare il controllo degli accessi un aspetto critico per la sicurezza
Per gli sblocchi dei Door/Gate Controller:
- Il tuo sistema deve decidere se la persona può entrare prima di chiamare il Performance Hub.
- Il Performance Hub restituisce
200solo dopo che il controller in loco ha confermato che il relè si è fisicamente sbloccato. - La maggior parte delle conferme arriva entro 3-5 secondi.
- Un timeout è uno sblocco esplicitamente non riuscito, non un successo in background.
- Ripeti i tentativi solo secondo le tue regole di accesso e di sicurezza.
Registra sempre l'event_id e il command_id restituiti dall'endpoint di sblocco.
Monitorare la tua integrazione
Usa i log delle richieste della Partner Console durante lo sviluppo e il lancio. In produzione, mantieni anche log propri con:
- Data e ora della richiesta.
- Endpoint.
- ID del record di origine.
- Identificatore della struttura.
- Codice di stato HTTP.
- Corpo della risposta o messaggio di errore del Performance Hub.
Questi campi rendono l'assistenza e la riconciliazione molto più rapide quando un cliente chiede cosa è successo.
Organizzazioni
Rappresenta l'entità aziendale di primo livello che gestisce una o più strutture integrate con la piattaforma Performance Hub.
Endpoint
GET /partner/v1/organisations - List all organisations
L'oggetto Organizzazione
Attributi
org_id
stringobbligatorioIdentificatore univoco dell'organizzazione.
name
stringobbligatorioNome dell'organizzazione.
L'oggetto Organizzazione
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
}
Elencare tutte le organizzazioni
Restituisce l'elenco delle organizzazioni accessibili al tuo account partner.
Valore restituito
Restituisce un oggetto JSON con una proprietà data che contiene un array di oggetti Organizzazione.
Richiesta
curl https://partner-api.performancehub.co/partner/v1/organisations \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Risposta
{
"data": [
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
},
{
"org_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Wellness Studios Network"
}
]
}
Strutture
Rappresenta una sede fisica, come un ufficio, un negozio, un locale, un campus, una clinica o una palestra, in cui i membri possono accedere ai servizi.
Endpoint
GET /partner/v1/facilities - List all facilities
L'oggetto Struttura
Attributi
facility_id
stringobbligatorioIdentificatore univoco della struttura.
org_id
stringobbligatorioIdentificatore univoco dell'organizzazione principale.
name
stringobbligatorioNome della struttura.
brand
stringfacoltativoNome del brand usato dalla struttura.
website_url
stringfacoltativoURL del sito web della struttura.
place_data
objectfacoltativoDati sulla posizione provenienti dalla Google Places API, con paese, indirizzo formattato, Google Place ID, provincia e città.
social_links
objectfacoltativoLink ai social media della struttura.
timezone
stringfacoltativoIdentificatore del fuso orario IANA (ad esempio
"Australia/Sydney","America/New_York").
L'oggetto Struttura
{
"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"
}
Elencare tutte le strutture
Restituisce l'elenco delle strutture accessibili al tuo account partner.
Valore restituito
Restituisce un oggetto JSON con una proprietà data che contiene un array di oggetti Struttura.
Richiesta
curl https://partner-api.performancehub.co/partner/v1/facilities \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Risposta
{
"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"
}
]
}
Piani di abbonamento
Definisce un'offerta acquistabile da un'organizzazione o da una struttura, con servizi, diritti, programmazione e prezzi.
Endpoint
POST /partner/v1/membership-plans - Save a membership plan
L'oggetto Membership Plan
Attributi
membership_plan_id
stringobbligatorioIdentificatore univoco del piano di abbonamento.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore univoco della struttura nel Performance Hub.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùValore dell'identificatore univoco che il partner usa per ogni sede (ad esempio "Branch ID", "Location Code", "Store Number"). Scopri di più
name
stringobbligatorioNome leggibile del piano (ad esempio
"Office tenant – business hours","Student – term access","Hotel guest","10 Class Pack").billing_cycle
stringfacoltativoFrequenza di fatturazione. Uno tra
weekly,fortnightly,monthly,annuallyeone_time.price
integerfacoltativoCosto base nella più piccola unità della valuta (centesimi per USD/AUD).
currency
stringfacoltativoCodice valuta ISO 4217 (ad esempio
"AUD","USD").description
stringfacoltativoDescrizione facoltativa, di marketing o interna.
active_members
integerfacoltativoNumero di membri attivi che usano questo piano di abbonamento
is_recurring
booleanfacoltativoIndica se il piano si rinnova automaticamente.
is_trial
booleanfacoltativoIndica se si tratta di un'offerta di prova.
visible_to_public
booleanfacoltativoIndica se il piano è disponibile per l'acquisto in autonomia.
duration_days
integerfacoltativoNumero di giorni di validità del piano di abbonamento.
access_zones
arrayfacoltativoArray delle zone di accesso incluse nel piano di abbonamento. Ogni zona può definire orari di accesso propri. Consulta Zone di accesso per i dettagli.
class_limit
integerfacoltativoNumero massimo di lezioni consentite (null per un numero illimitato).
L'oggetto Membership Plan
Questo esempio usa facility_id. Per un'integrazione con identificatore di collegamento, invia invece "linking_identifier": "branch_downtown".
{
"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
}
Zone di accesso
Le zone di accesso definiscono le aree specifiche di una struttura a cui un piano di abbonamento dà accesso. Ogni zona può avere orari di accesso propri, così da consentire limitazioni orarie diverse per area.
Struttura dei dati
Ogni zona di accesso include:
name
stringobbligatorioIl nome della zona (ad esempio "Level 3 Tenancy", "Library", "Guest Floors", "Main Gym Floor").
description
stringfacoltativoDescrizione di ciò che è incluso nella zona.
access_hours
objectfacoltativoOrari di accesso specifici di questa zona. Consulta Orari di accesso per il formato degli intervalli di tempo.
Esempio
Un edificio per uffici con una palestra per i propri inquilini: accesso agli spazi in affitto durante l'orario lavorativo e alla palestra dalla mattina presto alla sera tardi.
{
"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"]]
}
}
]
}
Orari di accesso
Gli orari di accesso indicano quando i membri possono accedere a una zona specifica in ciascun giorno della settimana. Gli orari di accesso sono definiti per ogni zona di accesso, così da consentire limitazioni orarie diverse per le diverse aree di una struttura.
Struttura dei dati
{
"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"]]
}
Ogni giorno è un array di intervalli di tempo nel formato HH:MM (orologio a 24 ore). Un array vuoto [] significa nessun accesso in quel giorno. I giorni omessi vengono trattati come un array vuoto.
Esempi di casi d'uso
Inquilino di un ufficio – orario lavorativo: accesso durante l'orario lavorativo, solo nei giorni feriali.
{
"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"]]
}
}
Studente – accesso durante il periodo di lezione: una biblioteca universitaria aperta nei giorni feriali, con una pausa a metà giornata, e il sabato mattina.
{
"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"]]
}
}
Palestra – mattinieri: accesso solo al mattino nei giorni feriali.
{
"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"]]
}
}
Ospite di un hotel – 24/7: accesso sempre attivo, il caso d'uso più comune.
{
"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"]]
}
}
Esempio per zona
Un piano per gli ospiti di un hotel con accesso 24 ore su 24 ai piani delle camere e orari più ridotti per la piscina:
{
"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"]]
}
}
]
}
Salvare un piano di abbonamento
Crea o aggiorna i record dei piani di abbonamento. L'API stabilisce se creare o aggiornare in base al membership_plan_id.
Parametri
membership_plans
arrayobbligatorioArray di oggetti Membership Plan da salvare. Massimo consigliato: 1000 elementi per richiesta, per prestazioni ottimali. L'API suddivide automaticamente gli elementi in batch per l'elaborazione. Ogni elemento deve includere
facility_id(obbligatorio se non usilinking_identifier) oppurelinking_identifier(obbligatorio se non usifacility_id).
Valore restituito
Restituisce un semplice messaggio di conferma dell'operazione di sincronizzazione.
Richiesta
Questo esempio usa facility_id. Per un'integrazione con identificatore di collegamento, invia invece "linking_identifier": "branch_downtown".
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
}
]
}'
Risposta
Restituisce un messaggio di esito positivo con i metadati dell'operazione di sincronizzazione.
{
"message": "Membership plan sync successful.",
"metadata": {
"success": 98,
"skipped": 2,
"skipped_items": [
{
"membership_plan_id": "plan_456",
"facility_id": null,
"reason": "Missing facility_id"
}
]
}
}
Campi dei metadati:
- success - Numero di piani di abbonamento elaborati correttamente
- skipped - Numero di piani saltati (se presenti)
- skipped_items - Array dei piani saltati con i relativi motivi (se presenti)
- dry-run - Flag booleano presente se usi il tipo di chiave dryrun (se applicabile)
Membri
Rappresenta un singolo cliente di una struttura. Può essere un lead, un potenziale cliente, un cliente ricorrente, un membro scaduto o un utente bloccato.
Gli upsert dei membri possono includere anche un'istantanea access_time_windows completa e con revisione, che contiene accessi assoluti e settimanali ricorrenti. Consulta Access Time Windows prima di produrre questi campi. Si tratta di autorizzazioni aggiuntive, che non sostituiscono le regole ordinarie o le concessioni permanenti della struttura.
Endpoint
POST /partner/v1/members - Save a member
L'oggetto Member
Attributi
member_id
stringobbligatorioIdentificatore univoco del membro.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore univoco della struttura nel Performance Hub.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùValore dell'identificatore univoco che il partner usa per ogni sede (ad esempio "Branch ID", "Location Code", "Store Number"). Scopri di più
first_name
stringobbligatorioNome del membro.
last_name
stringobbligatorioCognome del membro.
email
stringfacoltativoIndirizzo email.
mobile_phone
stringfacoltativoNumero di cellulare in formato E.123 (ad esempio
"+1 415 555 2671").address
objectfacoltativoOggetto indirizzo fisico con le seguenti proprietà:
address_line_1(string) - Indirizzo principale (via e numero civico)address_line_2(string, optional) - Riga aggiuntiva dell'indirizzocity(string) - Nome della cittàstate(string) - Codice dello stato/della provinciapostal_code(string) - Codice postale/CAPcountry(string) - Codice paese ISO 3166-1 alpha-2 (ad esempio "AU", "US")country_name(string, optional) - Nome completo del paese
date_of_birth
stringfacoltativoData di nascita nel formato
YYYY-MM-DD.gender
stringfacoltativoUno tra
male,female,non_binary,prefer_not_to_sayeunknown.type
stringfacoltativoTipo di membro (ad esempio
staff,member,prospect).tags
arrayfacoltativoBrevi stringhe o testi di supporto per classificare e identificare membri specifici (ad esempio
["vip", "personal-training", "student"]).membership_status
stringfacoltativoStato attuale dell'abbonamento (ad esempio
active,expired,on_hold).membership_plans
arrayfacoltativoArray dei piani di abbonamento associati al membro.
profile_picture
stringfacoltativoImmagine del profilo codificata in Base64 (facoltativa).
created
stringfacoltativoTimestamp ISO 8601 della creazione del membro.
updated
stringfacoltativoTimestamp ISO 8601 dell'ultimo aggiornamento del membro.
access_time_windows
arrayfacoltativoIstantanea completa, di proprietà della fonte, delle Access Time Windows assolute e/o settimanali ricorrenti. Ometti il campo per lasciare invariata l'istantanea; invia un array vuoto con una revisione più recente per revocarla. Consulta Access Time Windows per le forme, la convalida, la mappatura degli ambiti e la semantica di sostituzione.
access_time_windows_revision
integerobbligatorio con access_time_windowsIntero non negativo, sicuro per JSON e monotonicamente crescente per questo flusso membro/fonte. Obbligatorio ogni volta che è presente
access_time_windows.
L'oggetto 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
}
]
}
Finestre temporali di accesso
Le Access Time Windows consentono a un Partner Member di avere un accesso temporaneo o ricorrente fornito da un sistema esterno. Questa pagina è la guida autorevole per i produttori di access_time_windows e access_time_windows_revision.
Le Access Time Windows sono autorizzazioni aggiuntive che possono solo consentire l'accesso. Una finestra attiva può consentire l'accesso, ma una finestra inattiva, scaduta, obsoleta o non mappata non nega un accesso già consentito da una regola ordinaria o da una concessione permanente. Restano comunque validi la disattivazione dell'utente, il blocco esplicito delle porte, la modalità di manutenzione, il geofencing, i limiti di frequenza e la disponibilità del controller.
Le implementazioni per specifici sistemi a monte sono adattatori separati. Devono convertire i propri dati di origine in questo contratto indipendente dal fornitore, senza modificare il significato dei campi.
Campi dell'istantanea del membro
access_time_windows
arrayfacoltativoL'istantanea completa delle Access Time Windows per questo membro e questa fonte partner. Un'istantanea può combinare finestre
absoluteeweekly. Ometti il campo per lasciare invariata l'istantanea salvata; invia[]per revocare tutte le finestre di proprietà di questa fonte.access_time_windows_revision
integerobbligatorio con access_time_windowsUn intero non negativo, sicuro per JSON e monotonicamente crescente per questo flusso di revisioni membro/fonte. È obbligatorio ogni volta che è presente
access_time_windowse non deve superare9007199254740991.
Ogni istantanea accetta al massimo 50 finestre. external_id, scope_key e label accettano al massimo 120 caratteri. Le finestre assolute possono coprire al massimo 90 giorni. Un giorno settimanale accetta al massimo otto blocchi non sovrapposti. I dati non validi vengono rifiutati, anziché troncati o interpretati per ipotesi.
Forme delle finestre
Una finestra assoluta identifica un unico intervallo esatto:
Richiesta mista completa
Questa richiesta sostituisce la precedente istantanea di proprietà della fonte per il membro con una finestra assoluta e una settimanale:
Regole su orari e limiti
from, to, active_from e active_until sono secondi Unix espressi come interi JSON che identificano istanti UTC:
- Invia un intero JSON senza virgolette. Stringhe numeriche, numeri in virgola mobile, stringhe RFC 3339 e millisecondi Unix vengono rifiutati.
- Ogni intervallo è semiaperto:
[from, to). L'accesso può iniziare esattamente afrome non è più attivo esattamente ato. fromdeve essere minore dito. Quando sono presenti entrambi i limiti settimanali,active_fromdeve essere minore diactive_until.- Non ricavare gli epoch da una data/ora locale senza fuso orario. Prima converti l'orario di origine in un istante UTC, poi dividi i millisecondi Unix per 1000 e verifica che il risultato sia un intero.
Fusi orari e ora legale
timezone deve essere un fuso orario IANA valido, come UTC, Australia/Perth o America/New_York. Se omesso, il valore predefinito è UTC.
- Finestre assolute:
frometoidentificano già istanti UTC esatti.timezoneè solo un metadato di visualizzazione e audit; modificarlo non sposta mai nessuno dei due istanti. - Finestre settimanali:
timezonedefinisce l'ora locale e le regole dell'ora legale usate per valutareaccess_hours. Non convertire in anticipo i blocchi settimanali in UTC. - Durante il passaggio all'ora legale, un'ora locale saltata dal fuso orario non si verifica mai.
- Durante il ritorno all'ora solare, entrambi gli istanti reali che corrispondono all'ora locale ripetuta rientrano nel blocco settimanale.
active_fromeactive_untilrestano istanti UTC anche quando una finestra settimanale usa un fuso orario diverso da UTC.
access_hours usa le chiavi minuscole da sun a sat. Ogni valore è un array di coppie [start, end] nel formato HH:mm a 24 ore con zeri iniziali. I blocchi devono essere non vuoti, ordinati e non sovrapposti. end è escluso. Un blocco non può attraversare la mezzanotte: suddividi un intervallo notturno di origine in un blocco serale il primo giorno e un blocco mattutino il giorno successivo.
ID stabili e mappatura degli ambiti
external_id deve restare stabile per tutta la durata di una finestra logica ed essere univoco all'interno dell'istantanea del membro. Mantienilo stabile quando cambiano orari o etichette, in modo che operatori e record di audit possano correlare le revisioni. Non riutilizzarlo per una finestra non correlata.
scope_key è la tua destinazione di accesso logica stabile. Il valore predefinito è default. Un amministratore della struttura mappa ogni chiave consentita a destinazioni del Performance Hub valide per l'intera struttura, per una porta o per un Ambito di accesso:
Istantanee complete e revisioni
Tratta i due campi come una partizione con versioni separate all'interno dell'upsert del Member:
| Input | Risultato |
|---|---|
access_time_windows omesso |
L'istantanea esistente resta invariata; non è richiesta alcuna revisione |
| Presente con una revisione più recente | L'intera istantanea salvata per questo membro/fonte viene sostituita |
| Stessa revisione e stesso payload normalizzato | Ripetizione idempotente; l'istantanea non cambia |
| Stessa revisione e payload normalizzato diverso | Conflitto; assegna una nuova revisione dopo la riconciliazione |
| Revisione più vecchia | L'istantanea obsoleta viene saltata; non può sovrascrivere uno stato più recente |
access_time_windows: [] con una revisione più recente |
Revoca esplicitamente tutte le finestre di proprietà della fonte |
Un'istantanea è completa, non una modifica parziale. Se la revisione 1842 contiene le finestre A e B, la revisione 1843 che contiene solo B rimuove A.
Mantieni un unico flusso di revisioni coordinato per partner/membro tra worker dei webhook, polling, ripetizioni e riconciliazione completa. È preferibile una sequenza persistente in un database. Un valore in millisecondi Unix può essere usato come revisione solo se tutti i writer si coordinano e garantiscono ordinamento e univocità rigorosi; si tratta di un valore di revisione, non di un campo epoch.
Conserva la richiesta e la revisione esatte finché non conosci la risposta dell'API. Dopo un timeout o un errore temporaneo, riprova con la stessa istantanea normalizzata e la stessa revisione. Non assegnare una nuova revisione solo perché la consegna è incerta.
Annullamento, scadenza ed errori a monte
- Annullare una finestra: recupera correttamente lo stato autorevole dalla fonte, rimuovi quella finestra e invia l'istantanea completa rimanente con una revisione più recente.
- Annullare tutte le finestre: invia
access_time_windows: []con una revisione più recente. - Lasciare scadere una finestra assoluta: smette di consentire l'accesso a
to; invia una riconciliazione successiva senza la voce scaduta per mantenere pulite le istantanee. - Terminare una finestra settimanale: rimuovila in un'istantanea più recente oppure usa
active_untilquando la fonte ha un istante di fine noto. - Il recupero dalla fonte non riesce o è incompleto: non inviare
[]e non pubblicare un'istantanea parziale. Invia un avviso e riprova il recupero. Trasformare un errore a monte in un'istantanea vuota significa revocare l'accesso involontariamente. - La richiesta alla Partner API non supera la convalida: correggi i dati e invia una revisione più recente solo se l'istantanea normalizzata cambia. Riprova gli errori temporanei con la revisione originale.
L'aggiornamento dei dati di origine si configura per ogni integrazione in base alla frequenza di consegna e di riconciliazione promessa. Prima dell'attivazione, concorda l'età massima dei dati di origine, cosa succede quando viene superata, le soglie di avviso e se gli operatori possono accettare di affidarsi solo ai limiti di ciascuna finestra. Una finestra con dati di origine obsoleti non diventa mai una regola di negazione; le regole ordinarie e le concessioni permanenti restano percorsi di riserva.
Algoritmo del produttore
Usa questo flusso indipendente dal linguaggio per ogni aggiornamento di un membro:
Elenco di controllo per la certificazione
Completa queste verifiche in una struttura di staging usando la mappatura scope_key definitiva:
- Una finestra assoluta viene accettata con il fuso orario omesso e viene valutata in UTC.
- Una finestra assoluta con fuso orario IANA personalizzato mantiene gli stessi istanti
from/to. - Una finestra settimanale con fuso orario IANA personalizzato segue l'ora locale durante il passaggio all'ora legale e il ritorno all'ora solare.
- Un'istantanea mista assoluta/settimanale sostituisce completamente l'istantanea precedente.
- L'accesso inizia esattamente a
frome termina esattamente ato; anche le fini dei blocchi settimanali sono escluse. - L'aggiornamento degli orari con lo stesso
external_ide una revisione più recente ha effetto. - L'omissione di
access_time_windowsmodifica gli altri campi del Member senza modificare le finestre. - La ripetizione della stessa revisione/dello stesso payload è idempotente.
- La stessa revisione con un payload diverso restituisce un conflitto e non modifica l'istantanea.
- Una revisione più vecchia arrivata fuori ordine viene segnalata come obsoleta e non può riportare indietro lo stato.
- Un
[]più recente revoca le finestre di proprietà della fonte; un errore di recupero a monte non invia nulla. - Uno
scope_keysconosciuto o non mappato nega l'accesso e genera un avviso visibile agli operatori. - Gli avvisi sull'età dei dati di origine e i criteri configurati per i dati obsoleti funzionano alla soglia concordata.
- I percorsi del webhook e della riconciliazione completa convergono sulla stessa istantanea e sullo stesso ordine delle revisioni.
- La consegna del flusso raggiunge Door & Gate Access entro l'obiettivo concordato.
- Una finestra attiva può consentire l'accesso alla porta fisica mappata, ma non può aggirare la disattivazione dell'utente,
blockAllAccess, la manutenzione o il geofencing. - Prima, al di fuori e dopo una finestra, le regole ordinarie e le concessioni permanenti continuano a consentire l'accesso agli utenti che ne hanno comunque diritto.
Indicazioni correlate
{
"external_id": "access-4b1782",
"kind": "absolute",
"from": 1792053000,
"to": 1792058400,
"timezone": "Australia/Perth",
"scope_key": "after_hours_entry",
"label": "Temporary site access"
}
I campi obbligatori sono external_id, kind, from e to. timezone, scope_key e label sono facoltativi.
Una finestra settimanale identifica intervalli ricorrenti in ora locale, eventualmente delimitati da istanti 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"
}
I campi obbligatori sono external_id, kind e access_hours. timezone, active_from, active_until, scope_key e label sono facoltativi.
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"
}
]
}
]
}'
Usa facility_id oppure linking_identifier in base al metodo di collegamento configurato. Non inviarli entrambi.
Conversione in epoch
2026-10-15T08:30:00Z diventa 1792053000:
UTC instant Unix milliseconds Unix seconds sent
2026-10-15T08:30:00Z 1792053000000 1792053000
Conversione indipendente dal linguaggio:
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
Se la fonte ha una precisione inferiore al secondo, definisci una regola di arrotondamento intenzionale per inizio e fine prima dei test di integrazione. Non passare mai millisecondi affidandoti all'API per dedurre l'unità.
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
I partner non inviano ID di strutture, porte o Ambiti di accesso del Performance Hub all'interno di una finestra. Uno scope_key sconosciuto, disattivato o non mappato nega l'accesso per quella finestra; non amplia l'accesso. Concorda e testa le mappature prima del lancio.
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)
Vettori di test minimi
[
{
"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."
}
]
Invia anche vettori negativi per millisecondi Unix, stringhe numeriche, numeri in virgola mobile, fusi IANA non validi, from >= to, external_id duplicati, blocchi sovrapposti, blocchi notturni, più di otto blocchi in un giorno, più di 50 finestre e chiavi di ambito non mappate.
Salvare un membro
Crea o aggiorna i record dei membri. L'API stabilisce se creare o aggiornare in base al member_id.
Parametri
members
arrayobbligatorioArray di oggetti Member da salvare. Massimo consigliato: 1000 elementi per richiesta, per prestazioni ottimali. L'API suddivide automaticamente gli elementi in batch per l'elaborazione. Ogni elemento deve includere
facility_id(obbligatorio se non usilinking_identifier) oppurelinking_identifier(obbligatorio se non usifacility_id).Quando un membro include
access_time_windows, deve includere ancheaccess_time_windows_revision. L'array è un'istantanea completa della fonte, non una modifica parziale. Omettilo per mantenere l'istantanea esistente oppure invia[]con una revisione più recente per revocare tutte le finestre di proprietà della fonte. Leggi la guida alle Access Time Windows prima di attivare questo campo.
Valore restituito
Restituisce un semplice messaggio di conferma dell'operazione di sincronizzazione.
I campi del profilo del membro restano normali upsert anche quando un'istantanea delle finestre viene segnalata come ripetizione idempotente o come obsoleta e saltata. Un'istantanea in conflitto, con la stessa revisione e un payload diverso, non può essere ripetuta senza modifiche: riconcilia lo stato della fonte e invia una revisione più recente.
Richiesta
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
}
]
}
]
}'
Risposta
Restituisce un messaggio di esito positivo con i metadati dell'operazione di sincronizzazione.
{
"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"
}
]
}
}
Campi dei metadati:
- success - Numero di membri elaborati correttamente
- skipped - Numero di membri saltati (se presenti)
- skipped_items - Array dei membri saltati con i relativi motivi (se presenti)
- dry-run - Flag booleano presente se usi il tipo di chiave dryrun (se applicabile)
Check-in
Rappresenta la registrazione della presenza di una persona in una struttura, a una lezione o a un'attività. Viene usato per monitorare le presenze, per le analisi di utilizzo e per migliorare l'accuratezza del rilevamento visivo.
Endpoint
POST /partner/v1/check-ins - Save check-ins
L'oggetto Check-In
Attributi
check_in_id
stringfacoltativoIdentificatore univoco del check-in. Facoltativo: se non viene fornito, viene generato automaticamente dalla coppia
member_idetimestamp.member_id
stringobbligatorioIdentificatore univoco del membro.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore univoco della struttura nel Performance Hub.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùValore dell'identificatore univoco che il partner usa per ogni sede (ad esempio "Branch ID", "Location Code", "Store Number"). Scopri di più
check_in_type
stringfacoltativoTipo di visita. Uno tra
member,class,staff,guestetrial.source
stringfacoltativoModalità di acquisizione del check-in. I valori comuni includono
manual,tag,rfid,kiosk,app. Si possono usare anche altri valori, comedoor_readerobooking.class_id
stringfacoltativoFacoltativo. Da usare se il check-in è legato a una prenotazione o alla presenza a una lezione.
timestamp
stringobbligatorioTimestamp in formato ISO 8601 del momento in cui è avvenuto il check-in.
L'oggetto 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"
}
Salvare i check-in
Crea record di check-in. L'API rimuove automaticamente i duplicati in base a membro, struttura e timestamp.
Parametri
check_ins
arrayobbligatorioArray di oggetti Check-In da salvare. Massimo consigliato: 1000 elementi per richiesta, per prestazioni ottimali. L'API suddivide automaticamente gli elementi in batch per l'elaborazione. Ogni elemento deve includere
facility_id(obbligatorio se non usilinking_identifier) oppurelinking_identifier(obbligatorio se non usifacility_id).
Valore restituito
Restituisce un semplice messaggio di conferma dell'operazione di sincronizzazione.
Richiesta
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"
}
]
}'
Risposta
Restituisce un messaggio di esito positivo con i metadati dell'operazione di sincronizzazione.
{
"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"
}
]
}
}
Campi dei metadati:
- success - Numero di check-in elaborati correttamente
- skipped - Numero di check-in saltati (se presenti)
- skipped_items - Array dei check-in saltati con i relativi motivi (se presenti)
- dry-run - Flag booleano presente se usi il tipo di chiave dryrun (se applicabile)
Controllo degli accessi
La Partner API può attivare l'hardware Door/Gate Controller del Performance Hub nelle strutture in cui la tua integrazione è attivata.
Usa questa API quando il tuo sistema di gestione dei membri ha già deciso che una persona può entrare. Il Performance Hub non valuta lo stato dell'abbonamento, gli orari di accesso, le regole delle zone delle porte, i controlli antifrode o la logica di sospensione. Il tuo sistema resta l'autorità per queste decisioni.
La richiesta di sblocco è sincrona. Il Performance Hub invia il comando al controller in loco in tempo reale e restituisce 200 solo dopo che il dispositivo ha confermato che il relè si è fisicamente sbloccato. La maggior parte delle conferme dovrebbe arrivare entro 3-5 secondi. Se non riceve alcuna conferma entro il tempo limite, l'API restituisce un errore esplicito.
Puoi anche registrare un tentativo di accesso o un rifiuto che non ha mai raggiunto il controller. Questa chiamata non sblocca la porta, ma scrive un evento nei Registri di accesso di 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
L'oggetto Door/Gate Controller
Attributi
door_id
stringobbligatorioIdentificatore univoco del Door/Gate Controller. Salvalo nel tuo sistema dopo il rilevamento e usalo quando chiami l'endpoint di sblocco.
facility_id
stringobbligatorioID della struttura nel Performance Hub.
linking_identifier
stringfacoltativoIdentificatore della struttura del partner, quando la tua integrazione usa gli identificatori di collegamento. Scopri di più
name
stringobbligatorioNome leggibile del dispositivo configurato nel Performance Hub.
zone
stringfacoltativoZona o posizione della porta, ad esempio
Entrance.status
stringobbligatorioonlineooffline.relay_state
stringfacoltativoUltimo stato noto del relè, ad esempio
lockedounlocked.maintenance_mode
stringobbligatorioModalità di manutenzione attuale. Uno tra
off,force-openeforce-closed.hold_time_seconds
integerobbligatorioTempo di mantenimento predefinito dello sblocco configurato per la porta.
last_seen
stringfacoltativoTimestamp ISO dell'ultimo aggiornamento dei metadati del dispositivo.
L'oggetto 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"
}
Elencare i Door/Gate Controller
Restituisce i Door/Gate Controller disponibili per la tua integrazione.
Se non viene fornito né facility_id né linking_identifier, l'API restituisce i Door/Gate Controller di tutte le strutture collegate al tuo account partner.
Parametri
facility_id
stringfacoltativo in alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùID della struttura nel Performance Hub. Usalo per le integrazioni con collegamento diretto.
linking_identifier
stringfacoltativo in alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIl tuo identificatore di struttura/sede. Usalo quando la tua integrazione è configurata per gli identificatori di collegamento.
Valore restituito
Restituisce un array di oggetti Door/Gate Controller.
Richiesta
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:
Risposta
{
"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"
}
]
}
Ottenere lo stato di un Door/Gate Controller
Recupera l'ultimo stato noto e la configurazione di base di un singolo Door/Gate Controller.
Indica un identificatore della struttura, in modo che il Performance Hub possa verificare che la porta appartenga a una struttura a cui la tua integrazione ha accesso.
Parametri
door_id
stringobbligatorioID del Door/Gate Controller restituito dall'endpoint di elenco.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùID della struttura nel Performance Hub. Obbligatorio per le integrazioni con collegamento diretto.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore della struttura del partner. Obbligatorio per le integrazioni con identificatore di collegamento.
Valore restituito
Restituisce un oggetto Door/Gate Controller.
Richiesta
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:
Risposta
{
"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"
}
}
Sbloccare un Door/Gate Controller
Invia un comando di sblocco al Door/Gate Controller e attende che il relè fisico confermi lo sblocco.
Il tuo sistema deve decidere se la persona è autorizzata prima di chiamare questo endpoint. Il Performance Hub verifica solo la chiave partner, l'accesso alla struttura, l'appartenenza della porta e lo stato del dispositivo.
Parametri
door_id
stringobbligatorioID del Door/Gate Controller restituito dall'endpoint di elenco.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùID della struttura nel Performance Hub. Obbligatorio per le integrazioni con collegamento diretto.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore della struttura del partner. Obbligatorio per le integrazioni con identificatore di collegamento.
member_id
stringobbligatorioID del membro nel sistema del partner. Viene usato per la registrazione di audit e per il successivo collegamento dei dati.
first_name
stringobbligatorioNome della persona che apre la porta.
last_name
stringobbligatorioCognome della persona che apre la porta.
full_name
stringfacoltativoFacoltativo. Se omesso, il Performance Hub combina
first_nameelast_name.check_in_id
stringfacoltativoID facoltativo del check-in nel tuo sistema, per la correlazione.
idempotency_key
stringfacoltativoChiave facoltativa di protezione dalla ripetizione. Riutilizzando la stessa chiave per lo stesso partner, la stessa struttura e la stessa porta si ottiene il risultato esistente, se disponibile.
Valore restituito
Restituisce 200 solo quando il dispositivo conferma che il relè si è fisicamente sbloccato. La porta usa il tempo di mantenimento configurato in Gestione dei dispositivi del Performance Hub; i partner non possono modificare i tempi del relè per singola richiesta. La maggior parte delle conferme dovrebbe arrivare entro 3-5 secondi. Considera il timeout documentato come uno sblocco esplicitamente non riuscito e ripeti il tentativo solo secondo le tue regole di sicurezza.
Errori comuni:
403 integration_not_enabled- la tua integrazione non è attivata per la struttura.409 maintenance_mode_active- il personale della struttura ha attivato la modalità di manutenzione per la porta.503 device_offline- il Door/Gate Controller è offline o non aggiornato.504 unlock_confirmation_timeout- il comando è stato inviato, ma non è stata ricevuta alcuna conferma corrispondente prima del timeout.
Richiesta
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"
}'
Risposta
{
"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"
}
Risposta di errore
{
"status": "failed",
"reason": "device_offline",
"door_id": "00000000000000000000000000000007",
"facility_id": "550e8400-e29b-41d4-a716-446655440000",
"event_id": "00000000-0000-0000-0000-000000000045"
}
Registrare un tentativo di accesso o un rifiuto
Registra un tentativo di accesso o un rifiuto già deciso dal tuo sistema. Il Door/Gate Controller non viene contattato e la porta non si sblocca.
Usa questa chiamata quando il tuo sistema rifiuta l'ingresso o quando un tentativo deve comparire nei Registri di accesso di Door & Gate Access senza uno sblocco. Il Performance Hub non valuta lo stato dell'abbonamento, gli orari di accesso o altre regole di accesso.
Un evento rifiutato compare nei Registri di accesso di Door & Gate Access con l'esito Denied, il nome del tuo partner, la porta, l'identificatore del membro se lo invii e il codice del motivo in forma leggibile. Ad esempio, membership_expired viene mostrato come "Membership Expired". reason_display_text e user_email vengono salvati con l'evento.
Parametri
door_id
stringobbligatorioID del Door/Gate Controller restituito dall'endpoint di elenco.
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùID della struttura nel Performance Hub. Obbligatorio per le integrazioni con collegamento diretto.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore della struttura del partner. Obbligatorio per le integrazioni con identificatore di collegamento.
outcome
stringobbligatoriodeniedoattempted.reason
stringfacoltativoCodice del motivo in snake_case minuscolo, fino a 64 caratteri. Obbligatorio quando
outcomeèdenied. Esempio:membership_expired.reason_display_text
stringfacoltativoMotivo in forma leggibile, fino a 256 caratteri. Esempio:
Membership expired on 2026-04-01.member_id
stringfacoltativoID del membro nel sistema del partner. Omettilo quando la credenziale non corrisponde a nessun membro, ad esempio nel caso di una tessera sconosciuta.
user_email
stringfacoltativoEmail della persona che ha tentato l'accesso.
timestamp
stringfacoltativoMomento in cui è avvenuto il tentativo, in formato ISO 8601 con fuso orario. Esempio:
2026-05-18T10:15:30Z. Il valore predefinito è l'ora di ricezione della richiesta. Non può essere più di 5 minuti nel futuro né più vecchio di 30 giorni.idempotency_key
stringfacoltativoChiave di protezione dalla ripetizione, fino a 128 caratteri. Riutilizzando la stessa chiave per lo stesso partner, la stessa struttura e la stessa porta si ottiene il risultato originale.
Valore restituito
Restituisce 201 quando l'evento viene registrato. Ripetendo la richiesta con la stessa idempotency_key si ottiene 200 con idempotent impostato su true e non viene creato un altro evento.
Una chiave dry-run restituisce 200 con dry_run impostato su true. Non viene registrato nulla.
Errori comuni:
400- il corpo non è valido, un rifiuto non ha unreason, il timestamp è fuori intervallo oppurefacility_id/linking_identifiernon corrisponde a una struttura collegata.403- la chiave è di sola lettura.403 integration_not_enabled- la tua integrazione non è attivata per la struttura.messageindica il motivo.404- il Door/Gate Controller non è stato trovato per la struttura collegata.
Richiesta
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"
}'
Risposta
{
"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"
}
Ripetizione idempotente
{
"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
}
Report delle strutture
Un record puntuale che raccoglie le principali metriche operative e finanziarie di una struttura in un periodo specifico.
Endpoint
POST /partner/v1/report-snapshots - Save report snapshots
L'oggetto Report Snapshot
Attributi
facility_id
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùIdentificatore univoco della struttura nel Performance Hub.
linking_identifier
stringin alternativaIndica il tipo di identificatore della struttura configurato per la tua integrazione: usa facility_id per le integrazioni con collegamento diretto oppure linking_identifier per le integrazioni con identificatore di collegamento. Non inviarli entrambi: l'API usa il tipo di identificatore configurato per il tuo account partner e ignora l'altro. Scopri di piùValore dell'identificatore univoco che il partner usa per ogni sede (ad esempio "Branch ID", "Location Code", "Store Number"). Scopri di più
start_date
stringobbligatorioData di inizio del periodo dell'istantanea nel formato
YYYY-MM-DD.end_date
stringobbligatorioData di fine del periodo dell'istantanea nel formato
YYYY-MM-DD.metrics
objectobbligatorioOggetto delle metriche, con i dati sui membri e sui ricavi del periodo.
L'oggetto 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"
}
}
}
Salvare le istantanee dei report
Invia le metriche operative e finanziarie di una struttura per un periodo specifico.
Parametri
snapshots
arrayobbligatorioArray di oggetti Report Snapshot da salvare. Massimo 25 elementi per richiesta. Ogni elemento deve includere
facility_id(obbligatorio se non usilinking_identifier) oppurelinking_identifier(obbligatorio se non usifacility_id).
Valore restituito
Restituisce un semplice messaggio di conferma dell'operazione di sincronizzazione.
Richiesta
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"
}
}
}
]
}'
Risposta
{
"message": "Report snapshot sync successful."
}
Errori
La Partner API usa codici di stato HTTP standard e corpi di risposta JSON per spiegare perché una richiesta non è riuscita.
Struttura della risposta di errore
La maggior parte degli errori dell'API restituisce un corpo JSON con un messaggio e, dove disponibili, dettagli strutturati.
Codici di stato
Errori delle Access Time Windows
La convalida delle finestre non riesce prima che l'istantanea non valida venga scritta. Le cause comuni per cui non ha senso riprovare includono:
access_time_windows_revisionmancante quandoaccess_time_windowsè presente.- Valori epoch di tipo stringa, a virgola mobile o probabilmente espressi in millisecondi.
- Un fuso orario IANA non valido, un intervallo invertito, un
external_idduplicato, blocchi settimanali sovrapposti o un blocco notturno non suddiviso. - Un valore al di fuori dei limiti documentati di numero, lunghezza o durata.
Una revisione ripetuta con un contenuto normalizzato diverso genera un 409 Conflict. Esegui la riconciliazione con lo stato autorevole più recente e assegna una revisione più nuova; non continuare a riprovare la coppia in conflitto. Una revisione più vecchia viene segnalata come istantanea obsoleta saltata, invece di poter sovrascrivere uno stato più recente. Uno scope_key sconosciuto o non mappato nega l'autorizzazione per impostazione predefinita e va trattato come un avviso di configurazione.
Se la consegna va in timeout o riceve un 5xx temporaneo, riprova con la stessa identica istantanea normalizzata e la stessa revisione. Se il recupero dalla fonte a monte non è riuscito, ometti completamente il campo delle finestre; non sostituirlo mai con un array vuoto.
Indicazioni sui nuovi tentativi
Riprova questi errori con un backoff esponenziale e un numero limitato di tentativi:
429500502503504
Non riprovare questi errori alla cieca:
400401403404409422
Per il controllo degli accessi, considera sempre le risposte di timeout e offline come sblocchi non riusciti, a meno che le tue regole di accesso e i tuoi processi di sicurezza non stabiliscano diversamente.
Dettagli da includere per l'assistenza
Quando contatti l'assistenza, includi:
- Endpoint e metodo HTTP.
- Data, ora e fuso orario.
- ID della chiave partner, non la chiave segreta.
- Identificatore della struttura usato.
- ID del record di origine nel tuo sistema.
- Stato e corpo della risposta.
event_idocommand_id, se disponibili.
{
"success": false,
"message": "Request body.members[0].member_id is required"
}
Alcuni endpoint specifici di un dominio restituiscono uno stato e un motivo espliciti. Ad esempio, gli errori del controllo degli accessi includono campi come reason, door_id, facility_id ed 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
La richiesta non è formata correttamente o mancano campi obbligatori. Correggi la richiesta prima di riprovare.
401 Unauthorized
L'autenticazione non è riuscita. Verifica di usare HTTP Basic Auth con la tua chiave segreta API come nome utente e una password vuota.
403 Forbidden
La chiave è valida, ma l'operazione non è consentita. Le cause comuni includono l'uso di una chiave di sola lettura per un'operazione di scrittura o il tentativo di accedere a una struttura in cui la tua integrazione non è attivata.
404 Not Found
La risorsa richiesta non è stata trovata o non è disponibile per la tua integrazione.
409 Conflict
La richiesta è in conflitto con lo stato attuale della risorsa. Nel controllo degli accessi, ad esempio, un Door/Gate Controller può trovarsi in modalità di manutenzione.
422 Unprocessable Entity
La richiesta è un JSON valido, ma non supera la convalida semantica. Correggi i dati prima di riprovare.
429 Too Many Requests
L'integrazione ha superato il limite di frequenza documentato. Riprova con un backoff esponenziale.
500 Internal Server Error
Il Performance Hub non è riuscito a completare la richiesta a causa di un errore interno. Riprova con un backoff. Se il problema persiste, contatta l'assistenza indicando l'endpoint, il timestamp e il corpo della risposta.
503 Service Unavailable
Un servizio o un dispositivo da cui dipende la richiesta non è disponibile. Per gli sblocchi dei Door/Gate Controller, può significare che il controller è offline.
504 Gateway Timeout
L'operazione è scaduta. Per gli sblocchi dei Door/Gate Controller, significa che lo sblocco non è stato confermato entro il tempo limite.
Controllo delle versioni
La versione della Partner API è indicata nell'URL. La versione attuale è:
Criteri per le modifiche
Il Performance Hub cerca di apportare, ove possibile, modifiche aggiuntive e retrocompatibili.
Esempi di modifiche retrocompatibili:
- Aggiunta di un nuovo campo facoltativo a una richiesta.
- Aggiunta di un nuovo campo a una risposta.
- Aggiunta di un nuovo endpoint.
- Aggiunta di un nuovo valore enum, quando ci si aspetta che i client gestiscano valori sconosciuti.
- Miglioramento dei messaggi di convalida senza modificare il contratto dei codici di stato.
access_time_windows e access_time_windows_revision sono campi aggiuntivi della richiesta Member. I client esistenti che li omettono lasciano invariata l'istantanea delle Access Time Windows salvata. Questa regola sull'omissione preserva la compatibilità con gli upsert parziali; omettere i campi non equivale a inviare un array vuoto.
Esempi di modifiche non retrocompatibili:
- Rimozione o ridenominazione di un campo.
- Modifica del tipo di un campo.
- Trasformazione di un campo facoltativo della richiesta in obbligatorio.
- Rimozione di un endpoint.
- Modifica del significato di un codice di stato esistente o di un
reasonspecifico di un dominio.
Deprecazioni
Quando è necessaria una modifica non retrocompatibile, il Performance Hub eviterà, ove possibile, di modificare direttamente la versione esistente. Introdurremo invece una nuova versione o un percorso di migrazione e comunicheremo la modifica ai partner interessati.
Gli avvisi di deprecazione possono includere:
- Una voce nel registro delle modifiche.
- Comunicazioni dirette ai partner.
- Note nella Partner Console.
- Indicazioni per la migrazione nella documentazione.
Consigli per i client
Crea client che tollerino le modifiche aggiuntive:
- Ignora i campi della risposta che non usi.
- Tratta i valori enum sconosciuti come non supportati, invece di generare un arresto anomalo.
- Evita controlli rigorosi di uguaglianza sulle risposte.
- Registra i valori non riconosciuti, così da poter aggiornare la tua integrazione in modo consapevole.
Per le partizioni Member con revisioni, come le Access Time Windows, conserva la revisione inviata e il payload normalizzato finché non conosci l'esito. Riutilizzare una revisione per un contenuto modificato genera un conflitto, mentre ripetere lo stesso contenuto è idempotente. Consulta Access Time Windows.
Specifiche OpenAPI
Usa le specifiche OpenAPI pubblicate per generare client, convalidare le richieste e monitorare nel tempo le modifiche alla struttura dell'API.
Consulta Specifiche OpenAPI.
https://partner-api.performancehub.co/partner/v1/
Registro delle modifiche
Questo registro delle modifiche riporta le modifiche rilevanti alla Partner API e alla Partner Console che influiscono sul comportamento delle integrazioni.
2026-09-09
2026-05-06
2026-05-01
Categorie di modifica
Le voci future usano queste categorie:
- Aggiunte - nuovo endpoint, campo, guida o funzionalità.
- Modifiche - comportamento o documentazione modificati senza rimuovere il supporto.
- Deprecazioni - la funzionalità resta disponibile, ma è previsto un percorso di migrazione.
- Rimozioni - funzionalità o endpoint rimossi.
- Correzioni - correzione di bug o della documentazione.
- Sicurezza - modifiche ad autenticazione, autorizzazione, gestione dei dati o gestione delle chiavi.
Aggiunte
- Aggiunte le istantanee
access_time_windowsdei membri, indipendenti dal fornitore, con finestre assolute e settimanali ricorrenti combinate. - Aggiunta la semantica di ordinamento tramite
access_time_windows_revision, ripetizione idempotente, conflitto, salto dei dati obsoleti e revoca esplicita. - Aggiunte le indicazioni su fusi orari IANA, ora legale, mappatura logica di
scope_key, aggiornamento dei dati di origine, implementazione per i produttori e certificazione.
Aggiunte
- Aggiunta la documentazione del programma partner, che copre tipi di partner, onboarding, best practice, preparazione al go-live, errori, controllo delle versioni e assistenza.
- Aggiunto un flusso dedicato di richiesta Become a Partner per i potenziali partner tecnici e commerciali.
- Aggiunta la documentazione su come le integrazioni partner approvate compaiono nella directory dei partner del Performance Hub, all'interno della piattaforma principale del Performance Hub.
Aggiunte
- Aggiunta la documentazione sul controllo degli accessi dei Door/Gate Controller, comprese le operazioni di elenco, stato e sblocco.
- Aggiunta la documentazione sul comportamento dello sblocco sincrono: l'API restituisce un esito positivo solo dopo che il controller in loco ha confermato che il relè si è fisicamente sbloccato.
- Aggiunta la documentazione sul supporto della
idempotency_keyfacoltativa per le richieste di sblocco dei Door/Gate Controller.