Introducción
La Partner API del Performance Hub permite que las plataformas de socios externas se integren sin problemas con los módulos principales del Performance Hub. La API admite visión artificial, análisis, registro del acceso de los miembros e información sobre las instalaciones.
Formato de las solicitudes
La API acepta cuerpos de solicitud codificados en JSON y devuelve respuestas codificadas en JSON.
Limitación de frecuencia
Para garantizar un uso justo y la estabilidad del sistema, las cuentas de la Partner API empiezan con estos límites predeterminados:
- 5 solicitudes por segundo por endpoint
- Recomendado: 1000 elementos como máximo por solicitud por lotes para un rendimiento óptimo
- 10MB como máximo de tamaño de la carga útil
Los límites de frecuencia se pueden ajustar y tu administrador de cuenta de socio del Performance Hub puede configurarlos caso por caso. Si tu integración necesita más rendimiento para el lanzamiento, las migraciones, las cargas retroactivas de informes o las instalaciones de gran volumen, plantéalo durante la incorporación o antes de la ventana de cambio prevista.
URL base
https://partner-api.performancehub.co/partner/v1/
Autenticación
Para acceder a la Partner API, es necesario autenticarse con claves secretas de API. Genera y administra tus claves desde la Partner Console.
Las claves de API son tus credenciales para acceder a los recursos de socios. Cada clave tiene acceso restringido a datos específicos de la organización y se puede desactivar al instante cuando sea necesario.
Trata tus claves de API con cuidado: ¡proporcionan acceso completo a tu cuenta! Nunca expongas estas claves en repositorios públicos, aplicaciones del lado del cliente ni en ningún lugar donde puedan quedar comprometidas.
Autentica las solicitudes con HTTP Basic Auth y pasa tu clave de API como nombre de usuario. Deja la contraseña vacía.
La API solo acepta conexiones HTTPS seguras. Se rechazan las solicitudes HTTP sin cifrar, al igual que cualquier solicitud que no incluya credenciales de autenticación válidas.
Solicitud de ejemplo
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.
Verificar la clave secreta
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>" }
Lista de comprobación para la puesta en producción
Usa esta lista de comprobación antes de habilitar una integración de socio para instalaciones en producción.
Configuración de la Partner Console
- Tu perfil de socio está completo.
- La URL del logotipo, el sitio web, la categoría y la descripción son correctos.
- El método de vinculación de datos está configurado: Direct Link o Linking Identifier.
- La vinculación de instalaciones se probó con al menos una instalación real.
- Se usa el tipo de clave adecuado:
- Dryrun para pruebas de escritura no destructivas.
- Read-only para consumir datos de forma segura.
- Live solo cuando estés listo para afectar los datos de producción.
Autenticación y administración de claves
- Las claves secretas se guardan solo en el servidor.
- Las claves no están incrustadas en aplicaciones del lado del cliente, aplicaciones móviles, repositorios públicos ni tickets de soporte.
- Se probaron la rotación y la revocación de claves.
- Tu equipo sabe qué clave usa cada entorno.
Validación de datos
- Los campos obligatorios están presentes en cada endpoint al que llamas.
- Los identificadores de instalación coinciden con el método de vinculación configurado.
- Los ID de tu sistema son estables y no cambian entre sincronizaciones.
- Las importaciones grandes se dividen en lotes que respetan los límites documentados.
- Los elementos de lote fallidos se pueden identificar y volver a enviar.
Pruebas de endpoints
Antes del lanzamiento, prueba todos los endpoints de los que depende tu integración:
- Se pueden leer las organizaciones y las instalaciones.
- Se pueden guardar y actualizar miembros.
- Los planes de membresía, las zonas de acceso y los horarios de acceso se sincronizan correctamente.
- Los registros de entrada se aceptan y se pueden relacionar con tu sistema.
- Las instantáneas de informes usan el período de informe y las métricas previstos.
- Los flujos del controlador de puertas y portones se prueban con hardware real, cuando corresponde.
Preparación de Access Time Windows
Si la integración proporciona Access Time Windows:
- Los ejemplos absolutos y semanales superan la lista de comprobación de certificación del productor.
- Las épocas son segundos Unix enteros sin comillas; se probaron los límites exactos
[from, to). - Se verificaron los valores predeterminados en UTC, las zonas horarias IANA personalizadas de la integración y los cambios de horario de verano pertinentes.
- Una única secuencia de revisiones duradera y monótona por miembro y fuente coordina las actualizaciones incrementales, la conciliación y los reintentos.
- Los operadores entienden el comportamiento de los valores omitidos, el reemplazo completo, las repeticiones idempotentes, los conflictos, los datos obsoletos y el
[]explícito. - Cada
scope_key, incluidodefault, tiene una asignación aprobada en el Performance Hub; se probó que las claves desconocidas deniegan el acceso. - Están configurados la frecuencia de actualización prevista de la integración, la antigüedad máxima de la fuente, el comportamiento ante fuentes obsoletas y las alertas.
- Se comprobó que un error en la consulta a la fuente de origen no emite una instantánea vacía ni parcial.
- La convergencia de la secuencia en el entorno de pruebas, la cancelación o revocación y los límites de inicio y fin en las puertas físicas cumplen los objetivos acordados.
- Se verificaron las reglas habituales y los permisos permanentes como vías alternativas, y las ventanas no pueden omitir la desactivación del usuario,
blockAllAccess, el mantenimiento ni la geovalla.
Preparación del control de acceso
En las integraciones de control de acceso:
- Tu sistema toma la decisión de acceso antes de llamar al Performance Hub.
- La integración gestiona
device_offline,maintenance_mode_activeyunlock_confirmation_timeout. - Los operadores entienden que un tiempo de espera agotado significa que el desbloqueo no se confirmó.
- Tus registros guardan el
event_idy elcommand_iddevueltos. - Tienes un proceso alternativo manual para el personal de la instalación.
Gestión de errores y reintentos
- Las respuestas
400,401,403,404,409y422se muestran a los operadores o a los equipos de soporte en lugar de reintentarse a ciegas. - Las respuestas
429,500,502,503y504usan una lógica de reintento acotada con retroceso. - Los errores repetidos generan una alerta en tu sistema.
- La integración nunca descarta registros fallidos de forma silenciosa.
Observabilidad
- Tus registros incluyen el endpoint, la marca de tiempo, el identificador de instalación, el ID del registro de origen, el resultado de la solicitud y el cuerpo de la respuesta.
- Tu equipo de soporte puede buscar por ID de miembro, ID de instalación, ID de registro de entrada o ID de evento de desbloqueo.
- Tienes una forma de repetir o conciliar las sincronizaciones fallidas.
Lanzamiento en producción
- El Performance Hub confirmó tu acceso a producción.
- Al menos una instalación de producción habilitó tu integración.
- Tu clave de producción está activa.
- Tus contactos operativos y técnicos están actualizados.
- Tu proceso de soporte está documentado para los clientes.
Una vez completadas estas comprobaciones, tu integración configurada aparecerá en el directorio de socios del Performance Hub, dentro de la plataforma principal del Performance Hub.
Prácticas recomendadas
Usa estos patrones para que las integraciones de socios sean predecibles, observables y seguras para las instalaciones.
Identifica las instalaciones de forma coherente
Elige el método de vinculación configurado para tu cuenta de socio y úsalo de forma coherente:
- Direct Link: usa el
facility_iddel Performance Hub que devuelve el endpoint de instalaciones. - Linking Identifier: usa tu propio identificador de ubicación, como un ID de sucursal, un código de ubicación o un número de tienda.
No envíes ambos identificadores en la misma solicitud. El Performance Hub resuelve las solicitudes con el método de vinculación configurado para tu cuenta de socio.
Consulta Métodos de vinculación de socios para obtener instrucciones de configuración.
Escribe por lotes con cuidado
La Partner API acepta cuerpos de solicitud JSON y está diseñada para flujos de sincronización por lotes, donde así se documenta. Mantén los lotes acotados y reintentables.
Pautas predeterminadas:
- Usa hasta 1000 elementos por solicitud por lotes para un rendimiento óptimo.
- Mantén las cargas útiles por debajo de 10MB.
- No superes 5 solicitudes por segundo por endpoint.
Los límites de frecuencia se pueden ajustar y tu administrador de cuenta de socio del Performance Hub puede configurarlos caso por caso. Si prevés importaciones de gran volumen, tráfico de lanzamiento o cargas retroactivas de informes, acuerda el rendimiento necesario antes de la ventana de cambio.
Si necesitas sincronizar un conjunto de datos grande, divídelo en fragmentos deterministas y registra el ID de cada fragmento en tu sistema. Así es más fácil analizar los reintentos fallidos.
Reintenta de forma segura
Usa el retroceso exponencial para los errores transitorios, como 429, 500, 502, 503 y 504.
Evita los bucles de reintento rápidos. Un buen punto de partida es:
- Reintentar después de 1 segundo.
- Reintentar después de 2 segundos.
- Reintentar después de 4 segundos.
- Detenerse y emitir una alerta si la operación sigue fallando.
En los errores de validación, como 400 o 422, corrige la solicitud antes de reintentar.
Usa la idempotencia donde se admita
El endpoint de desbloqueo del controlador de puertas y portones admite una idempotency_key opcional. Si reutilizas la misma clave para el mismo socio, la misma instalación y la misma puerta, se devuelve el resultado existente cuando hay uno disponible.
Usa una clave estable para la acción que se realiza, por ejemplo, un ID de registro de entrada o un ID de evento de acceso de tu sistema.
No supongas que todos los endpoints de escritura admiten la idempotencia, a menos que esté documentado para ese endpoint.
Mantén limpios los datos de origen
Envía valores estables y normalizados siempre que sea posible:
- Usa ID coherentes de miembros, planes, instalaciones y registros de entrada de tu sistema de origen.
- Usa marcas de tiempo ISO 8601 para las fechas y horas.
- Envía los números de teléfono en formato internacional, si están disponibles.
- Envía las monedas con los campos documentados para cada endpoint.
- Evita sobrecargar los campos de texto libre con datos que corresponden a campos estructurados.
Diseña para sincronizaciones incrementales y completas
La mayoría de las integraciones de socios necesitan ambas:
- Sincronizaciones incrementales para los cambios del día a día.
- Sincronizaciones completas de conciliación para corregir eventos perdidos, importaciones históricas o desviaciones de datos.
Tu integración debe poder reenviar el estado actual de un miembro, un plan de membresía o una instantánea de informe sin depender de que una solicitud anterior se haya completado correctamente.
Publica las Access Time Windows de forma segura
Trata el valor access_time_windows de cada miembro como una instantánea completa con revisiones independientes:
- Coordina una única secuencia de
access_time_windows_revisionmonótonamente creciente entre los procesos incrementales y los de conciliación. - Reintenta una entrega incierta o transitoria con la misma revisión y la misma carga útil normalizada.
- Omite
access_time_windowscuando no lo estés actualizando. - Envía
[]solo después de que una consulta correcta a la fuente autorizada demuestre que no queda ninguna ventana. Nunca conviertas un tiempo de espera agotado, un resultado parcial o un error de análisis de la fuente en una revocación. - Mantén estables
external_idyscope_key, y certifica cada asignación de ámbito antes de pasar a producción. - Supervisa la antigüedad de la fuente con respecto a la política de actualización acordada para esa integración.
Consulta la guía oficial para productores de Access Time Windows para conocer las instantáneas completas, las zonas horarias, el horario de verano, la cancelación y los vectores de prueba.
Trata el control de acceso como algo crítico para la seguridad
En los desbloqueos de controladores de puertas y portones:
- Tu sistema debe decidir si la persona puede entrar antes de llamar al Performance Hub.
- El Performance Hub devuelve
200solo después de que el controlador del sitio confirma que el relé se desbloqueó físicamente. - La mayoría de las confirmaciones se completan en 3-5 segundos.
- Un tiempo de espera agotado es un desbloqueo fallido explícito, no un éxito en segundo plano.
- Reintenta solo según tus propias reglas de acceso y seguridad.
Registra siempre el event_id y el command_id que devuelve el endpoint de desbloqueo.
Supervisa tu integración
Usa los registros de solicitudes de la Partner Console durante el desarrollo y el lanzamiento. En producción, mantén también tus propios registros con:
- Marca de tiempo de la solicitud.
- Endpoint.
- ID del registro de origen.
- Identificador de instalación.
- Código de estado HTTP.
- Cuerpo de la respuesta o mensaje de error del Performance Hub.
Estos campos agilizan mucho el soporte y la conciliación cuando un cliente pregunta qué ocurrió.
Organizaciones
Representa la entidad comercial de nivel superior que opera una o varias instalaciones integradas con la plataforma del Performance Hub.
Endpoints
GET /partner/v1/organisations - List all organisations
El objeto de organización
Atributos
org_id
stringobligatorioIdentificador único de la organización.
name
stringobligatorioNombre de la organización.
El objeto de organización
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
}
Enumerar todas las organizaciones
Devuelve una lista de las organizaciones a las que tiene acceso tu cuenta de socio.
Valor devuelto
Devuelve un objeto JSON con una propiedad data que contiene una matriz de objetos de organización.
Solicitud
curl https://partner-api.performancehub.co/partner/v1/organisations \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Respuesta
{
"data": [
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
},
{
"org_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Wellness Studios Network"
}
]
}
Instalaciones
Representa una ubicación física, como una oficina, una tienda, un local, un campus, una clínica o un gimnasio, donde los miembros pueden acceder a servicios.
Endpoints
GET /partner/v1/facilities - List all facilities
El objeto de instalación
Atributos
facility_id
stringobligatorioIdentificador único de la instalación.
org_id
stringobligatorioIdentificador único de la organización principal.
name
stringobligatorioNombre de la instalación.
brand
stringopcionalNombre de la marca que usa la instalación.
website_url
stringopcionalURL del sitio web de la instalación.
place_data
objectopcionalDatos de ubicación de la Google Places API que contienen el país, la dirección con formato, el Google Place ID, la provincia y la ciudad.
social_links
objectopcionalEnlaces a las redes sociales de la instalación.
timezone
stringopcionalIdentificador de zona horaria IANA (por ejemplo,
"Australia/Sydney"o"America/New_York").
El objeto de instalación
{
"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"
}
Enumerar todas las instalaciones
Devuelve una lista de las instalaciones a las que tiene acceso tu cuenta de socio.
Valor devuelto
Devuelve un objeto JSON con una propiedad data que contiene una matriz de objetos de instalación.
Solicitud
curl https://partner-api.performancehub.co/partner/v1/facilities \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Respuesta
{
"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"
}
]
}
Planes de membresía
Define una oferta que se puede comprar a una organización o instalación, incluidos los servicios, los derechos, el horario y los precios.
Endpoints
POST /partner/v1/membership-plans - Save a membership plan
El objeto de plan de membresía
Atributos
membership_plan_id
stringobligatorioIdentificador único del plan de membresía.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador único de la instalación en el Performance Hub.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónValor del identificador único que el socio usa para cada ubicación (por ejemplo, "Branch ID", "Location Code" o "Store Number"). Más información
name
stringobligatorioNombre legible del plan (por ejemplo,
"Office tenant – business hours","Student – term access","Hotel guest"o"10 Class Pack").billing_cycle
stringopcionalFrecuencia de facturación. Uno de estos valores:
weekly,fortnightly,monthly,annuallyoone_time.price
integeropcionalCosto base en la unidad monetaria más pequeña (centavos para USD/AUD).
currency
stringopcionalCódigo de moneda ISO 4217 (por ejemplo,
"AUD"o"USD").description
stringopcionalDescripción comercial o interna opcional.
active_members
integeropcionalNúmero de miembros activos que usan este plan de membresía
is_recurring
booleanopcionalIndica si el plan se renueva automáticamente.
is_trial
booleanopcionalIndica si se trata de una oferta de prueba.
visible_to_public
booleanopcionalIndica si el plan está disponible para comprarse mediante autoservicio.
duration_days
integeropcionalNúmero de días durante los que es válido el plan de membresía.
access_zones
arrayopcionalMatriz de zonas de acceso incluidas en el plan de membresía. Cada zona puede definir sus propios horarios de acceso. Consulta Zonas de acceso para obtener más detalles.
class_limit
integeropcionalNúmero máximo de clases permitidas (null para ilimitadas).
El objeto de plan de membresía
Este ejemplo usa facility_id. En una integración con identificador de vinculación, envía "linking_identifier": "branch_downtown" en su lugar.
{
"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
}
Zonas de acceso
Las zonas de acceso definen áreas específicas dentro de una instalación a las que un plan de membresía concede acceso. Cada zona puede tener sus propios horarios de acceso, lo que permite aplicar restricciones horarias distintas a cada área.
Estructura
Cada zona de acceso incluye:
name
stringobligatorioEl nombre de la zona (por ejemplo, "Level 3 Tenancy", "Library", "Guest Floors" o "Main Gym Floor").
description
stringopcionalDescripción de lo que incluye esa zona.
access_hours
objectopcionalHorarios de acceso específicos de esta zona. Consulta Horarios de acceso para ver el formato de las franjas horarias.
Ejemplo
Un edificio de oficinas con un gimnasio para sus inquilinos: acceso a las oficinas alquiladas en horario laboral y al gimnasio desde primera hora de la mañana hasta última hora de la noche.
{
"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"]]
}
}
]
}
Horarios de acceso
Los horarios de acceso especifican cuándo pueden acceder los miembros a una zona concreta cada día de la semana. Los horarios de acceso se definen por zona de acceso, lo que permite aplicar restricciones horarias distintas a diferentes áreas de una instalación.
Estructura
{
"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"]]
}
Cada día es una matriz de franjas horarias en formato HH:MM (reloj de 24 horas). Una matriz vacía [] significa que no hay acceso ese día. Los días que se omiten se tratan igual que una matriz vacía.
Casos de uso de ejemplo
Inquilino de oficina – horario laboral: acceso en horario laboral solo los días de semana.
{
"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"]]
}
}
Estudiante – acceso durante el período lectivo: una biblioteca del campus abierta los días de semana, con una pausa a mediodía, y los sábados por la mañana.
{
"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"]]
}
}
Gimnasio – madrugadores: acceso solo por la mañana los días de semana.
{
"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"]]
}
}
Huésped de hotel – 24/7: acceso permanente, el caso de uso más habitual.
{
"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"]]
}
}
Ejemplo por zona
Un plan para huéspedes de hotel con acceso las 24 horas a las plantas de huéspedes y un horario más reducido para 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"]]
}
}
]
}
Guardar un plan de membresía
Crea o actualiza registros de planes de membresía. La API determina si debe crear o actualizar según el membership_plan_id.
Parámetros
membership_plans
arrayobligatorioMatriz de objetos de plan de membresía que se van a guardar. Máximo recomendado: 1000 elementos por solicitud para un rendimiento óptimo. La API agrupa automáticamente los elementos en lotes para procesarlos. Cada elemento debe incluir
facility_id(obligatorio si no se usalinking_identifier) olinking_identifier(obligatorio si no se usafacility_id).
Valor devuelto
Devuelve un mensaje sencillo que confirma la operación de sincronización.
Solicitud
Este ejemplo usa facility_id. En una integración con identificador de vinculación, envía "linking_identifier": "branch_downtown" en su lugar.
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
}
]
}'
Respuesta
Devuelve un mensaje de éxito con metadatos sobre la operación de sincronización.
{
"message": "Membership plan sync successful.",
"metadata": {
"success": 98,
"skipped": 2,
"skipped_items": [
{
"membership_plan_id": "plan_456",
"facility_id": null,
"reason": "Missing facility_id"
}
]
}
}
Campos de metadatos:
- success: número de planes de membresía procesados correctamente
- skipped: número de planes omitidos (si los hay)
- skipped_items: matriz de planes omitidos con los motivos (si los hay)
- dry-run: indicador booleano si se usa el tipo de clave dryrun (si corresponde)
Miembros
Representa a un cliente individual de una instalación. Puede ser un cliente potencial, un prospecto, un cliente habitual, un miembro vencido o un usuario bloqueado.
Las operaciones de inserción o actualización de miembros también pueden incluir una instantánea access_time_windows completa y con revisiones, que contiene accesos absolutos y semanales recurrentes. Consulta Access Time Windows antes de generar estos campos. Son permisos adicionales y no reemplazan las reglas habituales ni los permisos permanentes de la instalación.
Endpoints
POST /partner/v1/members - Save a member
El objeto de miembro
Atributos
member_id
stringobligatorioIdentificador único del miembro.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador único de la instalación en el Performance Hub.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónValor del identificador único que el socio usa para cada ubicación (por ejemplo, "Branch ID", "Location Code" o "Store Number"). Más información
first_name
stringobligatorioNombre del miembro.
last_name
stringobligatorioApellido del miembro.
email
stringopcionalDirección de correo electrónico.
mobile_phone
stringopcionalNúmero de teléfono móvil en formato E.123 (por ejemplo,
"+1 415 555 2671").address
objectopcionalObjeto de dirección física con las siguientes propiedades:
address_line_1(string): dirección principaladdress_line_2(string, opcional): línea de dirección secundariacity(string): nombre de la ciudadstate(string): código del estado o la provinciapostal_code(string): código postalcountry(string): código de país ISO 3166-1 alfa-2 (por ejemplo, "AU" o "US")country_name(string, opcional): nombre completo del país
date_of_birth
stringopcionalFecha de nacimiento en formato
YYYY-MM-DD.gender
stringopcionalUno de estos valores:
male,female,non_binary,prefer_not_to_sayounknown.type
stringopcionalTipo de miembro (por ejemplo,
staff,memberoprospect).tags
arrayopcionalCadenas o textos auxiliares para clasificar e identificar rápidamente a miembros específicos (por ejemplo,
["vip", "personal-training", "student"]).membership_status
stringopcionalEstado actual de la membresía (por ejemplo,
active,expireduon_hold).membership_plans
arrayopcionalMatriz de planes de membresía asociados al miembro.
profile_picture
stringopcionalFoto de perfil codificada en Base64 (opcional).
created
stringopcionalMarca de tiempo ISO 8601 del momento en que se creó el miembro.
updated
stringopcionalMarca de tiempo ISO 8601 de la última actualización del miembro.
access_time_windows
arrayopcionalInstantánea completa, perteneciente a la fuente, de las Access Time Windows absolutas o semanales recurrentes. Omite el campo para no modificar la instantánea; envía una matriz vacía con una revisión más reciente para revocarla. Consulta Access Time Windows para conocer las formas, la validación, la asignación de ámbitos y la semántica de reemplazo.
access_time_windows_revision
integerobligatorio con access_time_windowsEntero no negativo, monótonamente creciente y seguro para JSON, correspondiente a la secuencia de este miembro y esta fuente. Es obligatorio siempre que
access_time_windowsesté presente.
El objeto de miembro
{
"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
}
]
}
Ventanas de tiempo de acceso
Las Access Time Windows permiten que un miembro de socio tenga acceso temporal o recurrente proporcionado por un sistema externo. Esta página es la guía oficial para productores de access_time_windows y access_time_windows_revision.
Las Access Time Windows son permisos adicionales que solo permiten. Una ventana activa puede permitir el acceso, pero una ventana inactiva, vencida, obsoleta o sin asignar no deniega el acceso que ya permite una regla habitual o un permiso permanente. La desactivación del usuario, el bloqueo explícito de puertas, el modo de mantenimiento, la geovalla, los límites de frecuencia y la disponibilidad del controlador siguen aplicándose.
Las implementaciones para sistemas de origen concretos son adaptadores independientes. Deben traducir sus datos de origen a este contrato independiente del proveedor sin cambiar el significado de sus campos.
Campos de la instantánea del miembro
access_time_windows
arrayopcionalLa instantánea completa de Access Time Windows para este miembro y esta fuente del socio. Una instantánea puede combinar ventanas
absoluteyweekly. Omite el campo para no modificar la instantánea guardada; envía[]para revocar todas las ventanas que pertenecen a esta fuente.access_time_windows_revision
integerobligatorio con access_time_windowsUn entero no negativo, monótonamente creciente y seguro para JSON, correspondiente a la secuencia de revisiones de este miembro y esta fuente. Es obligatorio siempre que
access_time_windowsesté presente y no puede superar9007199254740991.
Cada instantánea acepta como máximo 50 ventanas. external_id, scope_key y label aceptan como máximo 120 caracteres. Las ventanas absolutas pueden abarcar como máximo 90 días. Un día semanal acepta como máximo ocho bloques que no se superpongan. Los datos no válidos se rechazan en lugar de truncarse o interpretarse.
Formas de las ventanas
Una ventana absoluta identifica un intervalo exacto:
Solicitud combinada completa
Esta solicitud reemplaza la instantánea anterior del miembro que pertenece a la fuente por una ventana absoluta y una semanal:
Reglas de hora y límites
from, to, active_from y active_until son segundos Unix como enteros JSON que identifican instantes UTC:
- Envía un entero JSON sin comillas. Se rechazan las cadenas numéricas, los números de coma flotante, las cadenas RFC 3339 y los milisegundos Unix.
- Todos los intervalos son semiabiertos:
[from, to). El acceso puede empezar exactamente enfrom; deja de estar activo exactamente ento. fromdebe ser menor queto. Cuando están presentes los dos límites semanales,active_fromdebe ser menor queactive_until.- No obtengas las épocas a partir de una fecha y hora local sin zona horaria. Primero resuelve la hora de origen a un instante UTC, luego divide los milisegundos Unix entre 1000 y verifica que el resultado sea un entero.
Zonas horarias y horario de verano
timezone debe ser una zona horaria IANA válida, como UTC, Australia/Perth o America/New_York. Si se omite, el valor predeterminado es UTC.
- Ventanas absolutas:
fromytoya identifican instantes UTC exactos.timezonees solo un metadato de visualización y auditoría; cambiarlo nunca desplaza ninguno de los dos instantes. - Ventanas semanales:
timezonedefine la hora local del reloj y las reglas de horario de verano que se usan para evaluaraccess_hours. No conviertas previamente los bloques semanales a UTC. - Cuando se adelanta la hora, una hora local que la zona horaria omite nunca ocurre.
- Cuando se atrasa la hora, los dos instantes reales que tienen la hora local repetida coinciden con el bloque semanal.
active_fromyactive_untilsiguen siendo instantes UTC incluso cuando una ventana semanal usa una zona horaria distinta de UTC.
access_hours usa los valores en minúsculas de sun a sat. Cada valor es una matriz de pares [start, end] en formato HH:mm de 24 horas con ceros a la izquierda. Los bloques no pueden estar vacíos, deben estar ordenados y no pueden superponerse. end es exclusivo. Un bloque no puede cruzar la medianoche; divide un intervalo nocturno de origen en un bloque tardío el primer día y un bloque temprano el día siguiente.
ID estables y asignación de ámbitos
external_id debe ser estable durante toda la vida de una ventana lógica y único dentro de la instantánea del miembro. Mantenlo estable cuando cambien las horas o las etiquetas para que los operadores y los registros de auditoría puedan relacionar las revisiones. No lo reutilices para una ventana no relacionada.
scope_key es tu destino de acceso lógico estable. Su valor predeterminado es default. Un administrador de la instalación asigna cada clave permitida a destinos del Performance Hub que abarcan toda la instalación, una puerta o un Alcance de acceso:
Instantáneas completas y revisiones
Trata los dos campos como una partición con versiones independientes dentro de la inserción o actualización del miembro:
| Entrada | Resultado |
|---|---|
Se omite access_time_windows |
La instantánea existente no cambia; no se requiere una revisión |
| Presente con una revisión más reciente | Se reemplaza toda la instantánea guardada para este miembro y esta fuente |
| Misma revisión y misma carga útil normalizada | Repetición idempotente; la instantánea no cambia |
| Misma revisión y carga útil normalizada diferente | Conflicto; asigna una nueva revisión después de conciliar |
| Revisión anterior | Se omite la instantánea obsoleta; no puede sobrescribir un estado más reciente |
access_time_windows: [] con una revisión más reciente |
Revoca explícitamente todas las ventanas que pertenecen a la fuente |
Una instantánea es completa, no un parche. Si la revisión 1842 tiene las ventanas A y B, la revisión 1843, que solo contiene B, elimina A.
Mantén una única secuencia de revisiones coordinada por socio y miembro entre los procesos de webhooks, el sondeo, las repeticiones y la conciliación completa. Es preferible usar una secuencia duradera de base de datos. Un valor en milisegundos Unix solo puede usarse como revisión cuando todos los procesos que escriben se coordinan y garantizan un orden estricto y valores únicos; es un valor de revisión, no un campo de época.
Conserva la solicitud y la revisión exactas hasta conocer la respuesta de la API. Después de un tiempo de espera agotado o un error transitorio, reintenta la misma instantánea normalizada con la misma revisión. No asignes una nueva revisión solo porque la entrega sea incierta.
Cancelación, vencimiento y errores de la fuente de origen
- Cancelar una ventana: consulta correctamente el estado autorizado de la fuente, quita esa ventana y envía la instantánea completa restante con una revisión más reciente.
- Cancelar todas las ventanas: envía
access_time_windows: []con una revisión más reciente. - Dejar que venza una ventana absoluta: deja de permitir el acceso en
to; envía una conciliación posterior sin la entrada vencida para mantener limpias las instantáneas. - Finalizar una ventana semanal: quítala en una instantánea más reciente o usa
active_untilcuando la fuente tenga un instante de fin conocido. - La consulta a la fuente falla o está incompleta: no envíes
[]ni publiques una instantánea parcial. Emite una alerta y reintenta la consulta. Convertir un error de la fuente de origen en una instantánea vacía supone una revocación de acceso no deseada. - La solicitud a la Partner API no supera la validación: corrige los datos y envía una revisión más reciente solo si cambia la instantánea normalizada. Reintenta los errores transitorios con la revisión original.
La actualización de la fuente se configura para cada integración según la frecuencia de entrega y de conciliación comprometida. Antes de la activación, acuerda la antigüedad máxima de la fuente, qué ocurre cuando se supera, los umbrales de alerta y si los operadores pueden aceptar basarse solo en los límites propios de cada ventana. Una ventana de una fuente obsoleta nunca se convierte en una regla de denegación; las reglas habituales y los permisos permanentes siguen siendo vías alternativas.
Algoritmo del productor
Usa este flujo de trabajo independiente del lenguaje en cada actualización de miembro:
Lista de comprobación de certificación
Completa estas comprobaciones en una instalación de pruebas con la asignación final de scope_key:
- Se acepta una ventana absoluta sin zona horaria y se evalúa como UTC.
- Una ventana absoluta con una zona IANA personalizada conserva los mismos instantes
from/to. - Una ventana semanal con una zona IANA personalizada sigue la hora local del reloj en los cambios de adelanto y atraso de la hora.
- Una instantánea combinada absoluta y semanal reemplaza por completo la instantánea anterior.
- El acceso empieza exactamente en
fromy se detiene exactamente ento; los finales de los bloques semanales también son exclusivos. - Actualizar las horas con el mismo
external_idy una revisión más reciente surte efecto. - Omitir
access_time_windowsmodifica otros campos del miembro sin cambiar las ventanas. - Repetir la misma revisión y carga útil es idempotente.
- La misma revisión con una carga útil diferente devuelve un conflicto y no cambia la instantánea.
- Una revisión anterior recibida fuera de orden se notifica como obsoleta y no puede revertir el estado.
- Un
[]más reciente revoca las ventanas que pertenecen a la fuente; un error en la consulta a la fuente de origen no envía nada. - Un
scope_keydesconocido o sin asignar deniega el acceso y genera una advertencia visible para el operador. - Las alertas de antigüedad de la fuente y la política configurada para fuentes obsoletas funcionan con el umbral acordado.
- Las vías de webhook y de conciliación completa convergen en la misma instantánea y el mismo orden de revisiones.
- La entrega de la secuencia llega a Door & Gate Access dentro del objetivo acordado.
- Una ventana activa puede permitir el acceso a la puerta física asignada, pero no puede omitir la desactivación del usuario,
blockAllAccess, el mantenimiento ni la geovalla. - Antes, fuera y después de una ventana, las reglas habituales y los permisos permanentes siguen permitiendo el acceso a los usuarios que cumplen los requisitos.
Pautas relacionadas
{
"external_id": "access-4b1782",
"kind": "absolute",
"from": 1792053000,
"to": 1792058400,
"timezone": "Australia/Perth",
"scope_key": "after_hours_entry",
"label": "Temporary site access"
}
Los campos obligatorios son external_id, kind, from y to. timezone, scope_key y label son opcionales.
Una ventana semanal identifica intervalos recurrentes según la hora local del reloj, opcionalmente acotados por instantes 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"
}
Los campos obligatorios son external_id, kind y access_hours. timezone, active_from, active_until, scope_key y label son opcionales.
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 o linking_identifier según el método de vinculación configurado. No envíes ambos.
Conversión de épocas
2026-10-15T08:30:00Z se convierte en 1792053000:
UTC instant Unix milliseconds Unix seconds sent
2026-10-15T08:30:00Z 1792053000000 1792053000
Conversión independiente del lenguaje:
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
Si la fuente tiene precisión inferior al segundo, define una política deliberada de redondeo del inicio y el fin antes de las pruebas de integración. Nunca pases milisegundos esperando que la API deduzca la unidad.
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
Los socios no envían ID de instalación, de puerta ni de Alcance de acceso del Performance Hub dentro de una ventana. Un scope_key desconocido, deshabilitado o sin asignar deniega el acceso para esa ventana; no amplía el acceso. Acuerda y prueba las asignaciones antes del lanzamiento.
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)
Vectores de prueba mínimos
[
{
"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."
}
]
Envía también vectores negativos para milisegundos Unix, cadenas numéricas, números de coma flotante, zonas IANA no válidas, from >= to, external_id duplicados, bloques superpuestos, bloques nocturnos, más de ocho bloques en un día, más de 50 ventanas y claves de ámbito sin asignar.
Guardar un miembro
Crea o actualiza registros de miembros. La API determina si debe crear o actualizar según el member_id.
Parámetros
members
arrayobligatorioMatriz de objetos de miembro que se van a guardar. Máximo recomendado: 1000 elementos por solicitud para un rendimiento óptimo. La API agrupa automáticamente los elementos en lotes para procesarlos. Cada elemento debe incluir
facility_id(obligatorio si no se usalinking_identifier) olinking_identifier(obligatorio si no se usafacility_id).Cuando un miembro incluye
access_time_windows, también debe incluiraccess_time_windows_revision. La matriz es una instantánea completa de la fuente, no un parche. Omítela para conservar la instantánea existente o envía[]con una revisión más reciente para revocar todas las ventanas que pertenecen a la fuente. Lee la guía de Access Time Windows antes de habilitar este campo.
Valor devuelto
Devuelve un mensaje sencillo que confirma la operación de sincronización.
Los campos del perfil del miembro siguen siendo inserciones o actualizaciones normales incluso cuando una instantánea de ventanas se notifica como repetición idempotente u omisión por obsoleta. Una instantánea en conflicto (misma revisión con una carga útil diferente) no se puede reintentar sin cambios; concilia el estado de la fuente y envía una revisión más reciente.
Solicitud
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
}
]
}
]
}'
Respuesta
Devuelve un mensaje de éxito con metadatos sobre la operación de sincronización.
{
"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"
}
]
}
}
Campos de metadatos:
- success: número de miembros procesados correctamente
- skipped: número de miembros omitidos (si los hay)
- skipped_items: matriz de miembros omitidos con los motivos (si los hay)
- dry-run: indicador booleano si se usa el tipo de clave dryrun (si corresponde)
Registros de entrada
Representa el registro de la presencia de una persona en una instalación, una clase o una actividad. Se usa para hacer un seguimiento de la asistencia, analizar el uso y mejorar la precisión de la detección visual.
Endpoints
POST /partner/v1/check-ins - Save check-ins
El objeto de registro de entrada
Atributos
check_in_id
stringopcionalIdentificador único del registro de entrada. Opcional: si no se proporciona, se genera automáticamente a partir del par
member_idytimestamp.member_id
stringobligatorioIdentificador único del miembro.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador único de la instalación en el Performance Hub.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónValor del identificador único que el socio usa para cada ubicación (por ejemplo, "Branch ID", "Location Code" o "Store Number"). Más información
check_in_type
stringopcionalTipo de visita. Uno de estos valores:
member,class,staff,guestotrial.source
stringopcionalCómo se capturó el registro de entrada. Los valores habituales son
manual,tag,rfid,kioskyapp. También se pueden usar otros valores, comodoor_readerobooking.class_id
stringopcionalOpcional. Se usa si el registro está vinculado a la reserva o la asistencia a una clase.
timestamp
stringobligatorioMarca de tiempo en formato ISO 8601 del momento en que se produjo el registro de entrada.
El objeto de registro de entrada
{
// "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"
}
Guardar registros de entrada
Crea registros de entrada. La API elimina automáticamente los duplicados según el miembro, la instalación y la marca de tiempo.
Parámetros
check_ins
arrayobligatorioMatriz de objetos de registro de entrada que se van a guardar. Máximo recomendado: 1000 elementos por solicitud para un rendimiento óptimo. La API agrupa automáticamente los elementos en lotes para procesarlos. Cada elemento debe incluir
facility_id(obligatorio si no se usalinking_identifier) olinking_identifier(obligatorio si no se usafacility_id).
Valor devuelto
Devuelve un mensaje sencillo que confirma la operación de sincronización.
Solicitud
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"
}
]
}'
Respuesta
Devuelve un mensaje de éxito con metadatos sobre la operación de sincronización.
{
"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"
}
]
}
}
Campos de metadatos:
- success: número de registros de entrada procesados correctamente
- skipped: número de registros de entrada omitidos (si los hay)
- skipped_items: matriz de registros de entrada omitidos con los motivos (si los hay)
- dry-run: indicador booleano si se usa el tipo de clave dryrun (si corresponde)
Control de acceso
La Partner API puede activar el hardware del controlador de puertas y portones del Performance Hub en las instalaciones donde tu integración está habilitada.
Usa esta API cuando tu sistema de gestión de miembros ya haya decidido que una persona puede entrar. El Performance Hub no evalúa el estado de la membresía, los horarios de acceso, las reglas de zonas de puertas, las comprobaciones antifraude ni la lógica de suspensión. Tu sistema sigue siendo la autoridad para esas decisiones.
La solicitud de desbloqueo es síncrona. El Performance Hub envía el comando al controlador del sitio en tiempo real y devuelve 200 solo después de que el dispositivo confirma que el relé se desbloqueó físicamente. La mayoría de las confirmaciones deberían completarse en 3-5 segundos. Si no se recibe ninguna confirmación dentro del tiempo de espera, la API devuelve un error explícito.
También puedes registrar un intento de acceso o una denegación que nunca llegó al controlador. Esa llamada no desbloquea la puerta. Escribe un evento en los registros de acceso de Door & Gate Access.
Endpoints
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
El objeto de controlador de puertas y portones
Atributos
door_id
stringobligatorioIdentificador único del controlador de puertas y portones. Guárdalo en tu sistema después de detectarlo y úsalo al llamar al endpoint de desbloqueo.
facility_id
stringobligatorioID de instalación del Performance Hub.
linking_identifier
stringopcionalIdentificador de instalación del socio cuando tu integración usa identificadores de vinculación. Más información
name
stringobligatorioNombre legible del dispositivo configurado en el Performance Hub.
zone
stringopcionalZona o ubicación de la puerta, como
Entrance.status
stringobligatorioonlineuoffline.relay_state
stringopcionalÚltimo estado conocido del relé, como
lockedounlocked.maintenance_mode
stringobligatorioModo de mantenimiento actual. Uno de estos valores:
off,force-openoforce-closed.hold_time_seconds
integerobligatorioTiempo de apertura predeterminado configurado para la puerta.
last_seen
stringopcionalMarca de tiempo ISO de la actualización más reciente de los metadatos del dispositivo.
El objeto de controlador de puertas y portones
{
"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"
}
Enumerar los controladores de puertas y portones
Devuelve los controladores de puertas y portones disponibles para tu integración.
Si no se proporciona facility_id ni linking_identifier, la API devuelve los controladores de puertas y portones de todas las instalaciones vinculadas a tu cuenta de socio.
Parámetros
facility_id
stringopcional uno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónID de instalación del Performance Hub. Úsalo en las integraciones de vinculación directa.
linking_identifier
stringopcional uno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónTu propio identificador de instalación o ubicación. Úsalo cuando tu integración esté configurada para usar identificadores de vinculación.
Valor devuelto
Devuelve una matriz de objetos de controlador de puertas y portones.
Solicitud
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:
Respuesta
{
"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"
}
]
}
Obtener el estado de un controlador de puertas y portones
Recupera el último estado conocido y la configuración básica de un solo controlador de puertas y portones.
Proporciona un identificador de instalación para que el Performance Hub pueda verificar que la puerta pertenece a una instalación a la que tu integración tiene acceso.
Parámetros
door_id
stringobligatorioID del controlador de puertas y portones que devuelve el endpoint de lista.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónID de instalación del Performance Hub. Obligatorio en las integraciones de vinculación directa.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador de instalación del socio. Obligatorio en las integraciones con identificador de vinculación.
Valor devuelto
Devuelve un objeto de controlador de puertas y portones.
Solicitud
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:
Respuesta
{
"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"
}
}
Desbloquear un controlador de puertas y portones
Envía un comando de desbloqueo al controlador de puertas y portones y espera a que el relé físico confirme que se desbloqueó.
Tu sistema debe decidir si la persona está autorizada antes de llamar a este endpoint. El Performance Hub solo verifica la clave de socio, el acceso a la instalación, la pertenencia de la puerta y el estado del dispositivo.
Parámetros
door_id
stringobligatorioID del controlador de puertas y portones que devuelve el endpoint de lista.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónID de instalación del Performance Hub. Obligatorio en las integraciones de vinculación directa.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador de instalación del socio. Obligatorio en las integraciones con identificador de vinculación.
member_id
stringobligatorioID del miembro en el sistema del socio. Se usa para los registros de auditoría y para vincular datos más adelante.
first_name
stringobligatorioNombre de la persona que abre la puerta.
last_name
stringobligatorioApellido de la persona que abre la puerta.
full_name
stringopcionalOpcional. Si se omite, el Performance Hub combina
first_nameylast_name.check_in_id
stringopcionalID opcional del registro de entrada en tu sistema, para relacionar los datos.
idempotency_key
stringopcionalClave opcional de protección contra repeticiones. Si reutilizas la misma clave para el mismo socio, la misma instalación y la misma puerta, se devuelve el resultado existente cuando está disponible.
Valor devuelto
Devuelve 200 solo cuando el dispositivo confirma que el relé se desbloqueó físicamente. La puerta usa el tiempo de apertura configurado en Gestión de dispositivos del Performance Hub; los socios no pueden anular la temporización del relé en cada solicitud. La mayoría de las confirmaciones deberían completarse en 3-5 segundos. Trata el tiempo de espera documentado como un desbloqueo fallido explícito y reintenta solo según tus propias reglas de seguridad.
Errores comunes:
403 integration_not_enabled: tu integración no está habilitada para la instalación.409 maintenance_mode_active: el personal de la instalación activó el modo de mantenimiento para la puerta.503 device_offline: el controlador de puertas y portones está desconectado o sus datos están desactualizados.504 unlock_confirmation_timeout: el comando se envió, pero no se recibió una confirmación correspondiente antes del tiempo de espera.
Solicitud
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"
}'
Respuesta
{
"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"
}
Respuesta de error
{
"status": "failed",
"reason": "device_offline",
"door_id": "00000000000000000000000000000007",
"facility_id": "550e8400-e29b-41d4-a716-446655440000",
"event_id": "00000000-0000-0000-0000-000000000045"
}
Registrar un intento de acceso o una denegación
Registra un intento de acceso o una denegación que tu sistema ya decidió. No se contacta con el controlador de puertas y portones y la puerta no se desbloquea.
Usa este endpoint cuando tu sistema rechace la entrada o cuando un intento deba aparecer en los registros de acceso de Door & Gate Access sin un desbloqueo. El Performance Hub no evalúa el estado de la membresía, los horarios de acceso ni otras reglas de acceso.
Un evento denegado aparece en los registros de acceso de Door & Gate Access con el resultado Denied, el nombre de tu empresa asociada, la puerta, el identificador del miembro si lo envías y el código de motivo en formato legible. Por ejemplo, membership_expired se muestra como "Membership Expired". reason_display_text y user_email se guardan con el evento.
Parámetros
door_id
stringobligatorioID del controlador de puertas y portones que devuelve el endpoint de lista.
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónID de instalación del Performance Hub. Obligatorio en las integraciones de vinculación directa.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador de instalación del socio. Obligatorio en las integraciones con identificador de vinculación.
outcome
stringobligatoriodeniedoattempted.reason
stringopcionalCódigo de motivo en snake_case y minúsculas, de hasta 64 caracteres. Obligatorio cuando
outcomeesdenied. Ejemplo:membership_expired.reason_display_text
stringopcionalMotivo legible, de hasta 256 caracteres. Ejemplo:
Membership expired on 2026-04-01.member_id
stringopcionalID del miembro en el sistema del socio. Omítelo cuando la credencial no coincidió con ningún miembro, por ejemplo, una tarjeta desconocida.
user_email
stringopcionalCorreo electrónico de la persona que intentó acceder.
timestamp
stringopcionalMomento en que ocurrió el intento, en formato ISO 8601 con zona horaria. Ejemplo:
2026-05-18T10:15:30Z. Si se omite, se usa la hora en que se recibe la solicitud. No puede estar más de 5 minutos en el futuro ni tener más de 30 días de antigüedad.idempotency_key
stringopcionalClave de protección contra repeticiones, de hasta 128 caracteres. Si reutilizas la misma clave para el mismo socio, la misma instalación y la misma puerta, se devuelve el resultado original.
Valor devuelto
Devuelve 201 cuando se registra el evento. Si repites la misma idempotency_key, se devuelve 200 con idempotent establecido en true y no se crea otro evento.
Una clave de prueba (dry-run) devuelve 200 con dry_run establecido en true. No se registra nada.
Errores comunes:
400: el cuerpo no es válido, una denegación no tienereason, la marca de tiempo está fuera del rango ofacility_id/linking_identifierno coincide con una instalación vinculada.403: la clave es de solo lectura.403 integration_not_enabled: tu integración no está habilitada para la instalación.messageindica el motivo.404: no se encontró el controlador de puertas y portones en la instalación vinculada.
Solicitud
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"
}'
Respuesta
{
"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"
}
Repetición 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
}
Informes de las instalaciones
Un registro en un momento dado que recoge las métricas operativas y financieras clave de una instalación durante un período específico.
Endpoints
POST /partner/v1/report-snapshots - Save report snapshots
El objeto de instantánea de informe
Atributos
facility_id
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónIdentificador único de la instalación en el Performance Hub.
linking_identifier
stringuno u otroIndica el tipo de identificador de instalación configurado para tu integración: usa facility_id en las integraciones de vinculación directa o linking_identifier en las integraciones con identificador de vinculación. No envíes ambos; la API usa el tipo de identificador configurado para tu cuenta de socio e ignora el otro. Más informaciónValor del identificador único que el socio usa para cada ubicación (por ejemplo, "Branch ID", "Location Code" o "Store Number"). Más información
start_date
stringobligatorioFecha de inicio del período de la instantánea en formato
YYYY-MM-DD.end_date
stringobligatorioFecha de finalización del período de la instantánea en formato
YYYY-MM-DD.metrics
objectobligatorioObjeto de métricas que contiene los datos de miembros e ingresos del período.
El objeto de instantánea de informe
{
"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"
}
}
}
Guardar instantáneas de informes
Envía las métricas operativas y financieras de una instalación durante un período específico.
Parámetros
snapshots
arrayobligatorioMatriz de objetos de instantánea de informe que se van a guardar. Máximo de 25 elementos por solicitud. Cada elemento debe incluir
facility_id(obligatorio si no se usalinking_identifier) olinking_identifier(obligatorio si no se usafacility_id).
Valor devuelto
Devuelve un mensaje sencillo que confirma la operación de sincronización.
Solicitud
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"
}
}
}
]
}'
Respuesta
{
"message": "Report snapshot sync successful."
}
Errores
La Partner API usa códigos de estado HTTP estándar y cuerpos de respuesta JSON para explicar por qué falló una solicitud.
Estructura de las respuestas de error
La mayoría de los errores de la API devuelven un cuerpo JSON con un mensaje y, cuando están disponibles, detalles estructurados.
Códigos de estado
Errores de Access Time Windows
La validación de las ventanas falla antes de que se escriba la instantánea no válida. Las causas habituales que no admiten reintento son:
- Falta
access_time_windows_revisioncuandoaccess_time_windowsestá presente. - Valores de época como cadena, de coma flotante o que probablemente estén en milisegundos.
- Una zona horaria IANA no válida, un intervalo invertido, un
external_idduplicado, bloques semanales superpuestos o un bloque nocturno que no se dividió. - Un valor fuera de los límites documentados de cantidad, longitud o duración.
Una revisión repetida con contenido normalizado diferente genera un 409 Conflict. Concilia con el último estado autorizado y asigna una revisión más reciente; no sigas reintentando el par en conflicto. Una revisión anterior se notifica como una instantánea omitida por obsoleta, en lugar de permitir que sobrescriba un estado más reciente. Un scope_key desconocido o sin asignar deniega la autorización y debe tratarse como una alerta de configuración.
Si se agota el tiempo de espera de la entrega o se recibe un 5xx transitorio, reintenta exactamente la misma instantánea normalizada con la misma revisión. Si falló la consulta a la fuente de origen, omite por completo el campo de ventanas; nunca lo sustituyas por una matriz vacía.
Pautas de reintento
Reintenta estos errores con un retroceso exponencial acotado:
429500502503504
No reintentes estos errores a ciegas:
400401403404409422
En el control de acceso, trata siempre las respuestas de tiempo de espera agotado y de dispositivo desconectado como desbloqueos fallidos, a menos que tus propias reglas de acceso y procesos de seguridad indiquen lo contrario.
Datos que debes incluir al solicitar soporte
Cuando te comuniques con soporte, incluye:
- Endpoint y método HTTP.
- Marca de tiempo y zona horaria.
- ID de la clave de socio, no la clave secreta.
- Identificador de instalación usado.
- ID del registro de origen en tu sistema.
- Estado y cuerpo de la respuesta.
event_idocommand_id, si están disponibles.
{
"success": false,
"message": "Request body.members[0].member_id is required"
}
Algunos endpoints específicos de un dominio devuelven un estado y un motivo explícitos. Por ejemplo, los errores de control de acceso incluyen campos como reason, door_id, facility_id y 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 solicitud tiene un formato incorrecto o le faltan campos obligatorios. Corrige la solicitud antes de reintentar.
401 Unauthorized
Falló la autenticación. Comprueba que usas HTTP Basic Auth con tu clave secreta de API como nombre de usuario y una contraseña vacía.
403 Forbidden
La clave es válida, pero la operación no está permitida. Las causas habituales son usar una clave de solo lectura para una operación de escritura o intentar acceder a una instalación donde tu integración no está habilitada.
404 Not Found
No se encontró el recurso solicitado o no está disponible para tu integración.
409 Conflict
La solicitud entra en conflicto con el estado actual del recurso. En el control de acceso, puede deberse, por ejemplo, a que un controlador de puertas y portones está en modo de mantenimiento.
422 Unprocessable Entity
La solicitud es un JSON válido, pero no supera la validación semántica. Corrige los datos antes de reintentar.
429 Too Many Requests
La integración superó el límite de frecuencia documentado. Reintenta con retroceso exponencial.
500 Internal Server Error
El Performance Hub no pudo completar la solicitud debido a un error interno. Reintenta con retroceso. Si el problema continúa, comunícate con soporte e indica el endpoint, la marca de tiempo y el cuerpo de la respuesta.
503 Service Unavailable
Un servicio o dispositivo del que depende la operación no está disponible. En los desbloqueos de controladores de puertas y portones, puede significar que el controlador está desconectado.
504 Gateway Timeout
Se agotó el tiempo de espera de la operación. En los desbloqueos de controladores de puertas y portones, significa que el desbloqueo no se confirmó antes de que terminara el tiempo de espera.
Control de versiones
La versión de la Partner API se indica en la URL. La versión actual es:
Política de cambios
El Performance Hub procura hacer cambios aditivos y compatibles con versiones anteriores siempre que sea posible.
Ejemplos de cambios compatibles con versiones anteriores:
- Agregar un nuevo campo opcional a una solicitud.
- Agregar un nuevo campo a una respuesta.
- Agregar un nuevo endpoint.
- Agregar un nuevo valor de enumeración cuando se espera que los clientes gestionen valores desconocidos.
- Mejorar los mensajes de validación sin cambiar el contrato de códigos de estado.
access_time_windows y access_time_windows_revision son campos adicionales de la solicitud de miembros. Los clientes existentes que los omiten mantienen sin cambios la instantánea guardada de Access Time Windows. Esta regla de omisión preserva la compatibilidad con las inserciones o actualizaciones parciales; omitirlos no equivale a enviar una matriz vacía.
Ejemplos de cambios incompatibles:
- Eliminar o cambiar el nombre de un campo.
- Cambiar el tipo de un campo.
- Hacer obligatorio un campo de solicitud opcional.
- Eliminar un endpoint.
- Cambiar el significado de un código de estado existente o de un
reasonespecífico de un dominio.
Elementos obsoletos
Cuando sea necesario un cambio incompatible, el Performance Hub evitará, siempre que sea posible, modificar la versión existente. En su lugar, introduciremos una nueva versión o una ruta de migración y comunicaremos el cambio a los socios afectados.
Los avisos de obsolescencia pueden incluir:
- Una entrada en el registro de cambios.
- Una comunicación directa con los socios.
- Notas en la Partner Console.
- Pautas de migración en la documentación.
Recomendaciones para los clientes
Crea clientes que toleren los cambios aditivos:
- Ignora los campos de respuesta que no uses.
- Trata los valores de enumeración desconocidos como no admitidos en lugar de provocar un error.
- Evita las comprobaciones estrictas de igualdad de las respuestas.
- Registra los valores no reconocidos para poder actualizar tu integración de forma deliberada.
En las particiones de miembros con revisiones, como Access Time Windows, conserva la revisión enviada y la carga útil normalizada hasta conocer el resultado. Reutilizar una revisión con contenido modificado genera un conflicto, mientras que repetir el mismo contenido es idempotente. Consulta Access Time Windows.
Especificaciones OpenAPI
Usa las especificaciones OpenAPI publicadas para generar clientes, validar solicitudes y hacer un seguimiento de los cambios en la estructura de la API a lo largo del tiempo.
Consulta Especificaciones OpenAPI.
https://partner-api.performancehub.co/partner/v1/
Registro de cambios
Este registro de cambios recoge los cambios importantes de la Partner API y la Partner Console que afectan al comportamiento de las integraciones.
2026-09-09
2026-05-06
2026-05-01
Categorías de cambios
Las entradas futuras usan estas categorías:
- Agregado: nuevo endpoint, campo, guía o capacidad.
- Modificado: cambió el comportamiento o la documentación sin retirar la compatibilidad.
- Obsoleto: la función sigue disponible, pero tiene prevista una ruta de migración.
- Eliminado: se eliminó la función o el endpoint.
- Corregido: corrección de errores o de la documentación.
- Seguridad: cambio en la autenticación, la autorización, el tratamiento de datos o la administración de claves.
Agregado
- Se agregaron instantáneas
access_time_windowsde miembros, independientes del proveedor, con ventanas absolutas y semanales recurrentes combinadas. - Se agregó la semántica de ordenación por
access_time_windows_revision, repetición idempotente, conflicto, omisión de datos obsoletos y revocación explícita. - Se agregaron pautas sobre zonas horarias IANA, horario de verano, asignación lógica de
scope_key, actualización de la fuente, implementación del productor y certificación.
Agregado
- Se agregó documentación del programa de socios sobre los tipos de socios, la incorporación, las prácticas recomendadas, la preparación para la puesta en producción, los errores, el control de versiones y el soporte.
- Se agregó un flujo específico de consulta Conviértete en socio para posibles socios técnicos y comerciales.
- Se agregó documentación sobre cómo aparecen las integraciones de socios aprobadas en el directorio de socios del Performance Hub, dentro de la plataforma principal del Performance Hub.
Agregado
- Se agregó documentación de control de acceso para el controlador de puertas y portones, incluidas las operaciones de lista, estado y desbloqueo.
- Se agregó documentación del comportamiento síncrono del desbloqueo: la API devuelve un resultado correcto solo después de que el controlador del sitio confirma que el relé se desbloqueó físicamente.
- Se agregó documentación de la compatibilidad con la
idempotency_keyopcional en las solicitudes de desbloqueo del controlador de puertas y portones.