Введение
Partner API Performance Hub позволяет внешним партнерским платформам беспрепятственно интегрироваться с основными модулями Performance Hub. API поддерживает компьютерное зрение, аналитику, регистрацию доступа участников и аналитику объектов.
Формат запросов
API принимает тела запросов в кодировке JSON и возвращает ответы в кодировке JSON.
Ограничение частоты запросов
Для обеспечения справедливого использования и стабильности системы для партнерских учетных записей API изначально действуют следующие ограничения по умолчанию:
- 5 запросов в секунду на конечную точку
- Рекомендуется: не более 1000 элементов в одном пакетном запросе для оптимальной производительности
- Не более 10MB — размер полезной нагрузки
Ограничения частоты запросов можно изменить: ваш менеджер партнерской учетной записи Performance Hub настраивает их индивидуально. Если вашей интеграции нужна более высокая пропускная способность для запуска, миграций, загрузки исторических данных для отчетов или объектов с большим объемом данных, сообщите об этом во время подключения или до планового окна изменений.
Базовый URL-адрес
https://partner-api.performancehub.co/partner/v1/
Аутентификация
Для доступа к Partner API требуется аутентификация с помощью секретных ключей API. Создавайте ключи и управляйте ими в Partner Console.
Ключи API служат вашими учетными данными для доступа к партнерским ресурсам. Каждый ключ имеет ограниченный доступ к данным определенной организации, и при необходимости его можно мгновенно деактивировать.
Обращайтесь с ключами API бережно — они предоставляют полный доступ к вашей учетной записи! Никогда не размещайте эти ключи в общедоступных репозиториях, клиентских приложениях или в любом другом месте, где они могут быть скомпрометированы.
Аутентифицируйте запросы с помощью HTTP Basic Auth, передавая ключ API в качестве имени пользователя. Пароль оставьте пустым.
API принимает только защищенные подключения HTTPS. Запросы по обычному HTTP отклоняются, как и любые запросы без надлежащих учетных данных аутентификации.
Пример запроса
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.
Проверка секретного ключа
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>" }
Контрольный список перед запуском
Используйте этот контрольный список перед включением партнерской интеграции для рабочих объектов.
Настройка Partner Console
- Профиль партнера заполнен полностью.
- URL-адрес логотипа, сайт, категория и описание указаны верно.
- Настроен способ связи данных: Direct Link или Linking Identifier.
- Связь с объектами проверена как минимум на одном реальном объекте.
- Используется правильный тип ключа:
- Dryrun для тестирования записи без изменения данных.
- Read-only для безопасного получения данных.
- Live только тогда, когда вы готовы изменять рабочие данные.
Аутентификация и управление ключами
- Секретные ключи хранятся только на стороне сервера.
- Ключи не встроены в клиентские приложения, мобильные приложения, общедоступные репозитории или запросы в службу поддержки.
- Ротация и отзыв ключей протестированы.
- Ваша команда знает, какой ключ используется в каждой среде.
Проверка данных
- Для каждой вызываемой конечной точки указаны обязательные поля.
- Идентификаторы объектов соответствуют настроенному способу связи.
- Идентификаторы из вашей системы стабильны и не меняются между синхронизациями.
- Крупные импорты разбиты на пакеты в пределах документированных ограничений.
- Элементы пакетов с ошибками можно определить и отправить повторно.
Тестирование конечных точек
Перед запуском протестируйте все конечные точки, от которых зависит ваша интеграция:
- Организации и объекты успешно считываются.
- Участники сохраняются и обновляются.
- Планы членства, зоны доступа и часы доступа синхронизируются правильно.
- Посещения принимаются и могут быть сопоставлены с записями в вашей системе.
- Снимки отчетов используют ожидаемый отчетный период и показатели.
- Процессы Door/Gate Controller, где это применимо, протестированы на реальном оборудовании.
Готовность Access Time Windows
Если интеграция передает Access Time Windows:
- Примеры абсолютных и еженедельных окон проходят контрольный список сертификации поставщика данных.
- Значения эпохи передаются как целые числа секунд Unix без кавычек; точные границы
[from, to)протестированы. - Проверены значения UTC по умолчанию, пользовательские часовые пояса IANA интеграции и соответствующие переходы на летнее время.
- Один надежный монотонный поток ревизий по участнику и источнику координирует инкрементные обновления, сверку и повторные попытки.
- Операторы понимают поведение при опущенном значении, полной замене, идемпотентном повторе, конфликте, устаревших данных и явном
[]. - Для каждого
scope_key, включаяdefault, есть утвержденное сопоставление в Performance Hub; проверено, что неизвестные ключи приводят к отказу в доступе. - Настроены ожидаемая частота обновления интеграции, максимальная давность исходных данных, поведение при устаревшем источнике и оповещения.
- Доказано, что ошибка получения данных из вышестоящего источника не приводит к отправке пустого или неполного снимка.
- Сходимость потоков по этапам, отмена или отзыв доступа и границы начала и окончания для физических дверей соответствуют согласованным целевым показателям.
- Обычные правила и постоянные разрешения проверены как резервные варианты, и окна не могут обойти отключение пользователя,
blockAllAccess, режим обслуживания или геозонирование.
Готовность контроля доступа
Для интеграций контроля доступа:
- Ваша система принимает решение о доступе до вызова Performance Hub.
- Интеграция обрабатывает
device_offline,maintenance_mode_activeиunlock_confirmation_timeout. - Операторы понимают, что тайм-аут означает, что разблокировка не подтверждена.
- В ваших журналах сохраняются возвращаемые
event_idиcommand_id. - У персонала объекта есть ручной резервный процесс.
Обработка ошибок и повторные попытки
- Ответы
400,401,403,404,409и422передаются операторам или службе поддержки, а не повторяются вслепую. - Для ответов
429,500,502,503и504используется логика ограниченных повторных попыток с задержкой. - Повторяющиеся ошибки вызывают оповещение в вашей системе.
- Интеграция никогда не отбрасывает записи с ошибками без уведомления.
Наблюдаемость
- Ваши журналы содержат конечную точку, метку времени, идентификатор объекта, идентификатор исходной записи, результат запроса и тело ответа.
- Ваша служба поддержки может выполнять поиск по идентификатору участника, идентификатору объекта, идентификатору посещения или идентификатору события разблокировки.
- У вас есть способ повторить или сверить неудачные синхронизации.
Запуск в рабочей среде
- Performance Hub подтвердил ваш доступ к рабочей среде.
- Как минимум один рабочий объект включил вашу интеграцию.
- Ваш рабочий ключ активен.
- Ваши операционные и технические контакты актуальны.
- Ваш процесс поддержки задокументирован для клиентов.
После выполнения этих проверок ваша настроенная интеграция появится в каталоге партнеров Performance Hub внутри основной платформы Performance Hub.
Рекомендации
Следуйте этим подходам, чтобы партнерские интеграции оставались предсказуемыми, наблюдаемыми и безопасными для объектов.
Единообразно идентифицируйте объекты
Выберите способ связи, настроенный для вашей партнерской учетной записи, и используйте его единообразно:
- Direct Link — используйте
facility_idPerformance Hub, возвращаемый конечной точкой объектов. - Linking Identifier — используйте собственный идентификатор площадки, например идентификатор филиала, код площадки или номер магазина.
Не отправляйте оба идентификатора в одном запросе. Performance Hub обрабатывает запросы с помощью способа связи, настроенного для вашей партнерской учетной записи.
Инструкции по настройке см. в разделе Способы связи партнера.
Тщательно формируйте пакетные операции записи
Partner API принимает тела запросов в формате JSON и, где это указано в документации, рассчитан на пакетные процессы синхронизации. Ограничивайте размер пакетов и обеспечивайте возможность их повторной отправки.
Рекомендации по умолчанию:
- Для оптимальной производительности используйте не более 1000 элементов в одном пакетном запросе.
- Размер полезной нагрузки не должен превышать 10MB.
- Не превышайте 5 запросов в секунду на конечную точку.
Ограничения частоты запросов можно изменить: ваш менеджер партнерской учетной записи Performance Hub настраивает их индивидуально. Если вы ожидаете импорт больших объемов, всплеск трафика при запуске или загрузку исторических данных для отчетов, согласуйте необходимую пропускную способность до начала окна изменений.
Если нужно синхронизировать большой набор данных, разделите его на детерминированные части и регистрируйте идентификатор каждой части на своей стороне. Так будет проще разобраться в неудачных повторных попытках.
Безопасно повторяйте попытки
Для временных ошибок, таких как 429, 500, 502, 503 и 504, используйте экспоненциальную задержку.
Избегайте частых циклов повторных попыток. Для начала подойдет такая схема:
- Повторите попытку через 1 секунду.
- Повторите попытку через 2 секунды.
- Повторите попытку через 4 секунды.
- Если операция по-прежнему завершается ошибкой, остановитесь и отправьте оповещение.
При ошибках проверки, таких как 400 или 422, исправьте запрос, прежде чем повторять попытку.
Используйте идемпотентность там, где она поддерживается
Конечная точка разблокировки контроллера Door/Gate Controller поддерживает необязательный параметр idempotency_key. При повторном использовании того же ключа для того же партнера, объекта и двери возвращается существующий результат, если он доступен.
Используйте стабильный ключ для выполняемого действия, например идентификатор посещения или идентификатор события доступа из вашей системы.
Не рассчитывайте, что каждая конечная точка записи поддерживает идемпотентность, если это не указано в документации для этой конечной точки.
Поддерживайте чистоту исходных данных
По возможности отправляйте стабильные нормализованные значения:
- Используйте согласованные идентификаторы участников, планов, объектов и посещений из исходной системы.
- Используйте метки времени ISO 8601 для дат и времени.
- По возможности отправляйте номера телефонов в международном формате.
- Передавайте валюты в полях, указанных в документации для каждой конечной точки.
- Не перегружайте поля свободного текста данными, которые должны находиться в структурированных полях.
Предусмотрите инкрементную и полную синхронизацию
Большинству партнерских интеграций нужны оба варианта:
- Инкрементная синхронизация для ежедневных изменений.
- Полная сверочная синхронизация для исправления пропущенных событий, импорта исторических данных или расхождения данных.
Ваша интеграция должна уметь повторно отправлять текущее состояние участника, плана членства или снимка отчета, не завися от успешного выполнения предыдущего запроса.
Безопасно публикуйте Access Time Windows
Рассматривайте значение access_time_windows каждого участника как полный снимок с независимой нумерацией ревизий:
- Согласуйте единый монотонно возрастающий поток
access_time_windows_revisionмежду обработчиками инкрементной и сверочной синхронизации. - Повторяйте неподтвержденную или временно неудачную доставку с той же ревизией и той же нормализованной полезной нагрузкой.
- Не указывайте
access_time_windows, если не обновляете это значение. - Отправляйте
[]только после того, как успешное получение данных из основного источника подтвердит, что окон не осталось. Никогда не превращайте тайм-аут вышестоящей системы, неполный результат или ошибку разбора в отзыв доступа. - Сохраняйте
external_idиscope_keyстабильными и сертифицируйте каждое сопоставление областей перед запуском в рабочей среде. - Отслеживайте давность исходных данных в соответствии с политикой актуальности, согласованной для этой интеграции.
Сведения о полных снимках, часовых поясах, переходе на летнее время, отмене и тестовых векторах см. в официальном руководстве для поставщиков данных Access Time Windows.
Относитесь к контролю доступа как к критически важной для безопасности функции
Для разблокировки контроллеров Door/Gate Controller:
- Ваша система должна решить, разрешен ли человеку вход, до вызова Performance Hub.
- Performance Hub возвращает
200только после того, как контроллер на площадке подтвердит, что реле физически разблокировано. - Обычно подтверждение приходит за 3-5 секунд.
- Тайм-аут означает явную неудачу разблокировки, а не успешное выполнение в фоновом режиме.
- Повторяйте попытки только в соответствии с собственными правилами доступа и безопасности.
Всегда регистрируйте значения event_id и command_id, возвращаемые конечной точкой разблокировки.
Отслеживайте работу интеграции
Во время разработки и запуска используйте журналы запросов в Partner Console. В рабочей среде также ведите собственные журналы со следующими данными:
- Время запроса.
- Конечная точка.
- Идентификатор исходной записи.
- Идентификатор объекта.
- Код состояния HTTP.
- Тело ответа Performance Hub или сообщение об ошибке.
Эти поля значительно ускоряют поддержку и сверку, когда клиент спрашивает, что произошло.
Организации
Представляет бизнес-структуру верхнего уровня, которая управляет одним или несколькими объектами, интегрированными с платформой Performance Hub.
Конечные точки
GET /partner/v1/organisations - List all organisations
Объект Organisation
Атрибуты
org_id
stringобязательныйУникальный идентификатор организации.
name
stringобязательныйНазвание организации.
Объект Organisation
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
}
Список всех организаций
Возвращает список организаций, доступных вашей партнерской учетной записи.
Возвращаемое значение
Возвращает объект JSON со свойством data, содержащим массив объектов Organisation.
Запрос
curl https://partner-api.performancehub.co/partner/v1/organisations \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Ответ
{
"data": [
{
"org_id": "00000000-0000-0000-0000-000000000050",
"name": "Harbourside Group"
},
{
"org_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
"name": "Wellness Studios Network"
}
]
}
Объекты
Представляет физическую площадку, например офис, магазин, площадку для мероприятий, кампус, клинику или спортзал, где участники могут пользоваться услугами.
Конечные точки
GET /partner/v1/facilities - List all facilities
Объект Facility
Атрибуты
facility_id
stringобязательныйУникальный идентификатор объекта.
org_id
stringобязательныйУникальный идентификатор родительской организации.
name
stringобязательныйНазвание объекта.
brand
stringнеобязательныйНазвание бренда, используемое объектом.
website_url
stringнеобязательныйURL-адрес сайта объекта.
place_data
objectнеобязательныйДанные о местоположении из Google Places API: страна, форматированный адрес, Google Place ID, регион и город.
social_links
objectнеобязательныйСсылки объекта на социальные сети.
timezone
stringнеобязательныйИдентификатор часового пояса IANA (например,
"Australia/Sydney","America/New_York").
Объект Facility
{
"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"
}
Список всех объектов
Возвращает список объектов, доступных вашей партнерской учетной записи.
Возвращаемое значение
Возвращает объект JSON со свойством data, содержащим массив объектов Facility.
Запрос
curl https://partner-api.performancehub.co/partner/v1/facilities \
-u sk_live_YOUR_PARTNER_SECRET_KEY:
Ответ
{
"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"
}
]
}
Планы членства
Определяет предложение организации или объекта, доступное для покупки, включая услуги, права, расписание и цены.
Конечные точки
POST /partner/v1/membership-plans - Save a membership plan
Объект Membership Plan
Атрибуты
membership_plan_id
stringобязательныйУникальный идентификатор плана членства.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальный идентификатор объекта в Performance Hub.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальное значение идентификатора каждой площадки, используемое партнером (например, "Branch ID", "Location Code", "Store Number"). Подробнее
name
stringобязательныйУдобочитаемое название плана (например,
"Office tenant – business hours","Student – term access","Hotel guest","10 Class Pack").billing_cycle
stringнеобязательныйПериодичность выставления счетов. Одно из значений:
weekly,fortnightly,monthly,annuallyилиone_time.price
integerнеобязательныйБазовая стоимость в наименьшей денежной единице (центы для USD/AUD).
currency
stringнеобязательныйКод валюты ISO 4217 (например,
"AUD","USD").description
stringнеобязательныйНеобязательное маркетинговое или внутреннее описание.
active_members
integerнеобязательныйКоличество активных участников, использующих этот план членства
is_recurring
booleanнеобязательныйПродлевается ли план автоматически.
is_trial
booleanнеобязательныйЯвляется ли предложение пробным.
visible_to_public
booleanнеобязательныйДоступен ли план для самостоятельной покупки.
duration_days
integerнеобязательныйКоличество дней действия плана членства.
access_zones
arrayнеобязательныйМассив зон доступа, входящих в план членства. Для каждой зоны можно задать собственные часы доступа. Подробнее см. в разделе Зоны доступа.
class_limit
integerнеобязательныйМаксимальное разрешенное количество занятий (null — без ограничений).
Объект Membership Plan
В этом примере используется facility_id. Для интеграции со связующим идентификатором отправьте вместо него "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
}
Зоны доступа
Зоны доступа определяют конкретные области объекта, к которым план членства предоставляет доступ. Для каждой зоны можно задать собственные часы доступа, что позволяет устанавливать разные временные ограничения для разных областей.
Структура
Каждая зона доступа включает:
name
stringобязательныйНазвание зоны (например, "Level 3 Tenancy", "Library", "Guest Floors", "Main Gym Floor").
description
stringнеобязательныйОписание того, что входит в эту зону.
access_hours
objectнеобязательныйЧасы доступа для этой зоны. Формат временных диапазонов см. в разделе Часы доступа.
Пример
Офисное здание со спортзалом для арендаторов: доступ к арендуемым помещениям в рабочее время, а к спортзалу — с раннего утра до позднего вечера.
{
"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"]]
}
}
]
}
Часы доступа
Часы доступа определяют, когда участники могут получить доступ к определенной зоне в каждый день недели. Часы доступа задаются для каждой зоны доступа, что позволяет устанавливать разные временные ограничения для разных областей объекта.
Структура
{
"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"]]
}
Каждый день представлен массивом временных диапазонов в формате HH:MM (24-часовой формат). Пустой массив [] означает отсутствие доступа в этот день. Пропущенные дни обрабатываются так же, как пустой массив.
Примеры использования
Арендатор офиса — рабочие часы: доступ в рабочее время только по будним дням.
{
"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"]]
}
}
Студент — доступ на время семестра: библиотека кампуса, открытая по будним дням с перерывом в середине дня, а также по субботам утром.
{
"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"]]
}
}
Спортзал — ранние пташки: доступ только в утренние часы по будним дням.
{
"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"]]
}
}
Гость отеля — круглосуточно: постоянный доступ, наиболее распространенный сценарий.
{
"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"]]
}
}
Пример для отдельных зон
План для гостей отеля с круглосуточным доступом к гостевым этажам и сокращенными часами работы бассейна:
{
"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"]]
}
}
]
}
Сохранение плана членства
Создает или обновляет записи планов членства. API определяет, создавать или обновлять запись, на основе membership_plan_id.
Параметры
membership_plans
arrayобязательныйМассив объектов Membership Plan для сохранения. Рекомендуемый максимум для оптимальной производительности — 1000 элементов на запрос. API автоматически разбивает элементы на пакеты для обработки. Каждый элемент должен содержать либо
facility_id(обязателен, если не используетсяlinking_identifier), либоlinking_identifier(обязателен, если не используетсяfacility_id).
Возвращаемое значение
Возвращает простое сообщение, подтверждающее операцию синхронизации.
Запрос
В этом примере используется facility_id. Для интеграции со связующим идентификатором отправьте вместо него "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
}
]
}'
Ответ
Возвращает сообщение об успешном выполнении с метаданными операции синхронизации.
{
"message": "Membership plan sync successful.",
"metadata": {
"success": 98,
"skipped": 2,
"skipped_items": [
{
"membership_plan_id": "plan_456",
"facility_id": null,
"reason": "Missing facility_id"
}
]
}
}
Поля метаданных:
- success — количество успешно обработанных планов членства
- skipped — количество пропущенных планов (если есть)
- skipped_items — массив пропущенных планов с указанием причин (если есть)
- dry-run — логический флаг при использовании ключа типа dryrun (если применимо)
Участники
Представляет отдельного клиента объекта. Это может быть лид, потенциальный клиент, постоянный клиент, участник с истекшим членством или заблокированный пользователь.
Операции upsert для участников также могут передавать полный снимок access_time_windows с ревизией, содержащий абсолютный и еженедельный повторяющийся доступ. Прежде чем формировать эти поля, ознакомьтесь с разделом Access Time Windows. Они являются дополнительными разрешениями и не заменяют обычные правила объекта или постоянные разрешения.
Конечные точки
POST /partner/v1/members - Save a member
Объект Member
Атрибуты
member_id
stringобязательныйУникальный идентификатор участника.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальный идентификатор объекта в Performance Hub.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальное значение идентификатора каждой площадки, используемое партнером (например, "Branch ID", "Location Code", "Store Number"). Подробнее
first_name
stringобязательныйИмя участника.
last_name
stringобязательныйФамилия участника.
email
stringнеобязательныйАдрес электронной почты.
mobile_phone
stringнеобязательныйНомер мобильного телефона в формате E.123 (например,
"+1 415 555 2671").address
objectнеобязательныйОбъект физического адреса со следующими свойствами:
address_line_1(string) — основная строка адресаaddress_line_2(string, optional) — дополнительная строка адресаcity(string) — название городаstate(string) — код штата или регионаpostal_code(string) — почтовый индексcountry(string) — код страны ISO 3166-1 alpha-2 (например, "AU", "US")country_name(string, optional) — полное название страны
date_of_birth
stringнеобязательныйДата рождения в формате
YYYY-MM-DD.gender
stringнеобязательныйОдно из значений:
male,female,non_binary,prefer_not_to_sayилиunknown.type
stringнеобязательныйТип участника (например,
staff,member,prospect).tags
arrayнеобязательныйКороткие вспомогательные строки или тексты для категоризации и идентификации определенных участников (например,
["vip", "personal-training", "student"]).membership_status
stringнеобязательныйТекущий статус членства (например,
active,expired,on_hold).membership_plans
arrayнеобязательныйМассив планов членства, связанных с участником.
profile_picture
stringнеобязательныйФотография профиля в кодировке Base64 (необязательно).
created
stringнеобязательныйМетка времени ISO 8601 создания участника.
updated
stringнеобязательныйМетка времени ISO 8601 последнего обновления участника.
access_time_windows
arrayнеобязательныйПолный снимок абсолютных и (или) еженедельных повторяющихся Access Time Windows, принадлежащий источнику. Не указывайте поле, чтобы оставить снимок без изменений; отправьте пустой массив с более новой ревизией, чтобы отозвать его. Сведения о формах, проверке, сопоставлении областей и семантике замены см. в разделе Access Time Windows.
access_time_windows_revision
integerобязателен вместе с access_time_windowsМонотонно возрастающее неотрицательное целое число, безопасное для JSON, для потока этого участника и источника. Обязательно, если указано
access_time_windows.
Объект 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
}
]
}
Временные окна доступа
Access Time Windows позволяют участнику на стороне партнера получать временный или повторяющийся доступ, предоставленный внешней системой. Эта страница — официальное руководство для поставщиков данных по полям access_time_windows и access_time_windows_revision.
Access Time Windows — это дополнительные разрешения, которые только предоставляют доступ. Активное окно может разрешить доступ, но неактивное, истекшее, устаревшее или несопоставленное окно не запрещает доступ, который уже разрешен обычным правилом или постоянным разрешением. Отключение пользователя, явная блокировка двери, режим обслуживания, геозонирование, ограничения частоты и доступность контроллера по-прежнему действуют.
Реализации для конкретных вышестоящих систем представляют собой отдельные адаптеры. Они должны преобразовывать исходные данные в этот независимый от поставщика контракт, не меняя значения полей.
Поля снимка участника
access_time_windows
arrayнеобязательныйПолный снимок Access Time Windows для этого участника и источника партнера. Снимок может сочетать окна
absoluteиweekly. Не указывайте поле, чтобы оставить сохраненный снимок без изменений; отправьте[], чтобы отозвать все окна, принадлежащие этому источнику.access_time_windows_revision
integerобязателен вместе с access_time_windowsМонотонно возрастающее неотрицательное целое число, безопасное для JSON, для потока ревизий этого участника и источника. Обязательно, если указано
access_time_windows, и не должно превышать9007199254740991.
Каждый снимок может содержать не более 50 окон. Поля external_id, scope_key и label принимают не более 120 символов. Абсолютное окно может охватывать не более 90 дней. Для одного дня недели допускается не более восьми непересекающихся блоков. Недопустимые данные отклоняются, а не обрезаются или угадываются.
Формы окон
Абсолютное окно задает один точный интервал:
Полный смешанный запрос
Этот запрос заменяет предыдущий снимок участника, принадлежащий источнику, одним абсолютным и одним еженедельным окном:
Правила времени и границ
from, to, active_from и active_until — целые числа JSON в секундах Unix, обозначающие моменты времени UTC:
- Отправляйте целое число JSON без кавычек. Числовые строки, числа с плавающей запятой, строки RFC 3339 и миллисекунды Unix отклоняются.
- Каждый интервал полуоткрытый:
[from, to). Доступ может начаться точно в моментfrom; в моментtoон уже не активен. fromдолжно быть меньшеto. Если указаны обе границы еженедельного окна,active_fromдолжно быть меньшеactive_until.- Не вычисляйте значения эпохи из местной даты и времени без часового пояса. Сначала преобразуйте исходное время в момент UTC, затем разделите миллисекунды Unix на 1000 и убедитесь, что результат — целое число.
Часовые пояса и летнее время
timezone должен быть допустимым часовым поясом IANA, например UTC, Australia/Perth или America/New_York. Если он не указан, по умолчанию используется UTC.
- Абсолютные окна:
fromиtoуже обозначают точные моменты UTC.timezoneслужит только метаданными для отображения и аудита; его изменение никогда не сдвигает ни один из этих моментов. - Еженедельные окна:
timezoneопределяет местное время и правила перехода на летнее время, используемые для оценкиaccess_hours. Не преобразуйте еженедельные блоки в UTC заранее. - При переводе часов вперед местное время, которое пропускается в этом часовом поясе, не наступает.
- При переводе часов назад еженедельному блоку соответствуют оба реальных момента с повторяющимся местным временем.
active_fromиactive_untilостаются моментами UTC, даже если еженедельное окно использует часовой пояс, отличный от UTC.
access_hours использует ключи в нижнем регистре от sun до sat. Каждое значение — массив пар [start, end] в 24-часовом формате HH:mm с ведущими нулями. Блоки должны быть непустыми, упорядоченными и непересекающимися. end не включается в интервал. Блок не может переходить через полночь; разделите ночной исходный интервал на поздний блок в первый день и ранний блок на следующий день.
Стабильные идентификаторы и сопоставление областей
external_id должен оставаться неизменным в течение всего срока существования логического окна и быть уникальным в пределах снимка участника. Сохраняйте его неизменным при изменении времени или меток, чтобы операторы и записи аудита могли сопоставлять ревизии. Не используйте его повторно для несвязанного окна.
scope_key — ваша стабильная логическая цель доступа. По умолчанию используется default. Администратор объекта сопоставляет каждый разрешенный ключ с целями Performance Hub: весь объект, дверь или Область доступа:
Полные снимки и ревизии
Рассматривайте эти два поля как отдельный раздел с независимым управлением версиями внутри операции upsert для участника:
| Входные данные | Результат |
|---|---|
access_time_windows не указано |
Существующий снимок остается без изменений; ревизия не требуется |
| Указано с более новой ревизией | Весь сохраненный снимок для этого участника и источника заменяется |
| Та же ревизия и та же нормализованная полезная нагрузка | Идемпотентный повтор; снимок не меняется |
| Та же ревизия и другая нормализованная полезная нагрузка | Конфликт; после сверки назначьте новую ревизию |
| Более старая ревизия | Устаревший снимок пропускается; он не может перезаписать более новое состояние |
access_time_windows: [] с более новой ревизией |
Явно отзывает все окна, принадлежащие источнику |
Снимок является полным, а не исправлением. Если ревизия 1842 содержит окна A и B, то ревизия 1843, содержащая только B, удаляет A.
Поддерживайте один согласованный поток ревизий для каждой пары партнер — участник во всех обработчиках веб-перехватчиков, опросе, повторной отправке и полной сверке. Предпочтительно использовать надежную последовательность базы данных. Значение в миллисекундах Unix можно использовать в качестве ревизии, только если все записывающие процессы согласованы и гарантируют строгий порядок и уникальность; это значение ревизии, а не поле эпохи.
Сохраняйте точный запрос и ревизию, пока не станет известен ответ API. После тайм-аута или временной ошибки повторите отправку того же нормализованного снимка с той же ревизией. Не назначайте новую ревизию только потому, что доставка неизвестна.
Отмена, истечение срока и сбои вышестоящих систем
- Отмена одного окна: успешно получите состояние из основного источника, удалите это окно и отправьте оставшийся полный снимок с более новой ревизией.
- Отмена всех окон: отправьте
access_time_windows: []с более новой ревизией. - Истечение срока абсолютного окна: оно перестает предоставлять доступ в момент
to; отправьте последующую сверку без истекшей записи, чтобы снимки оставались чистыми. - Завершение еженедельного окна: удалите его в более новом снимке или используйте
active_until, если в источнике известен момент окончания. - Получение данных из источника не удалось или неполно: не отправляйте
[]и не публикуйте неполный снимок. Отправьте оповещение и повторите получение данных. Превращение сбоя вышестоящей системы в пустой снимок — это непреднамеренный отзыв доступа. - Запрос Partner API не прошел проверку: исправьте данные и отправьте более новую ревизию, только если нормализованный снимок изменился. Временные ошибки повторяйте с исходной ревизией.
Актуальность источника настраивается для каждой интеграции на основе обещанной частоты доставки и сверки. Перед активацией согласуйте максимальную давность исходных данных, последствия ее превышения, пороги оповещений и возможность для операторов подтвердить, что они полагаются только на собственные границы каждого окна. Устаревшее окно источника никогда не становится запрещающим правилом; обычные правила и постоянные разрешения остаются резервными вариантами.
Алгоритм для поставщика данных
Используйте этот не зависящий от языка программирования процесс для каждого обновления участника:
Контрольный список сертификации
Выполните эти проверки на тестовом объекте с окончательным сопоставлением scope_key:
- Абсолютное окно без часового пояса принимается и оценивается в UTC.
- Абсолютное окно с пользовательским часовым поясом IANA сохраняет те же моменты
from/to. - Еженедельное окно с пользовательским часовым поясом IANA следует местному времени при переводе часов вперед и назад.
- Смешанный снимок с абсолютными и еженедельными окнами полностью заменяет предыдущий снимок.
- Доступ начинается точно в момент
fromи прекращается точно в моментto; окончание еженедельных блоков также не включается. - Изменение времени для того же
external_idс более новой ревизией вступает в силу. - Если
access_time_windowsне указано, другие поля участника изменяются без изменения окон. - Повторная отправка той же ревизии и полезной нагрузки идемпотентна.
- Та же ревизия с другой полезной нагрузкой возвращает конфликт и не меняет снимок.
- Более старая ревизия, пришедшая не по порядку, помечается как устаревшая и не может откатить состояние.
- Более новое значение
[]отзывает окна, принадлежащие источнику; при сбое получения данных из вышестоящего источника ничего не отправляется. - Неизвестный или несопоставленный
scope_keyприводит к отказу в доступе и создает предупреждение, видимое оператору. - Оповещения о давности источника и настроенная политика для устаревшего источника срабатывают на согласованном пороге.
- Пути веб-перехватчика и полной сверки приводят к одному и тому же снимку и порядку ревизий.
- Доставка потока достигает Door & Gate Access в пределах согласованного целевого времени.
- Активное окно может разрешить доступ к сопоставленной физической двери, но не может обойти отключение пользователя,
blockAllAccess, режим обслуживания или геозонирование. - До окна, вне его и после него обычные правила и постоянные разрешения по-прежнему допускают пользователей, которые иным образом соответствуют требованиям.
Связанные рекомендации
{
"external_id": "access-4b1782",
"kind": "absolute",
"from": 1792053000,
"to": 1792058400,
"timezone": "Australia/Perth",
"scope_key": "after_hours_entry",
"label": "Temporary site access"
}
Обязательные поля: external_id, kind, from и to. Поля timezone, scope_key и label необязательны.
Еженедельное окно задает повторяющиеся интервалы по местному времени, при необходимости ограниченные моментами времени 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"
}
Обязательные поля: external_id, kind и access_hours. Поля timezone, active_from, active_until, scope_key и label необязательны.
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"
}
]
}
]
}'
Используйте либо facility_id, либо linking_identifier в соответствии с настроенным способом связи. Не отправляйте оба.
Преобразование в эпоху
2026-10-15T08:30:00Z преобразуется в 1792053000:
UTC instant Unix milliseconds Unix seconds sent
2026-10-15T08:30:00Z 1792053000000 1792053000
Преобразование, не зависящее от языка программирования:
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
Если исходные данные имеют точность до долей секунды, до начала интеграционного тестирования определите продуманную политику округления начала и окончания. Никогда не передавайте миллисекунды в расчете на то, что API сам определит единицу измерения.
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
Партнеры не передают в окне идентификаторы объектов, дверей или областей доступа Performance Hub. Неизвестный, отключенный или несопоставленный scope_key приводит к отказу в доступе для этого окна; он не расширяет доступ. Согласуйте и протестируйте сопоставления до запуска.
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)
Минимальные тестовые векторы
[
{
"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."
}
]
Также отправьте отрицательные векторы для миллисекунд Unix, числовых строк, чисел с плавающей запятой, недопустимых часовых поясов IANA, from >= to, повторяющихся external_id, пересекающихся блоков, ночных блоков, более восьми блоков в день, более 50 окон и несопоставленных ключей областей.
Сохранение участника
Создает или обновляет записи участников. API определяет, создавать или обновлять запись, на основе member_id.
Параметры
members
arrayобязательныйМассив объектов Member для сохранения. Рекомендуемый максимум для оптимальной производительности — 1000 элементов на запрос. API автоматически разбивает элементы на пакеты для обработки. Каждый элемент должен содержать либо
facility_id(обязателен, если не используетсяlinking_identifier), либоlinking_identifier(обязателен, если не используетсяfacility_id).Если участник содержит
access_time_windows, он также должен содержатьaccess_time_windows_revision. Массив представляет собой полный снимок источника, а не исправление. Не указывайте его, чтобы сохранить существующий снимок, или отправьте[]с более новой ревизией, чтобы отозвать все окна, принадлежащие источнику. Перед включением этого поля прочитайте руководство по Access Time Windows.
Возвращаемое значение
Возвращает простое сообщение, подтверждающее операцию синхронизации.
Поля профиля участника обрабатываются как обычные операции upsert, даже если снимок окон зарегистрирован как идемпотентный повтор или пропуск устаревших данных. Конфликтующий снимок (та же ревизия, другая полезная нагрузка) нельзя повторно отправить без изменений; выполните сверку состояния источника и отправьте более новую ревизию.
Запрос
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
}
]
}
]
}'
Ответ
Возвращает сообщение об успешном выполнении с метаданными операции синхронизации.
{
"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"
}
]
}
}
Поля метаданных:
- success — количество успешно обработанных участников
- skipped — количество пропущенных участников (если есть)
- skipped_items — массив пропущенных участников с указанием причин (если есть)
- dry-run — логический флаг при использовании ключа типа dryrun (если применимо)
Посещения
Представляет запись о присутствии человека на объекте, занятии или мероприятии. Используется для учета посещаемости, аналитики использования и повышения точности визуального распознавания.
Конечные точки
POST /partner/v1/check-ins - Save check-ins
Объект Check-In
Атрибуты
check_in_id
stringнеобязательныйУникальный идентификатор посещения. Необязательный параметр: если он не указан, он автоматически формируется из пары
member_idиtimestamp.member_id
stringобязательныйУникальный идентификатор участника.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальный идентификатор объекта в Performance Hub.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальное значение идентификатора каждой площадки, используемое партнером (например, "Branch ID", "Location Code", "Store Number"). Подробнее
check_in_type
stringнеобязательныйТип визита. Одно из значений:
member,class,staff,guestилиtrial.source
stringнеобязательныйСпособ регистрации посещения. Распространенные значения:
manual,tag,rfid,kiosk,app. Также могут использоваться дополнительные значения, напримерdoor_readerилиbooking.class_id
stringнеобязательныйНеобязательный параметр. Указывается, если посещение связано с бронированием или посещением занятия.
timestamp
stringобязательныйМетка времени посещения в формате ISO 8601.
Объект 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"
}
Сохранение посещений
Создает записи о посещениях. API автоматически удаляет дубликаты по участнику, объекту и метке времени.
Параметры
check_ins
arrayобязательныйМассив объектов Check-In для сохранения. Рекомендуемый максимум для оптимальной производительности — 1000 элементов на запрос. API автоматически разбивает элементы на пакеты для обработки. Каждый элемент должен содержать либо
facility_id(обязателен, если не используетсяlinking_identifier), либоlinking_identifier(обязателен, если не используетсяfacility_id).
Возвращаемое значение
Возвращает простое сообщение, подтверждающее операцию синхронизации.
Запрос
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"
}
]
}'
Ответ
Возвращает сообщение об успешном выполнении с метаданными операции синхронизации.
{
"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"
}
]
}
}
Поля метаданных:
- success — количество успешно обработанных посещений
- skipped — количество пропущенных посещений (если есть)
- skipped_items — массив пропущенных посещений с указанием причин (если есть)
- dry-run — логический флаг при использовании ключа типа dryrun (если применимо)
Контроль доступа
Partner API может активировать оборудование Door/Gate Controller в Performance Hub на объектах, где включена ваша интеграция.
Используйте этот API, когда ваша система управления участниками уже решила, что человеку разрешен вход. Performance Hub не проверяет статус членства, часы доступа, правила зон дверей, признаки мошенничества или логику приостановки. Ваша система по-прежнему принимает эти решения.
Запрос на разблокировку синхронный. Performance Hub в реальном времени отправляет команду контроллеру на площадке и возвращает 200 только после того, как устройство подтвердит, что реле физически разблокировано. Обычно подтверждение приходит за 3-5 секунд. Если подтверждение не получено в течение времени ожидания, API возвращает явную ошибку.
Вы также можете записать попытку доступа или отказ, не дошедшие до контроллера. Такой вызов не разблокирует дверь, а записывает событие в журналы доступа Door & Gate Access.
Конечные точки
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
Объект Door/Gate Controller
Атрибуты
door_id
stringобязательныйУникальный идентификатор контроллера Door/Gate Controller. Сохраните его в своей системе после обнаружения и используйте при вызове конечной точки разблокировки.
facility_id
stringобязательныйИдентификатор объекта в Performance Hub.
linking_identifier
stringнеобязательныйИдентификатор объекта на стороне партнера, если ваша интеграция использует связующие идентификаторы. Подробнее
name
stringобязательныйУдобочитаемое имя устройства, заданное в Performance Hub.
zone
stringнеобязательныйЗона или расположение двери, например
Entrance.status
stringобязательныйonlineилиoffline.relay_state
stringнеобязательныйПоследнее известное состояние реле, например
lockedилиunlocked.maintenance_mode
stringобязательныйТекущий режим обслуживания. Одно из значений:
off,force-openилиforce-closed.hold_time_seconds
integerобязательныйВремя удержания разблокировки по умолчанию, настроенное для двери.
last_seen
stringнеобязательныйМетка времени ISO последнего обновления метаданных устройства.
Объект 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"
}
Список контроллеров Door/Gate Controller
Возвращает контроллеры Door/Gate Controller, доступные вашей интеграции.
Если не указан ни facility_id, ни linking_identifier, API возвращает контроллеры Door/Gate Controller на всех объектах, связанных с вашей партнерской учетной записью.
Параметры
facility_id
stringнеобязательный одно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта в Performance Hub. Используйте его для интеграций с прямой связью.
linking_identifier
stringнеобязательный одно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееВаш собственный идентификатор объекта или площадки. Используйте его, если ваша интеграция настроена на связующие идентификаторы.
Возвращаемое значение
Возвращает массив объектов Door/Gate Controller.
Запрос
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:
Ответ
{
"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"
}
]
}
Получение состояния контроллера Door/Gate Controller
Возвращает последнее известное состояние и основную конфигурацию одного контроллера Door/Gate Controller.
Укажите идентификатор объекта, чтобы Performance Hub мог убедиться, что дверь принадлежит объекту, к которому у вашей интеграции есть доступ.
Параметры
door_id
stringобязательныйИдентификатор контроллера Door/Gate Controller, возвращаемый конечной точкой получения списка.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта в Performance Hub. Обязателен для интеграций с прямой связью.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта на стороне партнера. Обязателен для интеграций со связующим идентификатором.
Возвращаемое значение
Возвращает объект Door/Gate Controller.
Запрос
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:
Ответ
{
"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"
}
}
Разблокировка контроллера Door/Gate Controller
Отправляет команду разблокировки контроллеру Door/Gate Controller и ожидает подтверждения от физического реле о том, что разблокировка выполнена.
Перед вызовом этой конечной точки ваша система должна решить, есть ли у человека право доступа. Performance Hub проверяет только ключ партнера, доступ к объекту, принадлежность двери и состояние устройства.
Параметры
door_id
stringобязательныйИдентификатор контроллера Door/Gate Controller, возвращаемый конечной точкой получения списка.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта в Performance Hub. Обязателен для интеграций с прямой связью.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта на стороне партнера. Обязателен для интеграций со связующим идентификатором.
member_id
stringобязательныйИдентификатор участника на стороне партнера. Используется для журнала аудита и последующей связи данных.
first_name
stringобязательныйИмя человека, открывающего дверь.
last_name
stringобязательныйФамилия человека, открывающего дверь.
full_name
stringнеобязательныйНеобязательный параметр. Если он не указан, Performance Hub объединяет
first_nameиlast_name.check_in_id
stringнеобязательныйНеобязательный идентификатор посещения из вашей системы для сопоставления.
idempotency_key
stringнеобязательныйНеобязательный ключ защиты от повторов. При повторном использовании того же ключа для того же партнера, объекта и двери возвращается существующий результат, если он доступен.
Возвращаемое значение
Возвращает 200 только в том случае, если устройство подтверждает, что реле физически разблокировано. Дверь использует время удержания, настроенное в разделе «Управление устройствами» Performance Hub; партнеры не могут переопределять время срабатывания реле в отдельном запросе. Обычно подтверждение приходит за 3-5 секунд. Рассматривайте истечение документированного времени ожидания как явную неудачу разблокировки и повторяйте попытку только в соответствии с собственными правилами безопасности.
Типичные ошибки:
403 integration_not_enabled— ваша интеграция не включена для объекта.409 maintenance_mode_active— персонал объекта включил для двери режим обслуживания.503 device_offline— контроллер Door/Gate Controller не в сети или его данные устарели.504 unlock_confirmation_timeout— команда отправлена, но соответствующее подтверждение не получено до истечения времени ожидания.
Запрос
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"
}'
Ответ
{
"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"
}
Ответ с ошибкой
{
"status": "failed",
"reason": "device_offline",
"door_id": "00000000000000000000000000000007",
"facility_id": "550e8400-e29b-41d4-a716-446655440000",
"event_id": "00000000-0000-0000-0000-000000000045"
}
Запись попытки доступа или отказа
Записывает попытку доступа или отказ, решение о котором ваша система уже приняла. Обращения к контроллеру Door/Gate Controller не происходит, и дверь не разблокируется.
Используйте этот вызов, когда ваша система отказывает во входе или когда попытка должна отобразиться в журналах доступа Door & Gate Access без разблокировки. Performance Hub не проверяет статус членства, часы доступа или другие правила доступа.
Событие отказа отображается в журналах доступа Door & Gate Access с результатом Denied, именем вашего партнера, дверью, идентификатором участника (если вы его передали) и кодом причины в удобочитаемом виде. Например, membership_expired отображается как "Membership Expired". Значения reason_display_text и user_email сохраняются вместе с событием.
Параметры
door_id
stringобязательныйИдентификатор контроллера Door/Gate Controller, возвращаемый конечной точкой получения списка.
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта в Performance Hub. Обязателен для интеграций с прямой связью.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееИдентификатор объекта на стороне партнера. Обязателен для интеграций со связующим идентификатором.
outcome
stringобязательныйdeniedилиattempted.reason
stringнеобязательныйКод причины в нижнем регистре в формате snake_case, до 64 символов. Обязателен, если
outcomeимеет значениеdenied. Пример:membership_expired.reason_display_text
stringнеобязательныйУдобочитаемая причина, до 256 символов. Пример:
Membership expired on 2026-04-01.member_id
stringнеобязательныйИдентификатор участника на стороне партнера. Не указывайте его, если учетные данные не соответствуют ни одному участнику, например при использовании неизвестной карты.
user_email
stringнеобязательныйАдрес электронной почты человека, пытавшегося получить доступ.
timestamp
stringнеобязательныйВремя попытки в формате ISO 8601 с часовым поясом. Пример:
2026-05-18T10:15:30Z. По умолчанию используется время получения запроса. Значение не должно опережать текущее время более чем на 5 минут или быть старше 30 дней.idempotency_key
stringнеобязательныйКлюч защиты от повторов, до 128 символов. При повторном использовании того же ключа для того же партнера, объекта и двери возвращается исходный результат.
Возвращаемое значение
Возвращает 201, если событие записано. Повторная отправка с тем же idempotency_key возвращает 200 со значением idempotent, равным true, и не создает новое событие.
Ключ dry-run возвращает 200 со значением dry_run, равным true. Ничего не записывается.
Типичные ошибки:
400— тело запроса недопустимо, для отказа не указанreason, время вне допустимого диапазона илиfacility_id/linking_identifierне соответствует связанному объекту.403— ключ предназначен только для чтения.403 integration_not_enabled— ваша интеграция не включена для объекта. Причина указана вmessage.404— контроллер Door/Gate Controller не найден для связанного объекта.
Запрос
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"
}'
Ответ
{
"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"
}
Идемпотентный повтор
{
"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
}
Отчеты объекта
Запись на определенный момент времени, содержащая ключевые операционные и финансовые показатели объекта за определенный период.
Конечные точки
POST /partner/v1/report-snapshots - Save report snapshots
Объект Report Snapshot
Атрибуты
facility_id
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальный идентификатор объекта в Performance Hub.
linking_identifier
stringодно из двухУкажите тип идентификатора объекта, настроенный для вашей интеграции: facility_id для интеграций с прямой связью или linking_identifier для интеграций со связующим идентификатором. Не отправляйте оба; API использует тип идентификатора, настроенный для вашей партнерской учетной записи, и игнорирует другой. ПодробнееУникальное значение идентификатора каждой площадки, используемое партнером (например, "Branch ID", "Location Code", "Store Number"). Подробнее
start_date
stringобязательныйДата начала периода снимка в формате
YYYY-MM-DD.end_date
stringобязательныйДата окончания периода снимка в формате
YYYY-MM-DD.metrics
objectобязательныйОбъект показателей с данными об участниках и выручке за период.
Объект 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"
}
}
}
Сохранение снимков отчетов
Передает операционные и финансовые показатели объекта за определенный период.
Параметры
snapshots
arrayобязательныйМассив объектов Report Snapshot для сохранения. Не более 25 элементов на запрос. Каждый элемент должен содержать либо
facility_id(обязателен, если не используетсяlinking_identifier), либоlinking_identifier(обязателен, если не используетсяfacility_id).
Возвращаемое значение
Возвращает простое сообщение, подтверждающее операцию синхронизации.
Запрос
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"
}
}
}
]
}'
Ответ
{
"message": "Report snapshot sync successful."
}
Ошибки
Partner API использует стандартные коды состояния HTTP и тела ответов в формате JSON, чтобы объяснить причину неудачного запроса.
Структура ответа с ошибкой
Большинство ошибок API возвращают тело JSON с сообщением и, если доступно, структурированными подробностями.
Коды состояния
Ошибки Access Time Windows
Проверка окон завершается ошибкой до того, как недопустимый снимок будет записан. Распространенные причины, при которых повторная попытка не поможет:
- Отсутствует
access_time_windows_revision, хотя указанaccess_time_windows. - Строковые значения, значения с плавающей запятой или значения эпохи, вероятно указанные в миллисекундах.
- Недопустимый часовой пояс IANA, перевернутый интервал, повторяющийся
external_id, пересекающиеся еженедельные блоки или неразделенный ночной блок. - Значение, выходящее за документированные ограничения по количеству, длине или продолжительности.
Повторная ревизия с другим нормализованным содержимым приводит к ошибке 409 Conflict. Выполните сверку с последним состоянием основного источника и назначьте более новую ревизию; не повторяйте попытки с конфликтующей парой. Более старая ревизия регистрируется как устаревший пропущенный снимок и не может перезаписать более новое состояние. Неизвестный или несопоставленный scope_key приводит к отказу в авторизации и должен рассматриваться как оповещение о проблеме конфигурации.
Если при доставке истекло время ожидания или получена временная ошибка 5xx, повторите отправку точно того же нормализованного снимка с той же ревизией. Если не удалось получить данные из вышестоящего источника, полностью опустите поле окон; никогда не подставляйте пустой массив.
Рекомендации по повторным попыткам
Повторяйте следующие запросы с ограниченной экспоненциальной задержкой:
429500502503504
Не повторяйте вслепую следующие запросы:
400401403404409422
В контексте контроля доступа всегда рассматривайте тайм-аут и ответы о том, что устройство не в сети, как неудачную разблокировку, если ваши собственные правила доступа и процессы безопасности не предписывают иное.
Сведения для службы поддержки
При обращении в службу поддержки укажите:
- Конечную точку и метод HTTP.
- Время и часовой пояс.
- Идентификатор ключа партнера (не сам секретный ключ).
- Использованный идентификатор объекта.
- Идентификатор исходной записи в вашей системе.
- Состояние и тело ответа.
event_idилиcommand_id, если доступны.
{
"success": false,
"message": "Request body.members[0].member_id is required"
}
Некоторые предметные конечные точки возвращают явное состояние и причину. Например, ошибки контроля доступа содержат такие поля, как reason, door_id, facility_id и 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
Запрос сформирован неправильно или в нем отсутствуют обязательные поля. Исправьте запрос, прежде чем повторять попытку.
401 Unauthorized
Ошибка аутентификации. Убедитесь, что вы используете HTTP Basic Auth с секретным ключом API в качестве имени пользователя и пустым паролем.
403 Forbidden
Ключ действителен, но операция не разрешена. Распространенные причины: использование ключа только для чтения для операции записи или попытка доступа к объекту, для которого ваша интеграция не включена.
404 Not Found
Запрошенный ресурс не найден или недоступен вашей интеграции.
409 Conflict
Запрос конфликтует с текущим состоянием ресурса. В контексте контроля доступа это может означать, что контроллер Door/Gate Controller находится в режиме обслуживания.
422 Unprocessable Entity
Запрос содержит допустимый JSON, но не проходит семантическую проверку. Исправьте данные, прежде чем повторять попытку.
429 Too Many Requests
Интеграция превысила документированное ограничение частоты запросов. Повторите попытку с экспоненциальной задержкой.
500 Internal Server Error
Performance Hub не удалось выполнить запрос из-за внутренней ошибки. Повторите попытку с задержкой. Если проблема не исчезнет, обратитесь в службу поддержки, указав конечную точку, метку времени и тело ответа.
503 Service Unavailable
Зависимая служба или устройство недоступны. При разблокировке контроллера Door/Gate Controller это может означать, что контроллер не в сети.
504 Gateway Timeout
Истекло время ожидания операции. При разблокировке контроллера Door/Gate Controller это означает, что разблокировка не была подтверждена до истечения времени ожидания.
Управление версиями
Версия Partner API указывается в URL-адресе. Текущая версия:
Политика изменений
По возможности Performance Hub стремится вносить дополняющие изменения с сохранением обратной совместимости.
Примеры изменений с обратной совместимостью:
- Добавление нового необязательного поля в запрос.
- Добавление нового поля в ответ.
- Добавление новой конечной точки.
- Добавление нового значения перечисления, если клиенты должны обрабатывать неизвестные значения.
- Улучшение сообщений проверки без изменения контракта кодов состояния.
access_time_windows и access_time_windows_revision — дополнительные поля запроса Member. У существующих клиентов, которые их не указывают, сохраненный снимок Access Time Windows остается без изменений. Это правило опускания сохраняет совместимость с частичными операциями upsert; опускание поля не равнозначно отправке пустого массива.
Примеры изменений, нарушающих совместимость:
- Удаление или переименование поля.
- Изменение типа поля.
- Превращение необязательного поля запроса в обязательное.
- Удаление конечной точки.
- Изменение значения существующего кода состояния или предметного
reason.
Вывод из использования
Если требуется изменение, нарушающее совместимость, Performance Hub по возможности не будет изменять существующую версию на месте. Вместо этого мы представим новую версию или путь миграции и сообщим об изменении затронутым партнерам.
Уведомления о выводе из использования могут включать:
- Запись в журнале изменений.
- Прямое информирование партнеров.
- Примечания в Partner Console.
- Рекомендации по миграции в документации.
Рекомендации для клиентов
Создавайте клиенты, устойчивые к дополняющим изменениям:
- Игнорируйте поля ответа, которые вы не используете.
- Рассматривайте неизвестные значения перечислений как неподдерживаемые, а не завершайте работу аварийно.
- Избегайте строгих проверок на точное совпадение ответов.
- Регистрируйте нераспознанные значения, чтобы обновлять интеграцию осознанно.
Для разделов Member с ревизиями, таких как Access Time Windows, сохраняйте отправленную ревизию и нормализованную полезную нагрузку, пока не станет известен результат. Повторное использование ревизии для измененного содержимого приводит к конфликту, а повторная отправка того же содержимого идемпотентна. См. раздел Access Time Windows.
Спецификации OpenAPI
Используйте опубликованные спецификации OpenAPI для создания клиентов, проверки запросов и отслеживания изменений структуры API со временем.
См. раздел Спецификации OpenAPI.
https://partner-api.performancehub.co/partner/v1/
Журнал изменений
В этом журнале изменений фиксируются значимые изменения Partner API и Partner Console, влияющие на работу интеграций.
2026-09-09
2026-05-06
2026-05-01
Категории изменений
В будущих записях используются следующие категории:
- Добавлено — новая конечная точка, поле, руководство или возможность.
- Изменено — изменение поведения или документации без прекращения поддержки.
- Устарело — функция остается доступной, но для нее запланирован путь миграции.
- Удалено — функция или конечная точка удалена.
- Исправлено — исправление ошибки или уточнение документации.
- Безопасность — изменение аутентификации, авторизации, обработки данных или управления ключами.
Добавлено
- Добавлены независимые от поставщика снимки
access_time_windowsучастника со смешанными абсолютными и еженедельными повторяющимися окнами. - Добавлены упорядочение по
access_time_windows_revision, идемпотентный повтор, обработка конфликтов, пропуск устаревших данных и семантика явного отзыва. - Добавлены рекомендации по часовым поясам IANA, летнему времени, логическому сопоставлению
scope_key, актуальности исходных данных, реализации на стороне поставщика данных и сертификации.
Добавлено
- Добавлена документация партнерской программы: типы партнеров, подключение, рекомендации, готовность к запуску, ошибки, управление версиями и поддержка.
- Добавлена отдельная форма запроса «Стать партнером» для потенциальных технических и коммерческих партнеров.
- Добавлена документация о том, как одобренные партнерские интеграции отображаются в каталоге партнеров Performance Hub на основной платформе Performance Hub.
Добавлено
- Добавлена документация по контролю доступа через Door/Gate Controller, включая операции получения списка, состояния и разблокировки.
- Добавлена документация по синхронной разблокировке: API возвращает успешный результат только после того, как контроллер на площадке подтвердит, что реле физически разблокировано.
- Добавлена документация по поддержке необязательного параметра
idempotency_keyв запросах на разблокировку Door/Gate Controller.