Introduction
Welcome to the 12RND & UBX Performance Hub API. This API Manages club data & key systems that integrate with your club and it's external systems systems, and is not publicly consumable API. For further information about using the various Performance Hub systems this API supports, please refer to our [Internal Wiki](https://portal.hub.gymsystems.co/wiki)'s individual entry for the system you require.
Base URL
https://portal.hub.gymsystems.co
Alternative Environments
https://portal.hub.gymsystems.co - Performance Hub API - Production
https://portal.hub.stage.gymsystems.co/ - Performance Hub API - Staging
Authentication
Authentication details will be provided when your integration is approved.
Device-reported "agent turn complete" event (web push trigger)
Called by a paired AI Agent device's sidecar (never by browsers) when a web-UI-initiated agent run finishes and ran longer than the device's notify threshold. Authenticated with a short-lived per-device HS256 JWT (aud 'events'). Deduped per device+session+start and rate-limited per device, then delivered to the initiating user's HTML5 push subscriptions with a deep link to the conversation.
Request Body
Endpoint
POST /ai/events/agent-turn-complete
Example Request
curl -X POST https://portal.hub.gymsystems.co/ai/events/agent-turn-complete \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Agent-initiated push notification (ph-notify skill)
Called by a paired AI Agent device's sidecar on behalf of the on-device agent (the ph-notify skill) to push an arbitrary notification to a user's browser and mobile devices. Authenticated with a short-lived per-device HS256 JWT (aud 'events'). The target user must have access to the device (per-agent access policy); when omitted, the notification goes to the device owner. Rate-limited per device, separately from turn-complete events.
Request Body
Endpoint
POST /ai/events/agent-notify
Example Request
curl -X POST https://portal.hub.gymsystems.co/ai/events/agent-notify \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Upload a notification image (ph-notify skill)
Accepts a raw image body from a paired device (aud 'events' JWT) and stores it in the public notify-media bucket under an unguessable UUID key. Objects auto-delete after 7 days (S3 lifecycle). Returns the public https URL for use as `imageUrl` in /ai/events/agent-notify. 5 MB cap; png/jpeg/gif/webp only.
Request Body
Endpoint
POST /ai/media/notify-image
Example Request
curl -X POST https://portal.hub.gymsystems.co/ai/media/notify-image \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List AI Agent relays (platform admin)
Returns all relay registry rows including PH-only fields and health.
Endpoint
GET /api/devices/ph-ai-agent/relays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/relays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Seed the AI Agent relay registry for this stage (platform admin)
Endpoint
POST /api/devices/ph-ai-agent/relays/seed
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/relays/seed \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert an AI Agent relay row (platform admin)
Parameters
region `string` (required)Endpoint
PUT /api/devices/ph-ai-agent/relays/{region}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/relays/{region} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete an AI Agent relay row (platform admin)
Parameters
region `string` (required)Endpoint
DELETE /api/devices/ph-ai-agent/relays/{region}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/relays/{region} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Device MCP relay for Connected Apps (external SaaS tools)
Streamable-HTTP MCP endpoint for paired AI Agent devices ("connected_apps" MCP server on the device sidecar's :8790 listener). Authenticated with a short-lived per-device HS256 JWT (aud 'mcp' — same credential as /mcp) and gated on the AGENT's Connected Apps enabled flag (connections are per agent device, not per facility). Requests stream through to the agent's own upstream tool-platform session MCP server with the session headers injected server-side; upstream credentials never reach the device. Tool names and vendor branding are white-labeled bidirectionally in transit. An upstream 401/410 (expired session) triggers one session recreation + retry.
Endpoint
POST /mcp/apps
Example Request
curl -X POST https://portal.hub.gymsystems.co/mcp/apps \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all agreements in the system
Endpoint
GET /api/admin/agreements/list-agreements
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/agreements/list-agreements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Uploads an agreement into the system.
Parameters
body `string` (required) Json object containing the agreement and parameters to add/upload to the system ...Endpoint
PUT /api/admin/agreements/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/agreements/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Uploads an agreement into the system.
Parameters
file `string` (optional) File attachment of agreement (pdf/doc)Endpoint
POST /api/admin/agreements/upload-attachment
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/agreements/upload-attachment \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists the number of agreements that are outstanding and require action based on a user and what clubs is associated with it
Endpoint
GET /api/agreements/agreements-outstanding
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agreements/agreements-outstanding \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all agreements available to a club
Parameters
club `string` (required) Internal ID of the club that you wish to access. contracts-sort `string` (optional) Sort agreements by date-effective or alphabetical. Defaults to date-effective. contracts-acknowledgement `string` (optional) Filter agreements by all, acknowledged or unacknowledged. Defaults to all. contracts-requirement `string` (optional) Filter agreements by all, signature, checkbox, popup or none. Defaults to all. contracts-status `string` (optional) Filter agreements by all, active or archived. Defaults to all.Endpoint
GET /api/agreements/list-agreements/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agreements/list-agreements/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Signs an agreement based on it's ID.
Parameters
club `string` (required) Internal ID of the club that is signing the agreement. agreementid `string` (required) ID of the agreement that is being signed. body `string` (required) Json object containing the agreement and parameters to add/upload to the system ...Endpoint
POST /api/agreements/sign/{club}/{agreementid}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agreements/sign/{club}/{agreementid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Debug Redis keys for audit logs (super-admin only)
Lists all Redis keys related to audit logs for debugging cache structure
Endpoint
GET /api/admin/audit-logs/debug-redis-keys
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/debug-redis-keys \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generate AI summary for audit log error
Uses LLM to generate a human-readable summary of an API error from audit log details
Request Body
Endpoint
POST /api/admin/audit-logs/generate-error-summary
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/audit-logs/generate-error-summary \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Query audit logs by IP address (Global Admin only)
Retrieve all API access logs from a specific IP address
Parameters
ipAddress `string` (required) IP address startTime `number` (optional) Start time (Unix timestamp) endTime `number` (optional) End time (Unix timestamp) limit `number` (optional) Maximum number of resultsEndpoint
GET /api/admin/audit-logs/query-by-ip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/query-by-ip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Query audit logs by user email (Global Admin only)
Retrieve all API access logs for a specific user
Parameters
email `string` (required) User email address startTime `number` (optional) Start time (Unix timestamp) endTime `number` (optional) End time (Unix timestamp) limit `number` (optional) Maximum number of resultsEndpoint
GET /api/admin/audit-logs/query-by-user
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/query-by-user \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search API audit logs (IAM & Admin module access)
Search and filter API access logs with advanced filtering capabilities. Users can only see logs for organisations they have access to.
Parameters
organisationId `string` (optional) Organisation ID for ACL verification (required for non-super-admin users)Request Body
Endpoint
POST /api/admin/audit-logs/search
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/audit-logs/search \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get cached audit log statistics from Redis (IAM & Admin module access)
Retrieve aggregated statistics from Redis cache for instant dashboard loading
Parameters
timeWindow `string` (optional) Time window for statistics (defaults to 12h)Endpoint
GET /api/admin/audit-logs/statistics-cached
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/statistics-cached \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get audit log statistics (IAM & Admin module access)
Retrieve aggregated statistics for the dashboard. Scoped to user's organisations.
Parameters
startTime `number` (optional) Start time (Unix timestamp), defaults to 24 hours ago endTime `number` (optional) End time (Unix timestamp), defaults to nowEndpoint
GET /api/admin/audit-logs/statistics
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/statistics \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get time series data for audit logs (IAM & Admin module access)
Retrieve bucketed time series data for request timeline visualization
Parameters
timeWindow `string` (optional) Time window for time series data: - 1h: Last 1 hour (10-minute blocks) - 12h: Last 12 hours (10-minute blocks) - 24h: Last 24 hours (10-minute blocks) - 7d: Last 7 days (1-hour blocks) - 14d: Last 14 days (1-hour blocks)Endpoint
GET /api/admin/audit-logs/timeseries
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/timeseries \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get organisations the user has access to for audit logs (IAM & Admin module access)
Returns the list of organisations the current user can view audit logs for
Endpoint
GET /api/admin/audit-logs/user-organisations
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/audit-logs/user-organisations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of clubs that implements the global agreement templates.
Endpoint
GET /api/admin/club-agreement-variation
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/club-agreement-variation \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create user agreement.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
POST /api/admin/club-user-agreements
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/club-user-agreements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of agreement.
Endpoint
GET /api/admin/club-user-agreements
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/club-user-agreements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of default config agreement from table.
Endpoint
GET /api/admin/cua-config-agreements
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/cua-config-agreements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete user agreement.
Endpoint
DELETE /api/admin/club-user-agreements/:id
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/club-user-agreements/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns specific of agreement.
Endpoint
GET /api/admin/club-user-agreements/:id
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/club-user-agreements/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update user agreement.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
PATCH /api/admin/club-user-agreements/:id
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/admin/club-user-agreements/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
The initial call to create a new club... Note only the 'template' club object is created - A second API request is then required to update the club with it's data such as Opening Hours, Location, Social URL's etc.
Parameters
body `string` (required) Json Object of the new club to add to the system.Endpoint
POST /api/admin/clubs/addclub
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/clubs/addclub \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Move a facility to a different brand/organisation
Updates a facility's brandId to move it to a different brand (and therefore organisation). Super admin only.
Parameters
club `string` (required) The facility ID to moveRequest Body
Endpoint
POST /api/admin/clubs/move-facility/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/clubs/move-facility/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Lists all agreements in the system
Endpoint
GET /api/admin/db-sync/list-tables
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/db-sync/list-tables \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Checks for unscheduled sms and schedule them, unless the send date has already passed in which case send the sms immedietly
Parameters
socketID `string` (optional) ID of the websocket (if connected) to return realtime logs to dryRun `string` (required) either a 'true' or 'false' value which specifies if you wish to perform a 'Dry Run' (Just returns a log without modifying data) or actually modify/sync tables. tables `string` (required) Array of tables to sync from prod to stageEndpoint
POST /api/admin/db-sync/sync-from-prod
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/db-sync/sync-from-prod \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns single email mapping based on id
Endpoint
GET /api/admin/email-mapping/:id
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/email-mapping/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns single faq item based on faqId
Endpoint
GET /api/admin/faqs/:faqId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/faqs/:faqId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all faq items that contains the specific category
Endpoint
GET /api/admin/faqs/category/:category
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/faqs/category/:category \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all hardware devices registered in our system & warranty information (if available)
Endpoint
GET /api/admin/hardware/all-devices
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/hardware/all-devices \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all holidays that are available to country, including global holidays and organisation-specific overrides.
Parameters
countryIso `string` (optional) Country iso. organisationId `string` (optional) Organisation ID. If not provided, returns global holidays only.Endpoint
GET /api/admin/country/{countryIso}/holidays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/country/{countryIso}/holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a country's blacklisted holidays.
Parameters
countryIso `string` (optional) Country iso. organisationId `string` (required) Organisation ID. If not provided, updates global holidays. body `string` (required)Endpoint
PUT /api/admin/country/{countryIso}/holidays
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/country/{countryIso}/holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists SMS Bulk history
Parameters
organisationId `string` (required) The organisation ID to filter the SMS history for.Endpoint
GET /api/admin/sms/message-history
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/sms/message-history \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a new SMS to one or more numbers.
Parameters
body `string` (required) Json Object with post params for new message to send.Endpoint
POST /api/admin/sms/new-message
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/sms/new-message \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Schedules an sms to be sent.
Parameters
body `string` (required) Json Object of the user data that you wish to add/update.Endpoint
POST /api/admin/sms/schedule
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/sms/schedule \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds a new user to the system
Parameters
body `string` (required) Json Object of the user data that you wish to add/update.Endpoint
POST /api/users
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/users \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Check if user is simulated
Returns true if the x-simulated-user header is present in the request
Parameters
x-simulated-user `string` (optional) Header indicating if user is simulatedEndpoint
GET /api/admin/users/is-simulated-user
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/users/is-simulated-user \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all users (Google Apps Accounts) that have access to the backoffice system/api
Endpoint
GET /api/admin/users/listusers
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/users/listusers \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List MCP keys for a user (redacted). Users can list their own keys; global admins can list any user's keys.
Parameters
userId `string` (required)Endpoint
GET /api/users/{userId}/mcp-keys
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/users/{userId}/mcp-keys \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a new MCP API key for a user. Users can create their own keys; global admins can create keys for any user.
Parameters
userId `string` (required) body `object` (optional)Endpoint
POST /api/users/{userId}/mcp-keys
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/users/{userId}/mcp-keys \
-H "x-api-key: YOUR_API_KEY"
Revoke/remove an MCP API key. Users can delete their own keys; global admins can delete any user's keys.
Parameters
userId `string` (required) keyId `string` (required)Endpoint
DELETE /api/users/{userId}/mcp-keys/{keyId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/users/{userId}/mcp-keys/{keyId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remove a role from a user
Parameters
userId `string` (optional) The email of the user you wish to remove the role from. roleId `string` (optional) The ID of the role you wish to remove from the user.Endpoint
DELETE /api/users/{userId}/roles/{roleId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/users/{userId}/roles/{roleId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remove a user from performance hub
Parameters
userId `string` (optional) The email of the user you wish to remove the role from. roleId `string` (optional) The ID of the role you wish to remove from the user.Endpoint
DELETE /api/users/{userId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/users/{userId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates an existing user's profile details (firstName, lastName, phoneNumber)
Parameters
userId `string` (required) User's email address body `object` (required) User profile data to updateEndpoint
PATCH /api/users/{userId}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/users/{userId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search Clubpass users
Endpoint
GET /api/admin/users/searchuser
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/users/searchuser \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Send welcome email to a user
Sends a welcome email with access summary, sign-in instructions, and a link to set up a password. Requires super admin access.
Parameters
userId `string` (required) Email address of the userEndpoint
POST /api/admin/users/{userId}/send-welcome-email
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/users/{userId}/send-welcome-email \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert a user role
Parameters
body `object` (optional)Endpoint
PUT /api/users/{userId}/roles
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/users/{userId}/roles \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create config block
Parameters
body `string` (required) Json Object of the new config block to add to the system.Endpoint
POST /api/admin/charges-config
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/charges-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all config blocks available to admin
Parameters
organisationId `string` (required)Endpoint
GET /api/admin/charges-config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/charges-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get config block applicable to club
Parameters
club `string` (required) hideInactive `string` (optional) Hide inactive config blocks and only return active ones showDisabledFees `string` (optional) Show all transaction type fees, including failed and chargebackEndpoint
GET /api/club/{club}/charges-config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/charges-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete an admin note from a facility.
Parameters
facilityId `string` (required) Internal ID of the facility that you wish to access. noteId `string` (required) ID of the admin note to delete.Endpoint
DELETE /api/facilities/{facilityId}/admin-notes/{noteId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/facilities/{facilityId}/admin-notes/{noteId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all admin notes for a facility.
Parameters
facilityId `string` (required) Internal ID of the facility that you wish to access. body `object` (optional)Endpoint
GET /api/facilities/{facilityId}/admin-notes
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/admin-notes \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert an admin note to a facility.
Parameters
facilityId `string` (required) Internal ID of the facility that you wish to access. body `object` (optional)Endpoint
PUT /api/facilities/{facilityId}/admin-notes
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/facilities/{facilityId}/admin-notes \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates club info in expresscart store v2.
Parameters
clubID `string` (required)Endpoint
PUT /api/admin/store/clubs/{clubID}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/store/clubs/{clubID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a new location entity on yext.
Parameters
facilityId `string` (optional) The facility ID to create the location for.Endpoint
GET /api/admin/yext/location
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/yext/location \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a location entity on yext.
Parameters
entityId `string` (optional) facilityId `string` (optional) The facility ID to delete the location for.Endpoint
DELETE /api/admin/yext/location/{entityId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/yext/location/{entityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates an existing location entity on yext.
Parameters
id `string` (required) Location id facilityId `string` (optional) The facility ID to update the location for.Endpoint
GET /api/admin/yext/location/{id}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/yext/location/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
list all listings given a club.
Parameters
clubId `string` (required)Endpoint
GET /api/admin/club/{clubId}/yext/listings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/club/{clubId}/yext/listings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create new email mapping record
Parameters
body `string` (required) Json Object of the new email mapping to add to the system.Endpoint
POST /api/admin/email-mapping/add
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/email-mapping/add \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete email mapping
Parameters
id `string` (required) ID of the email mapping body `string` (required) Json Object of email mapping that you wish to update.Endpoint
DELETE /api/admin/email-mapping/delete/{id}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/email-mapping/delete/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all email mappings
Endpoint
GET /api/admin/email-mapping
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/email-mapping \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update email mapping
Parameters
id `string` (required) ID of the email mapping body `string` (required) Json Object of club data that you wish to update.Endpoint
POST /api/email-mapping/update/{id}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/email-mapping/update/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create new faq record
Parameters
body `string` (required) Json Object of the new faq to add to the system.Endpoint
POST /api/admin/faqs/add
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/faqs/add \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete faq item
Parameters
faqId `string` (required) ID of the faq item body `string` (required) Json Object of club data that you wish to update.Endpoint
DELETE /api/admin/faqs/delete/{id}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/faqs/delete/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all faq items
Endpoint
GET /api/admin/faqs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/faqs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update faq item
Parameters
faqId `string` (required) ID of the faq item body `string` (required) Json Object of club data that you wish to update.Endpoint
POST /api/faqs/update/{id}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/faqs/update/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates new landing page
Parameters
body `string` (required) Json Object of the new landing page to add to the system.Endpoint
POST /api/admin/landing-pages
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/landing-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deletes a landing page
Parameters
body `string` (required) Json Object of the landing page to delete from the system.Endpoint
DELETE /api/admin/landing-pages
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/landing-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists landing pages
Endpoint
GET /api/admin/landing-pages
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/landing-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a landing page
Parameters
body `string` (optional) Json Object of the landing page to udpate.Endpoint
PATCH /api/admin/landing-pages
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/admin/landing-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create new press record
Parameters
body `string` (required) Json Object of the new press to add to the system.Endpoint
POST /api/admin/press/add
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/press/add \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete press item
Parameters
pressId `string` (required) ID of the press item body `string` (required) Json Object of club data that you wish to update.Endpoint
DELETE /api/admin/press/delete/{id}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/press/delete/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all press items
Endpoint
GET /api/admin/press
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/press \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns single faq item based on pressId
Endpoint
GET /api/admin/press/:pressId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/press/:pressId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update press item
Parameters
pressId `string` (required) ID of the press item body `string` (required) Json Object of club data that you wish to update.Endpoint
POST /api/press/update/{pressId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/press/update/{pressId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Billing health directory across every organisation and facility: resolved billing profile, payment settings flags (locked/paused), wallet balance for prepaid payers, the last twelve months' record statuses, and outstanding/overdue money rollups. Powers the Billing Administration applet's Directory view and its needs-attention dashboards. Super-admin only.
Parameters
includeArchived `string` (optional) Include archived facilities and their historical spend (default false).Endpoint
GET /api/admin/saas-billing/directory
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/directory \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Wallet summary + full transaction ledger + top-up invoices for any owner (facility# or org#). Super-admin only — the club-facing wallet API is scoped to the caller's facility, this one is not.
Parameters
ownerKey `string` (required) URL-encoded owner key, e.g. facility%23TestClub or org%23Org1Endpoint
GET /api/admin/saas-billing/wallets/{ownerKey}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/wallets/{ownerKey} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manual wallet adjustment. Positive amountCents credits the wallet (grant), negative debits it (correction). A note is required — it is the only audit trail on manual money movement. Credits that bring the balance above zero clear depletion markers and immediately re-evaluate lockout for facility wallets. Super-admin only.
Parameters
ownerKey `string` (required) body `string` (optional) { amountCents: integer (non-zero, positive=credit), note: string }Endpoint
POST /api/admin/saas-billing/wallets/{ownerKey}/adjust
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/wallets/{ownerKey}/adjust \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Cancel a pending top-up invoice (paid invoices cannot be cancelled). Super-admin only.
Parameters
invoiceId `string` (required)Endpoint
POST /api/admin/saas-billing/topup-invoices/{invoiceId}/cancel
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/topup-invoices/{invoiceId}/cancel \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Consolidated organisation monthly records (org#
Parameters
organisationId `string` (required)Endpoint
GET /api/admin/saas-billing/org/{organisationId}/monthly-records
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/org/{organisationId}/monthly-records \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List every billing profile row (org profiles + facility overrides). Super-admin only.
Endpoint
GET /api/admin/saas-billing/billing-profiles
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create or update a billing profile row. Super-admin only.
Parameters
body `string` (optional) { ownerKey: 'org#Endpoint
PUT /api/admin/saas-billing/billing-profiles
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Snapshot outstanding monthly records (and a negative prepaid wallet) before a billing-method flip. Super-admin only. Query `to` is the intended billingMethod after save.
Parameters
ownerKey `string` (optional) 'org#Endpoint
GET /api/admin/saas-billing/billing-profiles/migration-preflight/{ownerKey}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles/migration-preflight/{ownerKey} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a billing profile row so the owner falls back to inheritance (facility override -> org profile -> platform default). Super-admin only.
Parameters
ownerKey `string` (optional) 'org#Endpoint
DELETE /api/admin/saas-billing/billing-profiles/{ownerKey}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles/{ownerKey} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Preview the EFFECTIVE billing profile a facility resolves to (facility override -> org profile -> platform default) with per-field sources for inheritance display. Super-admin only.
Parameters
clubID `string` (optional) Facility IDEndpoint
GET /api/admin/saas-billing/billing-profiles/resolve/{clubID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles/resolve/{clubID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Preview the effective billing profile at ORGANISATION scope (org profile -> platform default). Super-admin only.
Parameters
organisationId `string` (optional) Organisation IDEndpoint
GET /api/admin/saas-billing/billing-profiles/resolve-org/{organisationId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/billing-profiles/resolve-org/{organisationId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Model Router admin summary for a facility
Facility row, prepaid ledger, live-effective remaining, auto-recharge, pause flag, and recent money-movement transactions. Super-admin only.
Parameters
clubID `string` (required)Endpoint
GET /api/admin/saas-billing/model-router/facilities/{clubID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Grant or debit Model Router credits
Positive amountCents grants complimentary credit (no card charge). Negative amountCents claws back unused credit. Note is required. Super-admin only. Cap is $5,000 per operation.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/admin/saas-billing/model-router/facilities/{clubID}/adjust
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/adjust \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Pause or resume Model Router inference
Sets inferencePaused on the facility row. The /ai prepaid gate returns 402 while paused, independent of remaining credits. Super-admin only.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/admin/saas-billing/model-router/facilities/{clubID}/pause
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/pause \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable or disable Model Router auto-recharge
Turns auto-recharge off (nulls threshold and amount so the cron will not charge) or on (requires thresholdCents and amountCents). Super-admin only.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/admin/saas-billing/model-router/facilities/{clubID}/auto-recharge
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/auto-recharge \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Model Router transaction ledger for a facility
Parameters
clubID `string` (required) limit `string` (optional) types `string` (optional) from `string` (optional) to `string` (optional)Endpoint
GET /api/admin/saas-billing/model-router/facilities/{clubID}/transactions
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/transactions \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Top-up receipt PDF (admin)
Parameters
clubID `string` (required) txId `string` (required)Endpoint
GET /api/admin/saas-billing/model-router/facilities/{clubID}/transactions/{txId}/receipt.pdf
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/transactions/{txId}/receipt.pdf \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Monthly Model Router usage rollups (admin)
Parameters
clubID `string` (required) months `string` (optional)Endpoint
GET /api/admin/saas-billing/model-router/facilities/{clubID}/usage-statements
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/usage-statements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Monthly usage statement PDF (admin)
Parameters
clubID `string` (required) month `string` (required)Endpoint
GET /api/admin/saas-billing/model-router/facilities/{clubID}/usage-statements/{month}/statement.pdf
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/model-router/facilities/{clubID}/usage-statements/{month}/statement.pdf \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Billing and revenue analytics for one organisation: monthly billed vs collected vs outstanding series, AR aging buckets, revenue by facility, revenue by charge category, and headline totals. Powers the Analytics view in the Billing Administration applet. Super-admin only.
Parameters
organisationId `string` (required) months `string` (optional) Lookback window in months (default 12, max 24). clubID `string` (optional) When set, analytics are scoped to this facility (must belong to the organisation). Billed-to-org facility records count in the receivable series here so the facility still sees its contribution. includeArchived `string` (optional) Include archived facilities in the organisation analytics (default false).Endpoint
GET /api/admin/saas-billing/org/{organisationId}/analytics
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/org/{organisationId}/analytics \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Reconcile an incoming payment against its money artifact by universal payment reference (XXXX-XXXX). Resolves wallet top-ups, top-up invoices (credits the wallet exactly once) and monthly records (marks paid). Idempotent — matching a settled reference is a reported no-op. Super-admin only.
Parameters
body `string` (optional) { reference: 'XXXX-XXXX', amountCents?: number (verified against the artifact when provided), paidAt?: unix seconds, source?: e.g. 'bank-transfer'|'ai-matcher', notes?: string, force?: boolean (override an amount mismatch) }Endpoint
POST /api/admin/saas-billing/payments/match
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/payments/match \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Platform-wide billing and revenue analytics for the Insights tab: MRR and growth, billed vs collected vs outstanding by month, AR aging, revenue by category and organisation, net-revenue movement, billed units, billing-run health, prepaid wallet float, and Model Router spend. Super-admin only. Cached in-process for 5 minutes.
Parameters
months `string` (optional) Lookback window in months (default 12, max 24). refresh `string` (optional) Pass 1 to bypass the in-process cache. includeArchived `string` (optional) Include archived facilities in all analytics (default false).Endpoint
GET /api/admin/saas-billing/platform-analytics
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/platform-analytics \
-H "x-api-key: YOUR_API_KEY"
Response
{}
The persisted platform-wide rate block (reserved org 'PLATFORM'), or the code defaults when none has been saved yet. Super-admin only.
Endpoint
GET /api/admin/saas-billing/platform-rates
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/platform-rates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert the platform-wide rate block. All charge keys must be non-negative numbers; chargeAdjustments is optional (percent / amountOffPerUnit / includedUnits per charge key). Changes take effect from the next daily billing log — never retroactively. Super-admin only.
Parameters
body `string` (optional) { charges: { pricePerGBStored, ... }, chargeAdjustments?: {Endpoint
PUT /api/admin/saas-billing/platform-rates
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/saas-billing/platform-rates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all pricing templates (reserved org 'TEMPLATE'). Super-admin only.
Endpoint
GET /api/admin/saas-billing/rate-templates
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/rate-templates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a pricing template. Requires a name plus a full charges object; chargeAdjustments, cloudAgents and customCharges are optional. Super-admin only.
Parameters
body `string` (optional) { name, description?, charges: { pricePerGBStored, ... }, chargeAdjustments?: {Endpoint
POST /api/admin/saas-billing/rate-templates
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/rate-templates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Duplicate a pricing template. The copy carries the source's rates, discounts, cloud-agent overlay and custom charges, but starts with an empty change log and no linked blocks. Names itself "
Parameters
templateId `string` (required) body `string` (optional) { name? } — omit to take the auto-generated copy name.Endpoint
POST /api/admin/saas-billing/rate-templates/{templateId}/duplicate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/saas-billing/rate-templates/{templateId}/duplicate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a pricing template (name, charges, chargeAdjustments, cloudAgents and/or customCharges). Fields the request omits keep their stored value, so a rates-only save never wipes custom charge rules. Prior versions are preserved in the template's changeLog, and the new values fan out to every rate block still following the template. Super-admin only.
Parameters
templateId `string` (required) body `string` (optional) { name, description?, charges, chargeAdjustments?, cloudAgents?, customCharges? }Endpoint
PUT /api/admin/saas-billing/rate-templates/{templateId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/saas-billing/rate-templates/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Soft-delete a pricing template. Blocks still linked to it are detached (they keep their current values). Super-admin only.
Parameters
templateId `string` (required)Endpoint
DELETE /api/admin/saas-billing/rate-templates/{templateId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/saas-billing/rate-templates/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get list of active services (Super Admin only)
Retrieve list of services that have logged API calls in the past 7 days. Used to populate service selector in dashboard. Super admin access required.
Endpoint
GET /api/admin/service-logs/active-services
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/service-logs/active-services \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Query multi-service API logs (Super Admin only)
Query and filter API logs from multiple services (partner-api, universal-api, etc.) with advanced filtering capabilities. Super admin access required.
Request Body
Endpoint
POST /api/admin/service-logs/query
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/service-logs/query \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get cached multi-service log statistics from Redis (Super Admin only)
Retrieve aggregated statistics from Redis cache for instant dashboard loading. Falls back to DynamoDB if cache miss. Super admin access required.
Parameters
serviceId `string` (optional) Service ID to get statistics for (required) timeWindow `string` (optional) Time window for statistics (defaults to 24h)Endpoint
GET /api/admin/service-logs/statistics
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/service-logs/statistics \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get time series data for timeline chart (Super Admin only)
Retrieve time-bucketed request/error counts for rendering timeline charts. Super admin access required.
Parameters
serviceId `string` (required) Service ID to get time series for (e.g., 'partner-api', 'universal-api') timeWindow `string` (optional) Time window for time series data (defaults to 24h)Endpoint
GET /api/admin/service-logs/timeseries
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/service-logs/timeseries \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Find clubs with missing additional charges for a given month. This helps identify clubs that should have had region-based additional items applied but didn't (due to the localisation.country bug).
Parameters
month `string` (required) The billing month to check in YYYY-MM format organisationId `string` (optional) Optional organisation ID to filter clubs countryIso `string` (optional) Optional country ISO code to filter clubs (e.g. JP, AU) limit `integer` (optional) Maximum number of clubs to return in the results update `boolean` (optional) If true, adds missing charges to the CCTV billing record for the first day of the given monthEndpoint
GET /api/admin/tasks/backfill-missing-billing-base-charges
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/backfill-missing-billing-base-charges \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add organisation IDs to billing-related records for the new role integration.
Endpoint
GET /api/admin/tasks/billing-migrations
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/billing-migrations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Start the brand regions migration task
Endpoint
GET /api/admin/tasks/brand-regions-migration
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/brand-regions-migration \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually forces GymMaster to start 'syncing' all member data
Endpoint
GET /api/admin/tasks/build-peak-time-insights
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/build-peak-time-insights \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Start the cache mms users cron job.
Parameters
facilityIds `string` (optional) Optional list of facility IDs to cache the users for. userIds `string` (optional) Optional list of user IDs to cache the users for. checkCache `string` (optional) Optional flag to check the cache before querying the database.Endpoint
GET /api/admin/tasks/cache-mms-users
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/cache-mms-users \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually triggers the CCTV heatmap pregeneration Lambda which fans out SQS messages per device to generate heatmaps.
Endpoint
GET /api/admin/tasks/cctv-heatmap-pregeneration
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/cctv-heatmap-pregeneration \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually triggers the CCTV retention cleanup Lambda (timelapse + AI metadata older than club retention).
Endpoint
GET /api/admin/tasks/cctv-retention-cleanup
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/cctv-retention-cleanup \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete old audit logs (Global Admin only)
Remove audit logs older than specified days (default 90 days) for log rotation/management
Request Body
Endpoint
POST /api/admin/tasks/cleanup-old-audit-logs
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/tasks/cleanup-old-audit-logs \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Run stripe daily payments report cron
Endpoint
GET /api/admin/tasks/daily-payments-report
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/daily-payments-report \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Save a daily saas billing log to DynamoDB for all clubs
Endpoint
GET /api/admin/tasks/daily-saas-billing-log
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/daily-saas-billing-log \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete notifications older than 30 days to improve performance
Endpoint
GET /api/admin/tasks/delete-old-notifications
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/delete-old-notifications \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Triggers club variables function
Parameters
clubId `string` (optional)Endpoint
GET /api/admin/tasks/clubs/{clubId}/variables
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/clubs/{clubId}/variables \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Triggers low battery duress notifications for all clubs.
Parameters
clubId `string` (optional)Endpoint
GET /api/admin/tasks/low-battery-duress-notifs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/low-battery-duress-notifs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
One-off migration that rewrites legacy moduleIds (e.g. ai-model-access -> ai-credits) stored in organisations, brands, club preferences and roles. Runs as a dry-run by default; pass ?apply=true to persist changes.
Parameters
apply `boolean` (optional) When true, persists changes. Otherwise only reports what would change.Endpoint
GET /api/admin/tasks/migrate-module-ids
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/migrate-module-ids \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add default ids, objects, etc for the new role integration.
Endpoint
GET /api/admin/tasks/role-migrations
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/role-migrations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Checks for unscheduled sms and schedule them, unless the send date has already passed in which case send the sms immediately
Endpoint
GET /api/admin/tasks/sms-schedule
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/sms-schedule \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually trigger a full directory sync for all enabled facilities.
Endpoint
GET /api/admin/tasks/start-directory-sync
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/start-directory-sync \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Start the monthly biller cron job.
Parameters
clubID `string` (optional) Optional club ID to run the monthly biller for. forceBilling `string` (optional) Optional flag to force billing for the club. billingMonth `string` (optional) Optional billing month to run the monthly biller for in the format YYYY-MM. simulationTime `string` (optional) Optional unix timestamp to simulate the cron job running at. This will override the billing month. organisationId `string` (optional) Optional organisation ID to run the monthly biller for.Endpoint
GET /api/admin/tasks/monthly-biller
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/monthly-biller \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually forces GymMaster to start 'syncing' all member data
Endpoint
GET /api/admin/tasks/sync-gm-data
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/sync-gm-data \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually forces GymMaster to start 'syncing' revenue history for our clubs
Parameters
startDate `string` (optional) Start date to report from (YYYY-MM-DD format). endDate `string` (optional) End date to report to (YYYY-MM-DD format).Endpoint
GET /api/admin/tasks/sync-gm-revenue-history
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/sync-gm-revenue-history \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update all clubs yext data.
Endpoint
GET /api/admin/tasks/update-all-clubs-yext-data
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/update-all-clubs-yext-data \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually starts updating the holiday hours of all clubs
Endpoint
GET /api/admin/tasks/club-holidays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/club-holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually starts updating the holidays of all countries
Endpoint
GET /api/admin/tasks/country-holidays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/country-holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually starts the cron that auto publishes 5 star reviews to our club pages
Endpoint
GET /api/admin/tasks/published-reviews
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/published-reviews \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually forces our cron to update club social reviews...
Endpoint
GET /api/admin/tasks/update-social-reviews
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/update-social-reviews \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get all modules available to a facility
Invokes the facility-modules Lambda to return modules for the given facility (facility preferences → brand → organisation hierarchy).
Parameters
facilityId `string` (required) The facility (club) ID.Endpoint
GET /api/admin/tasks/facilities/:facilityId/modules
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/tasks/facilities/:facilityId/modules \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get effective modules for a facility
Returns all modules available to a facility by resolving the hierarchy: facility preferences → brand modules → organisation modules. Results are cached in Redis for performance.
Parameters
facilityId `string` (required) The facility ID to resolve modules forEndpoint
GET /api/facilities/{facilityId}/modules
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/modules \
-H "x-api-key: YOUR_API_KEY"
Response
[]
Returns the module catalog plus the side-menu rendering config. The full module list is returned (including globalAdminOnly entries) so the front-end renderer can decide visibility per user; ACL is still enforced server-side via `auth.checkModuleAccess()`.
Endpoint
GET /api/modules
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/modules \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Sends a notification to all clubs that have failed payments.
Parameters
fromDate `string` (optional) Unix timestamp toDate `string` (optional) Unix timestampEndpoint
POST /api/admin/tasks/send-failed-club-payments-notif
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/tasks/send-failed-club-payments-notif \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates all club payment intents for the last 14 days.
Endpoint
PUT /api/admin/tasks/update-all-club-failed-payments-for-14-days
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/tasks/update-all-club-failed-payments-for-14-days \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List the stripe connected account details for all clubs in an organisation
Parameters
organisationId `string` (required)Endpoint
GET /api/clubs/stripe/connected-account
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/stripe/connected-account \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List stripe records of club.
Parameters
club `string` (required) fromDate `string` (optional) Unix timestamp toDate `string` (optional) Unix timestamp socketID `string` (required) Unique identifier for socket requestEndpoint
GET /api/club/{club}/stripe/records
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/records \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Cancel a payment intent
Parameters
club `string` (required) paymentIntent `string` (optional)Endpoint
GET /api/club/{club}/stripe/payment-intent/:paymentIntent/cancel
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/payment-intent/:paymentIntent/cancel \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a Stripe Account Session for embedded components
Creates a Stripe Account Session for a connected account. Returns a client_secret used to initialize Connect embedded components (disputes, payouts, account management, documents).
Request Body
Endpoint
POST /api/stripe/account-session
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/stripe/account-session \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Enables Apple Pay and Google Pay
Parameters
club `string` (required)Endpoint
GET /api/club/{club}/stripe/enable-apple-pay-google-pay
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/enable-apple-pay-google-pay \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generates a one-time-link for the Stripe KYC page for a connected account.
Parameters
club `string` (required)Endpoint
GET /api/club/{club}/stripe/generate-kyc-token
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/generate-kyc-token \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieve a payment intent from stripe.
Parameters
paymentIntentId `string` (optional)Endpoint
GET /api/stripe/payment-intents/{paymentIntentId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/stripe/payment-intents/{paymentIntentId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
returns the platform stripe account id
Endpoint
GET /api/stripe/platform-connected-account-id
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/stripe/platform-connected-account-id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
returns the stripe publishable key
Endpoint
GET /api/stripe/publishable-key
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/stripe/publishable-key \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List stripe balance transactions of club.
Parameters
club `string` (required) payout `string` (optional) type `string` (optional)Endpoint
GET /api/club/{club}/stripe/balance-transactions
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/balance-transactions \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List stripe payment intents of club.
Parameters
club `string` (required) fromDate `string` (optional) Unix timestamp toDate `string` (optional) Unix timestampEndpoint
GET /api/club/{club}/stripe/payment-intents
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/payment-intents \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List stripe payouts of club.
Parameters
club `string` (required) fromDate `string` (optional) Unix timestamp toDate `string` (optional) Unix timestampEndpoint
GET /api/club/{club}/stripe/payouts
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/payouts \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List club stripe charges.
Parameters
club `string` (required) fromDate `string` (optional) Unix timestamp toDate `string` (optional) Unix timestampEndpoint
GET /api/club/{club}/stripe/charges
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/charges \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets the account details for a Stripe connected account as part of the KYC process.
Parameters
club `string` (required)Endpoint
GET /api/club/{club}/stripe/connect-account-details
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/{club}/stripe/connect-account-details \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Live Services running on a facility's AI Agent (publish picker)
Fetches the device's bridge-detected Live Services over the tunnel for the applet's "Publish to Performance Hub" picker. Requires the ph-ai-agent module AND 'open' per-device access (same bar as publishing itself). Each service is annotated with publishedAppId when a Custom App already exists for its port.
Parameters
club `string` (required) device `string` (required)Endpoint
GET /api/agent-apps/services/{club}/{device}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/services/{club}/{device} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
MDI icon name index baked into a facility's AI Agent (icon picker)
Proxies the device bridge's baked MDI icon index (GET /__services/icons/mdi/index.json) over the tunnel. The publish/edit picker uses the applet's bundled catalog (same 7.4.47 pin); published-app SVGs are resolved from portal-server's local @mdi/js pack. Same access bar as the services picker (ph-ai-agent module + 'open' per-device access).
Parameters
club `string` (required) device `string` (required)Endpoint
GET /api/agent-apps/mdi-index/{club}/{device}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/mdi-index/{club}/{device} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Fetch a batch of MDI icon SVGs from a facility's AI Agent (picker previews)
Resolves up to 60 named MDI glyphs from the device's baked icon set in one call, sanitised server-side with the same allowlist applied to persisted app icons. Used by the icon picker to render search results; unknown names come back null.
Parameters
club `string` (required) device `string` (required)Request Body
Endpoint
POST /api/agent-apps/mdi-icons/{club}/{device}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/mdi-icons/{club}/{device} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Audience scopes the requester may publish to from this facility
The publisher's grantable audience envelope for the publish/edit picker: the facilities their ph-ai-agent roles reach (multi-facility scope), plus whether they hold the organisation-level standing required for whole-brand / whole-organisation audiences at this facility's brand/org. The same rules are re-enforced server-side on publish/update (validatePublishAudience) — this endpoint only shapes the UI.
Parameters
club `string` (required)Endpoint
GET /api/agent-apps/audience-options/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/audience-options/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Autocomplete peers for a named-users app audience
Searches ONLY the users the requester can already see — people whose roles overlap at least one facility/region/organisation of the requester's own ph-ai-agent access. A minimum 2-character query and a 10-result cap keep the endpoint useless for scraping; the same reachability set is re-enforced server-side when the audience is saved.
Parameters
club `string` (required) q `string` (required)Endpoint
GET /api/agent-apps/user-search/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/user-search/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Publish an AI Agent Live Service as a Performance Hub Custom App
Registers a web app hosted by the facility's AI Agent (a bridge-detected Live Service) as a "Custom Apps" side-menu item for the chosen audience. Requires the ph-ai-agent module at this facility AND 'open' per-device access; the audience is capped by the publisher's own role scopes (you can never publish wider than you can reach). Service identity is resolved LIVE from the device's /__services list; the http/https scheme is never persisted.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-apps/publish/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/publish/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Published Custom Apps visible at this facility
Returns the active published apps whose audience covers this facility, in the shape the side menu renders (appId, name, icon, description). Audience is re-resolved live on every call so access changes take effect immediately.
Parameters
club `string` (required)Endpoint
GET /api/agent-apps/menu/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/menu/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Published apps managed from this facility (publisher view)
Full app rows for apps whose HOME facility is this club, for the applet's "Published Apps" manage list. Each row is annotated with canManage for the requesting user (publisher or global admin).
Parameters
club `string` (required)Endpoint
GET /api/agent-apps/manage/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/manage/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Mint a service-scoped viewer token for a published Custom App
Returns a short-lived signed URL + token the browser uses to open ONE published app directly on the device's regional relay gateway. The token carries a svc claim naming the service port, so the gateway confines the session to /__services/proxy/
Parameters
club `string` (required) appId `string` (required)Endpoint
POST /api/agent-apps/access/{club}/{appId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/access/{club}/{appId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Support attribution for a published Custom App (owner contact)
Who supports this user-published app: the publisher's email (falling back to the hosting agent's owner). Shown on the viewer's offline/error panels so support requests go to the app's owner instead of Performance Hub — published apps are not part of PH core support. The app's audience is re-checked first; viewers the app was never shared with learn nothing. Paused apps still resolve (owners field "why is this paused?" questions too).
Parameters
club `string` (required) appId `string` (required)Endpoint
GET /api/agent-apps/support-info/{club}/{appId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-apps/support-info/{club}/{appId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Email a support request to a published Custom App's owner
Sends the viewer's message to the app's support contact (publisher, falling back to the agent owner) as a branded email — To the owner, CC the viewer (their record of the request), Reply-To the viewer so the owner replies straight to them. Published apps are user-maintained, so this keeps their support off Performance Hub's queue. Audience is re-checked; one request per viewer per app per 15 minutes (Redis cooldown, fail-open).
Parameters
club `string` (required) appId `string` (required)Request Body
Endpoint
POST /api/agent-apps/support-request/{club}/{appId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/support-request/{club}/{appId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Update a published Custom App (name, icon, description, status, audience)
Publisher (or global admin) only. Audience changes are re-validated against the EDITOR's role scopes with the same capping rules as publish. Status toggles between active and paused (paused apps vanish from menus and refuse mints).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-apps/update/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/update/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Unpublish a Custom App (soft delete)
Publisher (or global admin) only. Soft-deletes the registry row - the app disappears from menus immediately and viewer mints refuse; already-issued gateway sessions lapse at token expiry.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-apps/unpublish/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/unpublish/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Transfer ownership of a published Custom App
Mirrors the AI Agent reallocate-owner flow: the current publisher, an account owner (billing module) or a global admin may hand the app to another user, who then manages it. The new owner must have facility access at the app's home club.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-apps/transfer-owner/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-apps/transfer-owner/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Full scan report (+ LLM review) for one skill version
The complete findings list for a version — publisher, organisation admins (approval reviews) and global admins only; installers see the summarised counts on the skill detail instead.
Parameters
club `string` (required) skillId `string` (required) version `string` (required)Endpoint
GET /api/agent-skills/scan-report/{club}/{skillId}/{version}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/scan-report/{club}/{skillId}/{version} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Submit a draft skill version (publish, or queue for approval)
Moves a draft version forward per the organisation's governance. When the org has opted into LLM review the instruction review runs first (best-effort; a 'fail' verdict rejects, a 'flag' verdict forces the approval queue). Facility- tier shares publish immediately unless governance requires approval; org- library shares (brand/organisation audience) default to requiring approval. Publishing sets the skill's latestVersion — 'auto'-policy installs pick it up on the next reconcile sweep.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/submit/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/submit/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Skill library visible at this facility (audience-filtered)
Active skills with at least one published version whose audience covers this facility (or names the viewer), annotated with the latest published version summary and the org-adoption footprint (distinct facilities, never raw install counts). Audience is re-resolved live on every call.
Parameters
club `string` (required)Endpoint
GET /api/agent-skills/library/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/library/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Skill detail (versions, requirements, scan summary, adoption)
Full detail for one library skill: version history with changelogs and scan summaries (per-version endpoint lists power the update scan-diff), declared requirements from the manifest, publisher provenance and the facility-count adoption signal. The audience is re-checked — viewers a skill was never shared with learn nothing (the publisher and org admins always see it).
Parameters
club `string` (required) skillId `string` (required)Endpoint
GET /api/agent-skills/skill/{club}/{skillId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/skill/{club}/{skillId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Skills published from this facility (publisher's manage list)
Full skill rows whose HOME facility is this club, each annotated with canManage for the requesting user and its latest version summary (drafts and pending approvals included — this is the publisher's working view).
Parameters
club `string` (required)Endpoint
GET /api/agent-skills/manage/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/manage/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Install a library skill onto a facility's AI Agent
Governance-gated: the org's installSources must allow it, the skill's audience must cover this facility (or name the requester), the version must be published, and the requester must clear the whoCanInstall tier for the target device (owner / allowed user / facility admin / org admin — see governance). Writes the install lifecycle row (the source of truth) and makes an immediate best-effort push; the reconcile cron guarantees delivery once the device is reachable.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/install/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/install/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Approve a pending skill update for one install
Moves the install's desiredVersion to the latest published version (the 'notify' and 'pinned' policies' manual step, and the path when governance sets updatePosture 'approvalRequired'). Keeps the current version as the one-step rollback target and clears any post-rollback update pin (skipVersion). Same whoCanInstall permission tier as install.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/update-approve/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/update-approve/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Roll an installed skill back to its previous version
Sets desiredVersion to the install row's previousVersion (kept on every version move) and lets the normal delivery path re-install it. One-step: the versions swap, so rolling back twice returns to where you started. Also pins updates (skipVersion = the version rolled back from) so the auto/notify policies leave the rollback in place — the pin clears when a strictly newer version publishes, on update-approve, or on set-policy.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/rollback/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/rollback/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Uninstall a skill from a facility's AI Agent
Marks the install row pending-uninstall and pushes the desired state; the row is deleted once the device confirms removal (reconcile read-back). Same whoCanInstall permission tier as install.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/uninstall/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/uninstall/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Set the per-install update policy for a skill on one device
auto (reconcile applies new published versions automatically, unless the org's updatePosture requires approval), notify (owner is notified once per new version and applies it manually) or pinned (never moves without an explicit update-approve). Changing the policy clears any post-rollback update pin (skipVersion). Same whoCanInstall permission tier as install.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/set-policy/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/set-policy/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Skill installs on a facility's AI Agent (Skills tab)
The install lifecycle rows for one device, each annotated with the skill's listing fields and whether a newer published version exists. Requires 'open' per-device access (the Skills tab lives inside the agent drawer).
Parameters
club `string` (required) device `string` (required)Endpoint
GET /api/agent-skills/installs/{club}/{device}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/installs/{club}/{device} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Skill versions awaiting approval in this facility's organisation
The org-admin approval queue: every pending-approval version across the organisation's skills, with the skill listing and scan/LLM summaries. Organisation admins (or global admins) only.
Parameters
club `string` (required)Endpoint
GET /api/agent-skills/approvals/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/approvals/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Approve a pending skill version (publishes it)
Organisation admins (or global admins) only. The version becomes published, the skill's latestVersion moves, and the publisher is notified. 'auto'-policy installs pick the version up on the next reconcile sweep.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/approve/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/approve/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Reject a pending skill version
Organisation admins (or global admins) only. The version becomes rejected with the reviewer's reason and the publisher is notified — they can fix the findings and submit a new version (versions are immutable).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/reject/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/reject/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Effective Agent Skill governance for this facility's organisation
The stored per-org policy merged over the platform defaults (an org with no stored row sees pure defaults). Organisation admins (or global admins) only.
Parameters
club `string` (required)Endpoint
GET /api/agent-skills/governance/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/agent-skills/governance/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update Agent Skill governance for this facility's organisation
Partial update — only the supplied fields move; everything else keeps its stored/default value. Organisation admins (or global admins) only. Per-device overrides live on the registration row via the existing device config routes.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/agent-skills/governance/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/governance/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Kill switch — revoke a skill version and quarantine every install
Global admins only. Marks the named version (or EVERY published version when omitted) revoked, recomputes the skill's latestVersion, and fans a desired action 'quarantine' with the reason across every affected install (skillId GSI) — the device moves the skill aside (never silently deletes) on the next push/reconcile. Each install's device owner is notified.
Request Body
Endpoint
POST /api/agent-skills/admin/revoke
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/agent-skills/admin/revoke \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get environment data for a facility
Returns current weather conditions including sunrise/sunset (via Open-Meteo) and indoor facility temperature (from duress sensors) for the specified club. Cached in Redis for 30 minutes.
Parameters
clubId `string` (required) Internal ID of the club/facilityEndpoint
GET /api/clubs/{clubId}/environment
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubId}/environment \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/associates a generic IoT device with a club.
Parameters
club `string` (required) Internal ID of the club that you wish to add the device under. body `string` (required) Json Object of the new screen to associate with.Endpoint
POST /api/devices/addGenericDevice/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/addGenericDevice/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remove and factory-reset a display screen
Removes the screen's active facility association and arms a durable factory reset. A powered-off screen applies the reset after it next powers on and reconnects, then returns to its HDMI pairing page. Historical billing records are retained.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/display-screens/reset/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/display-screens/reset/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Associates a door controller with a facility.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/door-controllers/associate/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/door-controllers/associate/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Updates door controller settings for a facility.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/door-controllers/update/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/door-controllers/update/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Decommissions a door controller from a facility.
Parameters
club `string` (required)Endpoint
POST /api/devices/door-controllers/decommission/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/door-controllers/decommission/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the relay configuration for a door controller.
Parameters
uuid `string` (required)Endpoint
GET /api/devices/door-controllers/config/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/door-controllers/config/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the metadata of the device
Parameters
uuid `string` (required) Unique ID of the deviceEndpoint
GET /api/devices/metadata/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/metadata/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the metadata of the device. Response is the metadata row at the top level (legacy shape) plus `detectedType` (camera | ai-edge-processor | door-controller | ph-ai-agent | null) and `online` (true when updated within 5 minutes).
Parameters
deviceSerialNumber `string` (required) Serial Number of the deviceEndpoint
GET /api/devices/metadata/serial/{serialNo}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/metadata/serial/{serialNo} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the smart club data for the club.
Parameters
club_id `string` (required) Internal ID of the club that you wish to add the device under.Endpoint
GET /api/clubs/{club_id}/smart-club-data
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club_id}/smart-club-data \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all devices associated with an individual club.
Parameters
club `string` (required) Internal ID of the club that you wish to list devices from.Endpoint
GET /api/devices/list/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/list/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all application releases (versions) for our balena devices..
Endpoint
GET /api/devices/listReleases
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/listReleases \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Moves a device to a new facility (club) and updates related systems.
Parameters
club `string` (required) Source facility ID (current club the device is in) body `object` (required) Move parametersEndpoint
POST /api/devices/move/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/move/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Attempts to establish a connection to a facility's router by selecting the best in-club device and sending an MQTT command to create a tunnel.
Parameters
facilityID `string` (required) Internal ID of the facility for which the router connection is being attempted.Endpoint
GET /api/devices/openRouterWebpage/{facilityID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/openRouterWebpage/{facilityID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Cloud agent catalog (zones, sizes, live sell prices)
Parameters
club `string` (required)Endpoint
GET /api/devices/ph-ai-agent/cloud/catalog/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/catalog/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Quote a cloud agent (software + hosting)
Endpoint
POST /api/devices/ph-ai-agent/cloud/quote/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/quote/{club} \
-H "x-api-key: YOUR_API_KEY"
Launch a cloud agent (enqueue provision + auto-associate)
Endpoint
POST /api/devices/ph-ai-agent/cloud/launch/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/launch/{club} \
-H "x-api-key: YOUR_API_KEY"
Cloud agent job status
Endpoint
GET /api/devices/ph-ai-agent/cloud/jobs/{club}/{jobId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/jobs/{club}/{jobId} \
-H "x-api-key: YOUR_API_KEY"
Purge a cloud agent (VM + balena + registration)
Endpoint
POST /api/devices/ph-ai-agent/cloud/delete/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/delete/{club} \
-H "x-api-key: YOUR_API_KEY"
Resolve a parked cloud agent removal (retry backup, delete without backup, or cancel)
Endpoint
POST /api/devices/ph-ai-agent/cloud/delete-decision/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/cloud/delete-decision/{club} \
-H "x-api-key: YOUR_API_KEY"
Platform cloud-agent catalog (super-admin)
Endpoint
GET /api/admin/devices/ph-ai-agent/cloud/catalog
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/devices/ph-ai-agent/cloud/catalog \
-H "x-api-key: YOUR_API_KEY"
List an agent's Connected Apps (suites + apps with connected accounts)
Returns the agent's Connected Apps state: the enabled flag, per-suite rollups (Google Workspace, Microsoft 365) and the curated app catalog with each app's connected accounts (multi-account — an agent can hold several accounts per app, each with an optional alias) resolved from the agent's upstream session.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Endpoint
GET /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Full Connected Apps marketplace catalog for an agent
Returns every connectable app (the full managed-auth toolkit catalog, cached server-side for ~12h) with featured/suite tiers and the agent's connected accounts per app, plus per-suite rollups and the agent's pending connect requests — one payload for the client-side-searchable apps marketplace.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Endpoint
GET /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/catalog
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/catalog \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Dismiss a pending agent connect request
Marks the agent's pending connect request for a toolkit as dismissed (it disappears from the marketplace's "Requested by your agent" section). Idempotent — dismissing a request that isn't pending is a no-op.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/requests/dismiss
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/requests/dismiss \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Enable or disable Connected Apps for an agent
Persists the agent's Connected Apps switch and pushes the PH_APPS_MCP_ENABLED Balena device variable to that one device (best-effort — the PH-side flag is the hard gate on the MCP relay).
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/enable
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/enable \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Start connecting a single app to an agent (Connect Link OAuth flow)
Initiates a hosted Connect Link flow for one toolkit and returns the URL to send the user to. An optional alias labels the new account (multi-account — connecting an already connected app adds ANOTHER account, up to 10 per app). Runs through the same chaining callback as suite connects (a one-toolkit suite), so completion lands back on the ph-ai-agent applet page.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Connect preparation payload for one app (mode, credential fields, setup guide)
Everything the connect dialog needs before starting a connection: how the app connects (oauth = hosted consent flow, credentials = in-product form), the credential fields to collect for credentials mode, and the in-product setup guide (authored for priority apps, otherwise generated from the app's field metadata — never a link to external docs). Bring-your-own OAuth apps also carry whether the customer's OAuth app is registered for THIS agent yet (byoConfigured) and the redirect URL to register with the provider.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID. toolkit `string` (required)Endpoint
GET /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-info/{toolkit}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-info/{toolkit} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Connect an app with user-supplied credentials (API key etc., no OAuth)
Creates a connected account for a credentials-mode app straight from the in-product form — no hosted consent flow. The credential fields come from the app's connect-info payload; every required field must be supplied. Credentials are validated with the provider where supported (best-effort — some apps only reject a wrong key on the agent's first tool call). An optional alias labels the new account (multi-account — connecting an already connected app adds ANOTHER account).
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-credentials
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-credentials \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Register the customer's own OAuth app for a BYO app and start its connect flow
For bring-your-own OAuth apps (Xero, Shopify, ...): takes the client ID and client secret of the OAuth app the customer created with the provider (walked through by the app's setup guide), registers it for THIS agent (the secret is stored only with the upstream integration platform — never in Performance Hub), and immediately starts the hosted sign-in flow against it. Returns the consent URL to send the user to, same contract as the connect endpoint. Re-submitting replaces the agent's registered app (e.g. after a secret rotation) — existing connected accounts keep working.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-oauth-app
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-oauth-app \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Start a one-click suite connect for an agent (chained Connect Link flows)
Starts the chained connect flow for a whole suite (e.g. google-workspace). The returned URL opens the first toolkit's consent screen; each completion 302s straight into the next toolkit's flow, finishing on the ph-ai-agent applet page. Members that already have a connected account are SKIPPED, so retrying after a mid-chain failure resumes with the missing apps instead of creating duplicate accounts. When every member is already connected the full chain runs again — that is the explicit "add another account" flow.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-suite
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/connect-suite \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Disconnect one connected account from an agent
Deletes a single connected account (multi-account — other accounts of the same app stay connected). The account is validated as belonging to this agent before deletion; when it was the app's LAST account the toolkit is removed from the agent's connected set (the session is lazily recreated so the agent's tool list updates).
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/disconnect
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/disconnect \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Rename (re-alias) one of an agent's connected accounts
Sets the display alias of a single connected account. Aliases are normally set automatically after OAuth (from the signed-in identity); this endpoint backs the manual rename in the app detail dialog. An empty alias clears the label. The account is validated as belonging to this agent before the upstream update.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID.Request Body
Endpoint
POST /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/rename-account
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/rename-account \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Toggle a built-in Performance Hub service for an agent
Switches one always-on built-in service (Smart Search, Weather, ...) on or off for this agent. Built-ins need no connection or OAuth — they are included with every agent and on by default; this toggle persists the per-agent override and recreates the agent's upstream session immediately so the tool set updates. Note the separate "External apps" switch (the /enable route) is a hard off switch over the whole apps MCP server — when it is off, built-ins are unavailable too regardless of their individual toggles.
Parameters
facilityId `string` (required) deviceId `string` (required) The agent device's balena UUID. slug `string` (required) Built-in service slug.Request Body
Endpoint
PATCH /api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/built-in/{slug}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/connected-apps/{facilityId}/{deviceId}/built-in/{slug} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Associate an AI Agent device with a facility
Metadata-first association. Looks up the device by serial in live device metadata, requires it to be online, then lazily creates the registration row, assigns a Chisel relay region + tunnel port + secret, registers that slot on the relay, and pushes the facility + tunnel config to the device via Balena. New devices are also seeded with a default MCP service account (enabled, scoped to this facility, all capabilities); re-pairing keeps any existing MCP grant. Optional advanced settings override the stamped defaults at pairing time — backup config, MCP on/off, access restriction — and `restoreFrom` seeds the new device from another facility device's cloud backup (active or decommissioned source; queues a cross-repo restore, returned as `restoreRequest` for progress polling).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/associate/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/associate/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List AI Agent devices for a facility
Returns the facility's AI Agent devices with live online + tunnel status (used by the applet device switcher).
Parameters
club `string` (required)Endpoint
GET /api/devices/ph-ai-agent/list/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/list/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
AI Agent update + online status
Returns whether the device is online, whether an update is available/pending, and the offered release (fleet pin when the fleet is pinned; highest successful when the fleet tracks latest).
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/update-status/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/update-status/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
AI Agent live device status + metrics
Returns a curated snapshot for the applet's metrics strip and management drawer: identity + registration fields, liveness + connection, software versions, and the latest heartbeat metrics (CPU, temperature, memory, per-mount storage, uptime, network). Flattens the device metadata beacon + Balena update status; either half may be missing on a transient outage.
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/device-status/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/device-status/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
AI narrative for the device health report
Returns a short operator-facing explanation of the current derived health issues. Facts and playbook steps are always in device-status; this extra paragraph is best-effort and may be null.
Parameters
club `string` (required) uuid `string` (required)Endpoint
POST /api/devices/ph-ai-agent/health/{club}/{uuid}/explain
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/health/{club}/{uuid}/explain \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Mint a direct-to-relay access token for an AI Agent
Returns a short-lived signed URL the browser uses to connect DIRECTLY to the device's regional relay gateway (cutting the global PH/Sydney hop), plus the HS256 token. PH stays the authority (Google SSO + module/facility checks here); the relay-gateway verifies the token. The /ai-agent-ui proxy remains the fallback.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/access/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/access/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Send a chat message into an AI Agent session (notification inline reply)
Server-side relay used by the web push notification's inline reply action - the service worker POSTs here (same-origin, SSO cookies) so a reply works with no Performance Hub tab open. PH resolves the device's relay target (same lookup as the /ai-agent-ui proxy), stamps x-ph-user for turn attribution (the resulting completion push goes back to this user), and forwards to the device's /api/chat/start with the session id.
Request Body
Endpoint
POST /api/devices/ph-ai-agent/reply
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/reply \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Read an AI Agent's access-control settings (owner or super admin)
Returns the device's access block (mode, allowlist, visibility, PH Support toggle) plus any pending access requests. Readable by the device owner and by super admins (support, managing on the owner's behalf); other users get 403.
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/access-settings/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/access-settings/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update an AI Agent's access-control settings (owner or super admin)
Write of mode (org/restricted), the restricted allowlist, list visibility (all/admins), and the "permit access from Performance Hub Support" toggle. Allowed for the device owner and for super admins acting on the owner's behalf (support; audit-logged). The owner itself can only be changed via reallocate-owner. Approved access requests are durable — still-approved requesters are unioned back into the saved allowlist; removing one from the submitted list revokes their approval (request flips to denied; they may request again).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/access-settings/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/access-settings/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Reassign an AI Agent's owner
Reassigns device ownership to another Performance Hub user. Restricted to account owners (SaaS billing module access) and super admins — the escape hatch when a restricted agent's owner leaves. Both the previous and the new owner are notified (in-app + push + email).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/reallocate-owner/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/reallocate-owner/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Facility user list for the AI Agent allowlist / owner pickers
Returns email + name (+ isOrgAdmin/isGlobalAdmin flags) for every user whose role gives them access to THIS facility. Gated to the device owner and reallocators (account owner / super admin) so regular users can't enumerate the user base. Global admins may pass scope=system to list every user in the system (allowlist picker in Super Admin Mode); non-global-admins get the facility scope regardless.
Parameters
club `string` (required) uuid `string` (required) scope `string` (optional) 'system' (global admins only) lists all users instead of this facility's.Endpoint
GET /api/devices/ph-ai-agent/org-users/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/org-users/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Request access to a restricted AI Agent
Creates (or re-opens) the requester's access request for a restricted device — idempotent per user+device. The owner is notified over in-app, web push, and email with a deep link to the agent module.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/access-request/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/access-request/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Approve or deny an AI Agent access request (owner or super admin)
Resolution of a pending request by the device owner, or by a super admin on the owner's behalf (support; audit-logged). Approving appends the requester to the device's allowlist; either outcome notifies the requester (in-app + push + email).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/access-request-resolve/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/access-request-resolve/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Permit + apply an AI Agent update
Pins the device to the offered release (fleet pin, or highest successful when the fleet tracks latest) and releases the update lock so the balena supervisor applies it. State on the device's data volume survives the update.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/update/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/update/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Schedule an AI Agent update for later
Stores a scheduled install time on the device's registration. A recurring backend job (every 5 minutes) applies the update (pin + unlock) once the scheduled time passes. Scheduling replaces any existing schedule for the device.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/update-schedule/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/update-schedule/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Cancel a scheduled AI Agent update
Clears the pending scheduled install for the device (no-op when nothing is scheduled).
Parameters
club `string` (required) uuid `string` (required)Endpoint
DELETE /api/devices/ph-ai-agent/update-schedule/{club}/{uuid}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/update-schedule/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Run a remote command on an AI Agent device
Publishes an allow-listed MQTT command (reboot, restart a container, lock/unlock updates, Wi-Fi management) to the device-controller running on the AI Agent. The device must be associated with the facility.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/command/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/command/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Update an AI Agent's facility-facing configuration
Persists operator-editable settings for an associated AI Agent: the device name, the physical device location, and the scheduled-reboot cadence. The reboot schedule is also pushed to the device as the REBOOT_DEVICE Balena env var (2am local time), matching the Coaching Screen behaviour.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/config/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/config/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Facilities an AI Agent at this facility can be moved to
Returns the same-organisation facilities the signed-in user can access (excluding the current facility), for the "Move to another facility" picker. The move itself is performed by POST /api/devices/move/:club, which enforces the same same-organisation + target-access rules server-side.
Parameters
club `string` (required)Endpoint
GET /api/devices/ph-ai-agent/move-targets/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/move-targets/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
The requester's grantable MCP access envelope for a facility's AI Agents
Returns what the signed-in user is allowed to grant to an AI Agent MCP service account at this facility's organisation: the facilities/regions within their own access, whether they may grant organisation-wide scope, the module universe they hold, and the full MCP tool catalog (for the advanced per-tool mask). The UI uses this so users only ever see options within their own permission envelope; the mcp-access POST endpoint enforces the same attenuation server-side.
Parameters
club `string` (required)Endpoint
GET /api/devices/ph-ai-agent/mcp-grantable/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/mcp-grantable/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get an AI Agent's MCP service-account configuration
Returns the device's MCP access config (scope, modules, tool mask, audit fields). The superAdmin flag is only included for global admin callers.
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/mcp-access/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/mcp-access/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Configure an AI Agent's MCP service account
Saves the device's MCP access config with grant-time attenuation. Non-global-admin requesters can only grant facilities/regions within their own access, organisation scope only when they hold an organisation-wide role, and modules they themselves hold at the facility's organisation. The superAdmin flag is only accepted from global admins (preserved unchanged otherwise). The enabled flag is also pushed to the device as the PH_MCP_ENABLED Balena env var.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/mcp-access/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/mcp-access/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get an AI Agent's VPN configuration (redacted)
Returns the device's VPN support flag and connection list. Profile bodies and credential values are never returned — only import-time metadata (remotes, routes, DNS) and has-credential flags. Live per-connection state comes from the device-status endpoint (beacon metadata.vpn).
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/vpn-config/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-config/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Toggle an AI Agent's VPN support
Turns the device's VPN feature on/off. Pushes the PH_VPN_ENABLED balena device variable and nudges the device (MQTT vpnConfigChanged); connections are kept when toggled off (tunnels stop; config stays for re-enable).
Parameters
club `string` (required) uuid `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/vpn-config/{club}/{uuid}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-config/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Import OpenVPN profile(s) onto an AI Agent
Accepts base64-encoded uploads — single .ovpn/.conf, split-file bundles (config + certs/keys), and archives (.zip, .tar/.tgz Pritunl exports, .tblk Tunnelblick, .visc/.visz Viscosity). Profiles are normalised to a canonical inline form; each profile becomes one connection (imported disconnected — enter credentials, then connect). Actionable 400s on unusable uploads.
Parameters
club `string` (required) uuid `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/vpn-import/{club}/{uuid}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-import/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Update an AI Agent VPN connection (name / credentials / split-DNS)
Updates the stored connection. Credential fields are write-only (omitted = keep stored value; empty string = clear). Credential/split-DNS changes bump the connection revision so a live tunnel restarts with the new values.
Parameters
club `string` (required) uuid `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/vpn-connection/{club}/{uuid}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-connection/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete an AI Agent VPN connection
Removes the connection from the registration and nudges the device, which tears the tunnel down and purges its cached profile/credentials.
Parameters
club `string` (required) uuid `string` (required) connectionId `string` (required)Endpoint
DELETE /api/devices/ph-ai-agent/vpn-connection/{club}/{uuid}/{connectionId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-connection/{club}/{uuid}/{connectionId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Connect / disconnect an AI Agent VPN connection
Desired-state model — sets the connection's enabled flag on the registration and nudges the device (payload-free MQTT vpnConfigChanged); the device pulls the authoritative state via its JWT-authenticated universal-api call and reconciles its tunnels. A missed nudge converges on the periodic sync.
Parameters
club `string` (required) uuid `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/vpn-command/{club}/{uuid}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/vpn-command/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get an AI Agent's cloud-backup configuration + status
Returns the device's backup settings (enabled, retention, storage region), the rolling backup status (last backup, size, errors), the resolved automatic region, and the available storage regions for the picker. The restic repo password is never returned.
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-config/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-config/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update an AI Agent's cloud-backup configuration
Saves enabled/retention/region. Takes effect on the device's next hourly backup tick (the device asks PH for its run context before every run), so no device restart is involved.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/backup-config/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-config/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List backup restore sources for pairing a new AI Agent
Facility-wide view for the add-agent dialog's "restore from a backup" option: every registration in the club — active AND decommissioned/replaced — that still has a decryptable backup repo and at least one usable restore point, with its newest snapshots. Also returns the backup config option lists (allowedRetentionDays, availableRegions) so the dialog needs no device UUID to populate its selects.
Parameters
club `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-sources/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-sources/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List an AI Agent's backup restore points
Returns the device's snapshot index (newest first) from DynamoDB — no device or repo round-trip — plus the current manual-backup / restore request state for drawer polling. Stale requests (never picked up, or no progress heartbeat) are presented as failed so the UI can always submit a new one.
Parameters
club `string` (required) uuid `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-snapshots/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-snapshots/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Request a manual backup of an AI Agent now
Writes a manual-run request (with the user's note) onto the registration row and nudges the device over MQTT. The device fetches the verified request via its JWT-authenticated universal-api run-context call — even without MQTT it is picked up on the next scheduler tick. Rejected while another backup or restore is in flight.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/backup-run/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-run/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Pin or unpin an AI Agent restore point
Pinned restore points are protected from retention pruning — the device's nightly maintenance receives the pinned snapshot ids via its run-context call and excludes them from restic forget — and their index rows never TTL out. Unpinning restores the normal retention behaviour.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/backup-pin/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-pin/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Restore an AI Agent from a backup restore point
Writes a restore request onto the registration row and nudges the device. Full restores overwrite /data and /home/hermeswebui (the device first takes an automatic pre-restore safety snapshot and stops the agent during the restore) and require the device name typed as confirmation. Passing `paths` performs a non-disruptive file-level restore of just those paths instead. Optionally pins the device back to the snapshot's software release once the data restore completes (see backup-restore-release).
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/backup-restore/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-restore/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Apply the software release recorded on a completed restore
Final step of a restore that requested the snapshot's software version: once the device reports the data restore completed, this pins the device to the stored release and unlocks updates (same mechanics as the update endpoint). Driven by the drawer's polling; idempotent — the stored pin is cleared once applied.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/backup-restore-release/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-restore-release/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Browse files inside a backup restore point
Lists one directory level of a restic snapshot, served entirely server-side from the Wasabi repo (works with the device offline). Only tree metadata is read — no file data is downloaded for listings.
Parameters
club `string` (required) uuid `string` (required) takenAt `number` (required) path `string` (optional)Endpoint
GET /api/devices/ph-ai-agent/backup-files/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-files/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search filenames inside a backup restore point
Case-insensitive filename search from a directory down, served server-side from the restic tree metadata (no file data is read; works with the device offline). Streams the listing and stops at the first 200 matches.
Parameters
club `string` (required) uuid `string` (required) takenAt `number` (required) q `string` (required) path `string` (optional)Endpoint
GET /api/devices/ph-ai-agent/backup-search/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-search/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
What changed between two backup restore points
Runs a server-side restic diff between two of the device's snapshots (tree metadata only) and returns the added/removed/modified file list (capped at 500 changes) plus summary statistics. Results are cached — snapshots are immutable.
Parameters
club `string` (required) uuid `string` (required) fromTakenAt `number` (required) toTakenAt `number` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-diff/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-diff/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Version history of one file across all restore points
One server-side restic find across every snapshot in the device's repo, collapsed to DISTINCT versions (consecutive identical size+mtime hits are merged) and joined to the snapshot index rows for dates/kinds/notes.
Parameters
club `string` (required) uuid `string` (required) path `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-file-versions/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-file-versions/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search every restore point of a device's backups by file name
The deleted-file recovery path: one server-side restic find across ALL snapshots in the repo (case-insensitive, substring or glob), grouped by path with the restore points each file appears in. A file deleted from the device is still findable here as long as any restore point contains it.
Parameters
club `string` (required) uuid `string` (required) q `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-find/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-find/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Download a single file from a backup restore point
Streams one file straight out of the restic repo to the browser (attachment). Directories are streamed as a tar archive. Size-capped; served server-side, so it works with the device offline.
Parameters
club `string` (required) uuid `string` (required) takenAt `number` (required) path `string` (required)Endpoint
GET /api/devices/ph-ai-agent/backup-file-download/{club}/{uuid}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/backup-file-download/{club}/{uuid} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Decommission an AI Agent from a facility
Parameters
club `string` (required)Endpoint
POST /api/devices/ph-ai-agent/decommission/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/decommission/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remove an AI Agent from a facility and factory-reset the hardware
Fully disassociates the device so it can be paired at ANY facility, and wipes all data on the NUC. The wipe is armed via the PH_FACTORY_RESET balena device variable (a one-time nonce) BEFORE the cloud teardown, so it survives the device being offline at removal time — the wipe runs when it next connects. An MQTT factoryReset nudge makes the online case immediate. Cloud teardown then revokes every credential and grant, clears the Balena facility binding (device vars + club tag) and the metadata clubID, deletes access requests and the LAN DNS record. Cloud backups are RETAINED: the snapshot index and repo password stay on the soft-deleted registration, usable as a restore source when adding a replacement. Requires the device's name typed as confirmation.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/reset/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/reset/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Replace a dead AI Agent with a new NUC (disaster recovery)
One-shot device replacement: associates the replacement NUC (tunnel slot, secrets, balena vars, backup seed), carries over the old device's name, location, reboot schedule, backup settings, access block and MCP grant, re-keys the old snapshot index to the new device (so its full backup history stays browsable), decommissions the old registration (stamped replacedBy / replacedFrom), and — unless `restore` is false — queues a full restore of the chosen restore point from the OLD device's backup repo onto the new hardware. Works with the old device dead/offline; requires the old device's name typed as confirmation. Same-facility only.
Parameters
club `string` (required)Request Body
Endpoint
POST /api/devices/ph-ai-agent/replace/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/devices/ph-ai-agent/replace/{club} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Resolves a Performance Hub device QR short link to the deep link it points at, so the Add Device scanner can detect the device type. Only performancehub.co / ubx.fit hosts are followed.
Parameters
url `string` (required) The scanned short linkEndpoint
GET /api/devices/resolve-qr
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/resolve-qr \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Tests the connectivity to a facilities Unifi Controller and if the credentials are correct.
Parameters
facilityID `string` (required) Internal ID of the facility that you wish to test unifi connectivity withEndpoint
GET /api/devices/testUnifiController/{facilityID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/devices/testUnifiController/{facilityID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a generic IoT device with a club.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
PUT /api/devices/updateGenericDevice/{club}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/devices/updateGenericDevice/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Grant complimentary Model Router credit to a facility (super admin only)
Credits the facility's prepaid AI balance directly, with no card charge. Restricted to global admins. Recorded as an `adjustment` transaction with the granting admin's email and an optional note.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/clubs/{clubID}/ai-credits/admin/grant-credit
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/admin/grant-credit \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Facility Model Router summary (config, balance, spend).
Parameters
clubID `string` (required) tz `string` (optional) Viewer's IANA timezone — fallback for day/month spend windows when the facility has no timezone data.Endpoint
GET /api/clubs/{clubID}/ai-credits/overview
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/overview \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Catalogue of available models with per-facility enabled state (default all enabled).
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/models
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/models \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Available guardrails and PH preset templates.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/guardrails
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/guardrails \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Connected Model Router services. Includes paired AI Agent devices, explicitly typed external agents, and the facility Workflow service. Configuration is edited via PATCH /keys/{keyHash}.
Parameters
clubID `string` (required) tz `string` (optional) Viewer's IANA timezone — fallback for day/month spend windows when the facility has no timezone data.Endpoint
GET /api/clubs/{clubID}/ai-credits/agents
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/agents \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable Model Router for a facility (provisions its LiteLLM team).
Parameters
clubID `string` (required)Endpoint
POST /api/clubs/{clubID}/ai-credits/enable
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/enable \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update plan, model allowlist, guardrails, content filters (PH-side regex redact/block), spend limit, and auto-recharge config.
Parameters
clubID `string` (required)Endpoint
PATCH /api/clubs/{clubID}/ai-credits/config
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Reset the lifetime hard-cap counter to 0 (rebaseline to current spend) and log the closed period to history.
Parameters
clubID `string` (required)Endpoint
POST /api/clubs/{clubID}/ai-credits/spend-limit/reset-total
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/spend-limit/reset-total \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Hard-cap reset history (newest first) — cap, spent, and timestamps per closed period.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/spend-limit/history
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/spend-limit/history \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a new phk_ API key for the facility (plaintext returned once). Accepts optional spend caps, model allowlist, guardrails, content filters, and rpmLimit/tpmLimit rate limits.
Parameters
clubID `string` (required)Endpoint
POST /api/clubs/{clubID}/ai-credits/keys
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/keys \
-H "x-api-key: YOUR_API_KEY"
Update editable key fields: label, per-key spend caps, model allowlist, guardrails, content filters, and rpmLimit/tpmLimit rate limits (synced to the backing LiteLLM key).
Parameters
clubID `string` (required) keyHash `string` (required)Endpoint
PATCH /api/clubs/{clubID}/ai-credits/keys/{keyHash}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/keys/{keyHash} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Per-request inference logs for the facility (live from LiteLLM, metadata only).
Parameters
clubID `string` (required) page `string` (optional) pageSize `string` (optional) status `string` (optional) model `string` (optional) provider `string` (optional) source `string` (optional) `key` or `agent` keyHash `string` (optional) Filter to a single key/agent by its PH keyHash. q `string` (optional) Free-text search across request id, key/agent label, model, provider, end user. minutes `string` (optional) Sub-day window (e.g. Live=1440); overrides startDate/endDate. startTs `string` (optional) Epoch-seconds window start (click-to-zoom); overrides minutes/dates. endTs `string` (optional) Epoch-seconds window end (click-to-zoom); overrides minutes/dates.Endpoint
GET /api/clubs/{clubID}/ai-credits/logs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/logs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Requests-over-time histogram for the Logs view. Same filters as the list route, but aggregated server-side into time buckets (success/failure counts) so the response is tiny regardless of log volume. Bucket size is chosen automatically for the span.
Parameters
clubID `string` (required) status `string` (optional) model `string` (optional) provider `string` (optional) source `string` (optional) keyHash `string` (optional) q `string` (optional) minutes `string` (optional) startDate `string` (optional) endDate `string` (optional) startTs `string` (optional) endTs `string` (optional)Endpoint
GET /api/clubs/{clubID}/ai-credits/logs/histogram
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/logs/histogram \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Usage analytics buckets + per-model totals for a range (live from LiteLLM).
Parameters
clubID `string` (required) range `string` (optional) 24h | 7 | 30 | 90 | year | all (ignored if startDate/endDate given) startDate `string` (optional) endDate `string` (optional) groupBy `string` (optional) model (default) | key | source | provider | status — dimension for buckets + groups subgroupBy `string` (optional) optional second dimension nested under each group (Explore) keyHash `string` (optional) deep-dive filter — scope to a single key/agent model `string` (optional) deep-dive filter — scope to a single model provider `string` (optional) source `string` (optional) compare `string` (optional) set to "prev" to also return groupsPrev (immediately-preceding equal-length period)Endpoint
GET /api/clubs/{clubID}/ai-credits/stats
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/stats \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Daily activity calendar over the rolling last year (GitHub-style ~53 weeks).
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/activity
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/activity \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Charge the stored SaaS-billing card to add prepaid Model Router credit.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/clubs/{clubID}/ai-credits/topup
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/topup \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Finalise a top-up after the applet completes 3DS authentication.
Parameters
clubID `string` (required)Endpoint
POST /api/clubs/{clubID}/ai-credits/topup/confirm
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/topup/confirm \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Summary of the stored SaaS-billing card that top-ups / auto top-up will charge.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/payment-method
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/payment-method \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Ledger transactions for the facility, newest first. Optionally filtered by type (e.g. `types=topup,adjustment` for the money-movement history, or `types=charge-reconcile` with `from`/`to` for a month's usage deductions).
Parameters
clubID `string` (required) limit `integer` (optional) Max rows (default 50, max 200) types `string` (optional) Comma-separated transaction types (topup, charge-reconcile, refund, adjustment, trueup-shortfall) from `integer` (optional) Only transactions with createdAt >= from (unix seconds) to `integer` (optional) Only transactions with createdAt <= to (unix seconds)Endpoint
GET /api/clubs/{clubID}/ai-credits/transactions
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/transactions \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Distinct `YYYY-MM` months (UTC, newest first) that contain at least one transaction of the requested types. Drives the data-driven year/month filter dropdowns so the UI only offers periods that actually have data.
Parameters
clubID `string` (required) types `string` (optional) Comma-separated transaction types (topup, charge-reconcile, refund, adjustment, trueup-shortfall)Endpoint
GET /api/clubs/{clubID}/ai-credits/transactions/available-periods
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/transactions/available-periods \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Branded PDF payment receipt for a single Model Router transaction.
Parameters
clubID `string` (required) txId `string` (required)Endpoint
GET /api/clubs/{clubID}/ai-credits/transactions/{txId}/receipt.pdf
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/transactions/{txId}/receipt.pdf \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bundle of branded PDF payment receipts for the selected top-up transactions, as a ZIP. Every id must be a top-up belonging to the facility — usage deductions and admin adjustments have no receipts and are rejected.
Parameters
clubID `string` (required) ids `string` (required) Comma-separated transaction ids (max 50)Endpoint
GET /api/clubs/{clubID}/ai-credits/transactions/receipts.zip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/transactions/receipts.zip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Per-calendar-month (UTC) rollups of the facility's usage deductions, newest first. The current month is always included and flagged `isCurrentMonth` (month to date).
Parameters
clubID `string` (required) months `integer` (optional) Lookback window in months (default 12, max 24; ignored when `year` is set) year `integer` (optional) Scope the rollups to one UTC calendar year (e.g. 2026)Endpoint
GET /api/clubs/{clubID}/ai-credits/usage-statements
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/usage-statements \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Branded monthly Usage Statement PDF — a summary of the month's usage deductions (daily subtotals + total). Explicitly not an invoice or receipt; no payment is collected by usage deductions.
Parameters
clubID `string` (required) month `string` (required) UTC calendar month, `YYYY-MM`Endpoint
GET /api/clubs/{clubID}/ai-credits/usage-statements/{month}/statement.pdf
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/usage-statements/{month}/statement.pdf \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Raw usage-deduction line items for a month as CSV (transaction id, UTC timestamp, amount, balance after, lifetime spend snapshot) — the detail export that reconciles to the month's statement total.
Parameters
clubID `string` (required) month `string` (required) UTC calendar month, `YYYY-MM`Endpoint
GET /api/clubs/{clubID}/ai-credits/usage-statements/{month}/detail.csv
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/usage-statements/{month}/detail.csv \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Usage/spend summary for the facility (live from LiteLLM + reconciled ledger).
Parameters
clubID `string` (required) tz `string` (optional) Viewer's IANA timezone — fallback for day/month spend windows when the facility has no timezone data.Endpoint
GET /api/clubs/{clubID}/ai-credits/usage
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/ai-credits/usage \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Associates/Updates an AI Edge Processor device to a club
Parameters
body `string` (required) JSON Object for updating AI Edge Processor Device registration.Endpoint
POST /api/ai-edge-processor/devices
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ai-edge-processor/devices \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Associates an AI Edge Processor device to a club. Resolves the device metadata-first (live heartbeat wins), backfills the registration row if the device never self-registered, and cleans up stale registration rows left behind by re-provisioned hardware.
Parameters
body `string` (required) JSON Object for updating AI Edge Processor Device registration.Endpoint
POST /api/ai-edge-processor/devices/associate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ai-edge-processor/devices/associate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of bbox upload records in a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/bbox-timeline/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/bbox-timeline/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Camera database search index
Proxies the public docs camera-db search index (manufacturers, series, models, aliases) used by the Find my camera dialog when adding network cameras. Cached server-side for 12 hours.
Endpoint
GET /api/cctv/camera-db/search-index
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/camera-db/search-index \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Camera database manufacturer templates
Proxies a single manufacturer's RTSP URL templates and defaults from the public docs camera database. Slug is validated to prevent path traversal. Cached server-side for 12 hours.
Parameters
slug `string` (required) Manufacturer slug (e.g. hikvision)Endpoint
GET /api/cctv/camera-db/manufacturers/{slug}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/camera-db/manufacturers/{slug} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of check-ins data for a facility
Parameters
club `string` (required) Internal ID of the club/facility that you wish to access. startDate `string` (optional) Start date in YYYY-MM-DD format endDate `string` (optional) End date in YYYY-MM-DD format timezone `string` (optional) Timezone for date interpretation (default Australia/Brisbane) nextToken `string` (optional) Pagination token for fetching next pageEndpoint
GET /api/cctv/check-ins/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/check-ins/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieve configuration for CCTV Frontend or UI
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/config/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/config/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get CCTV content delivery configuration
Returns the content domain used by CCTV clients to resolve media assets. The domain is driven by the CONTENT_DOMAIN environment variable, falling back to a stage-aware default (production serves /cctv, other stages serve /cctv-stg).
Endpoint
GET /api/cctv/content-config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/content-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Change configuration for CCTV Frontend or UI
Parameters
body `object` (required) Json Object of the new config block to add to the system.Endpoint
PUT /api/cctv/config/:club/:section
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/cctv/config/:club/:section \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of Bucket Region availability for CCTV storage provider config
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/bucket-region/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/bucket-region/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Reset unidentified face collection
Resets the facility's unidentified CompreFace collection by deleting all subjects. DynamoDB person records, face detections, and OpenSearch timeline blocks are NOT affected. Only the underlying face recognition data is cleared. New shadow profiles will be created automatically as the system processes new camera detections.
Parameters
facilityId `string` (required)Endpoint
DELETE /api/cctv/config/{facilityId}/unidentified-collection
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/cctv/config/{facilityId}/unidentified-collection \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get unidentified collection info
Returns the current subject count for the facility's unidentified CompreFace collection.
Parameters
facilityId `string` (required)Endpoint
GET /api/cctv/config/{facilityId}/unidentified-collection-info
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/config/{facilityId}/unidentified-collection-info \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds a network camera (OEM/IP camera) via stream URL (RTSP, HTTP, HTTPS)
Parameters
body `string` (required) JSON Object for adding a network camera.Endpoint
POST /api/cctv/devices/add-network-camera
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/add-network-camera \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bulk-add network cameras to an edge processor
Registers multiple RTSP/HTTP network cameras against one edge processor, then pushes FEED_CONFIG once so the device reloads configuration a single time.
Parameters
body `object` (required)Endpoint
POST /api/cctv/devices/add-network-cameras
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/add-network-cameras \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Associates/Updates a device to a club
Parameters
body `string` (required) JSON Object for updating CCTV Device registration.Endpoint
POST /api/cctv/devices
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Associates a device to a club
Parameters
body `string` (required) JSON Object for updating CCTV Device registration.Endpoint
POST /api/cctv/devices/associate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/associate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Fires off a MQTT Request to a specific device UUID, And expects a response (via websocket) of the available capabilities of the camera.
Parameters
club `string` (required) Internal ID of the club that owns the device you are querying. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/cctv/devices/list-camera-capabilities/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/list-camera-capabilities/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List device registrations
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/devices/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/devices/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Removes a network camera by marking it as deleted and removing it from the Edge Processor FEED_CONFIG
Parameters
club `string` (required) Internal ID of the club that owns the device. balenaUUID `string` (required) UUID of the network camera to remove.Endpoint
DELETE /api/cctv/devices/remove-network-camera/{club}/{balenaUUID}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/cctv/devices/remove-network-camera/{club}/{balenaUUID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Saves any/all configured camera capabilities and applies them to the device as a environment variable (via balena)
Parameters
club `string` (required) Internal ID of the club that owns the device you are querying. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/cctv/devices/save-camera-capabilities/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/save-camera-capabilities/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Saves a motion mask (if configured) for the camera and applies it to the device as a environment variable (via balena)
Parameters
club `string` (required) Internal ID of the club that owns the device you are querying. body `string` (required) Json Object of the camera mask.Endpoint
POST /api/cctv/devices/save-camera-mask/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/save-camera-mask/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Sends a specific v4l2 command (such as brightness, or contrast) to the physical device
Parameters
club `string` (required) Internal ID of the club that owns the device you are querying. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/cctv/devices/set-camera-capability/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/set-camera-capability/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Test a network camera stream URL
Sends a test command to an edge processor to validate a camera stream URL using ffprobe
Request Body
Endpoint
POST /api/cctv/devices/test-stream
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/devices/test-stream \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Permanently deletes a single face detection record from the database. Used to remove mismatched or incorrect track entries from a person's activity log.
Parameters
club `string` (required) fdID `string` (required)Endpoint
DELETE /api/cctv/face-detections/:club/:fdID
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/cctv/face-detections/:club/:fdID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of face detections data of a person
Parameters
club `string` (required) Internal ID of the club that you wish to access. personID `string` (required) ID of person within the face identification systemEndpoint
GET /api/cctv/face-detections/:club/:personID
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/face-detections/:club/:personID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns face detections that reference a given person crop image, queried via the personCropImage GSI.
Parameters
club `string` (required) Internal ID of the club that you wish to access. personCropImage `string` (required) Person crop image URL stored on the face detection record. limit `string` (optional) Maximum number of detections to return. nextToken `string` (optional) Pagination token from a previous response.Endpoint
GET /api/cctv/face-detections-by-person-crop-image/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/face-detections-by-person-crop-image/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of face detections data of a club grouped from range relative to current time
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/face-detections/:club/timeline
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/face-detections/:club/timeline \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of face detections data of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/face-detections/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/face-detections/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search face detection timeline blocks in a facility using OpenSearch
Parameters
facilityId `string` (required) Internal ID of the facility to search in timezone `string` (required) IANA timezone for date conversion (e.g. Pacific/Auckland) startDate `string` (optional) Start date filter (YYYY-MM-DD), converted to startUnix using timezone endDate `string` (optional) End date filter (YYYY-MM-DD), converted to endUnix using timezone personId `string` (optional) Filter by a specific person ID query `string` (optional) Free-text search (e.g. person name) limit `string` (optional) Results per page (default 20, max 100) filters `string` (optional) JSON-encoded filters object (e.g., {"matchType":"identified"}) sortBy `string` (optional) Field to sort by (startUnix, endUnix, created). Default is endUnix. page `string` (optional) Page number for pagination (default 1) sortOrder `string` (optional) Sort direction (asc or desc). Default is desc.Endpoint
GET /api/cctv/search/face-detections/timeline-blocks/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/search/face-detections/timeline-blocks/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of reports about the club facility
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/facility/:club/reports
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/facility/:club/reports \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Trigger on-demand heatmap generation. Invokes the same Starter logic that the scheduled cron uses, but allows targeting a specific facility, date/time, and set of periods. When called with no body, behaves identically to the cron — scans all eligible facilities and enqueues every device.
Request Body
Endpoint
POST /api/cctv/heatmaps/generate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/heatmaps/generate \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Resolve the location of a composed rolling-window heatmap PNG for a single device. Returns JSON metadata only — the PNG bytes live on the content domain, the frontend constructs the URL as: `${contentDomain}/cctv/${storageService}/${region}/${filePath}?s=${token}` Resolution order: 1. DynamoDB `composed#…` index hit → return immediately (~10 ms). 2. Wasabi HEAD on the deterministic cache key. On hit, write a backfill index row and return. 3. Stale-fallback: any composed record exists for this (device, range, hour) tuple, even from a different date. Returned immediately with `cache: 'HIT-STALE'` so the FE can paint *something*. A fresh compose is fired async. 4. Cold path: no record exists at all. Compose Lambda is queued via `InvocationType: 'Event'` and the endpoint returns `202 { cache: 'PENDING' }`. The FE polls until a record lands (typically 3-5 seconds). Today-handling: when `endDate` is the facility's local "today", the endpoint serves yesterday's PNG instead — today's slices are still being written by the Starter cron and a fresh composition would be incomplete. The response echoes the requested `endDate` and includes `endDateUsed` (= yesterday). `cache` enum: - `HIT` — served from DDB index for the requested date. - `HIT-FALLBACK` — today requested; served yesterday's index row. - `HIT-BACKFILL` — DDB miss but Wasabi had the PNG; row was just written. - `HIT-FALLBACK-BACKFILL` — backfill on the yesterday fallback. - `HIT-STALE` — no record for the requested date but a record exists from another date for this tuple; served immediately and a fresh compose is queued in the background. - `PENDING` — no record at all; compose has been queued. FE should poll. Response is `202 Accepted`, no `filePath`.
Parameters
facilityId `string` (required) deviceUUID `string` (required) Device to compose for. Compositions are per-device. hour `integer` (required) Hour of day 0–23 to compose across the lookback window. endDate `string` (optional) Last date in the window (YYYY-MM-DD). Defaults to today (facility tz). range `string` (optional) Lookback window. Must be one of the whitelisted ranges. nocache `integer` (optional) Set to `1` to bypass the DDB + HEAD cache layers and force a fresh compose.Endpoint
GET /api/cctv/heatmaps/hourly/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/heatmaps/hourly/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Discover which hours of the day have `1h` slice records for a device over a rolling lookback window. The frontend uses this to populate the hour picker alongside a date + range picker before firing the composition endpoint (`/api/cctv/heatmaps/hourly/...`). Example: `GET /api/cctv/heatmaps/query-hourly/Birkdale?deviceUUID=abc123&endDate=2026-04-16&range=30d` Internally: one DynamoDB range query on `cctvheatmaps` (`sk BETWEEN 1h#{start}-00 AND 1h#{end}-23`), grouped by hour. Returns one entry per hour that has at least one slice, including a representative ref JPEG (taken from the most recent day in the window — ref is shared per-device-per-day).
Parameters
facilityId `string` (required) deviceUUID `string` (required) Device to query. Hourly slices are per-device. endDate `string` (optional) Last date in the window (YYYY-MM-DD). Defaults to today (facility tz). range `string` (optional) Lookback window. Must be one of the whitelisted ranges.Endpoint
GET /api/cctv/heatmaps/query-hourly/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/heatmaps/query-hourly/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Query pre-generated heatmap records for a facility. **All records for a period type:** - `/api/cctv/heatmaps/Birkdale?periodType=1y` - `/api/cctv/heatmaps/Birkdale?deviceUUID=abc123&periodType=1d` **Date range — single period type:** - `/api/cctv/heatmaps/Birkdale?periodType=1d&from=2026-03-01&to=2026-03-31` - `/api/cctv/heatmaps/Birkdale?periodType=6h&from=2026-03-31&to=2026-03-31` **Date range — all applicable period types (omit periodType):** - `/api/cctv/heatmaps/Birkdale?from=2026-03-01&to=2026-03-31` Returns annual, semi-annual, quarterly, etc. down to 6h records that overlap the given range. **Point-in-time — all 9 period types for one device:** - `/api/cctv/heatmaps/Birkdale?deviceUUID=abc123&date=2026-03-15T14:30` Returns up to 9 records (1y, 6m, 3m, 2m, 1m, 1w, 1d, 12h, 6h).
Parameters
facilityId `string` (required) The facility identifier. deviceUUID `string` (optional) Query a specific device. When omitted, queries across all devices (GSI). periodType `string` (optional) Filter to a single period type. When omitted with from/to, queries all types. from `string` (optional) Start date (yyyy-mm-dd). Must be used with `to`. to `string` (optional) End date (yyyy-mm-dd). Must be used with `from`. date `string` (optional) Point-in-time lookup (yyyy-mm-dd or yyyy-mm-ddTHH:mm). Requires deviceUUID. Returns one record per period type.Endpoint
GET /api/cctv/heatmaps/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/heatmaps/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the device livestream thumbnail
Parameters
club `string` (required) Internal ID of the club. deviceId `string` (required) Internal ID of the CCTV device.Endpoint
GET /api/cctv/livestream/:club/thumbnail/:deviceId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/livestream/:club/thumbnail/:deviceId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Tell the CCTV system that you are going to watch a livestream
Parameters
club `string` (required) Internal ID of the club. deviceId `string` (required) Internal ID of the CCTV device.Endpoint
POST /api/cctv/livestream/:club/iswatching/:deviceId
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/livestream/:club/iswatching/:deviceId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Approve an intersection match
Sets match status to confirmed and records the reviewer.
Parameters
club `string` (required) matchId `string` (required)Endpoint
POST /api/cctv/matching/{club}/detail/{matchId}/approve
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/matching/{club}/detail/{matchId}/approve \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get a single intersection match with visit details
Returns the match record and its per-visit timing breakdown.
Parameters
club `string` (required) matchId `string` (required)Endpoint
GET /api/cctv/matching/{club}/detail/{matchId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/matching/{club}/detail/{matchId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually link an unmatched person to a member
Associates a CCTV personId with a specific member, setting the match to confirmed.
Parameters
club `string` (required) matchId `string` (required)Request Body
Endpoint
POST /api/cctv/matching/{club}/detail/{matchId}/link
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/matching/{club}/detail/{matchId}/link \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List intersection matches for a facility
Returns paginated matches filtered by status.
Parameters
club `string` (required) status `string` (optional) limit `integer` (optional) nextToken `string` (optional)Endpoint
GET /api/cctv/matching/{club}/list
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/matching/{club}/list \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Reject an intersection match
Sets match status to rejected and records the reviewer.
Parameters
club `string` (required) matchId `string` (required)Endpoint
POST /api/cctv/matching/{club}/detail/{matchId}/reject
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/matching/{club}/detail/{matchId}/reject \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get intersection matching summary counts
Returns match counts grouped by status for the facility.
Parameters
club `string` (required) Facility IDEndpoint
GET /api/cctv/matching/{club}/summary
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/matching/{club}/summary \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Unlink an auto-learned profile match
Reverts a linked match back to rejected status and clears autoLearnedFrom on the member record.
Parameters
club `string` (required) matchId `string` (required)Request Body
Endpoint
POST /api/cctv/matching/{club}/detail/{matchId}/unlink
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/matching/{club}/detail/{matchId}/unlink \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Read the status of an in-flight "upsert identified person" operation (covers create and edit). Reads the row directly from the cctv-rekognition-api-owned `people-ops` table; no Lambda hop. Used by the CCTV frontend to poll progress after POST /api/cctv/people/{facility}/identified. Path is a sibling of `/cctv/people/...` (not nested under it) so the express router cannot mis-match `operationId` as `:personID` on `/cctv/people/:club/:personID`. See createAPIRouter glob order. Returns a `pending` placeholder while the upsertIdentifiedPerson Lambda hasn't yet written its first stage entry (cold-start window). The FE polling hook treats placeholder and pending identically, so this keeps the contract stable for callers.
Parameters
operationId `string` (required)Endpoint
GET /api/cctv/people-operations/{operationId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people-operations/{operationId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds a face image (from an existing track detection) to the person's CompreFace recognition subject and stores a reference in the shadow photos table. Does NOT upload the image to Wasabi — it is already there as a face detection capture.
Parameters
club `string` (required) personID `string` (required) body `string` (required)Endpoint
POST /api/cctv/people/:club/:personID/add-face
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/:club/:personID/add-face \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add shadow photos to a person record
Parameters
club `string` (required) Internal ID of the club that you wish to access. personID `string` (required) Record ID of the person body `string` (required) Json Object of the new config block to add to the system.Endpoint
POST /api/cctv/people/:club/shadow-photos/:personID
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/:club/shadow-photos/:personID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Query shadow photos of a person
Parameters
club `string` (required) Internal ID of the club that you wish to access. personID `string` (required) Record ID of the personEndpoint
GET /api/cctv/people/:club/shadow-photos/:personID
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people/:club/shadow-photos/:personID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Permanently removes a shadow photo record from CCTVShadowPhotosTable and removes the corresponding face from CompreFace (if faceId is stored).
Parameters
club `string` (required) personID `string` (required) id `string` (required) The shadow photo record ID (primary key)Endpoint
DELETE /api/cctv/people/:club/shadow-photos/:personID/:id
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/cctv/people/:club/shadow-photos/:personID/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deletes references and associated rekognition records by a personID
Parameters
club `string` (required) Internal ID of the club that you wish to access. personID `string` (required) Unique ID of the CCTV person.Endpoint
DELETE /api/cctv/people/:club/:personID
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/cctv/people/:club/:personID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a person record of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access. personID `string` (required) DB ID of the person.Endpoint
GET /api/cctv/people/:club/:personID
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people/:club/:personID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get access zones matched to a person's membership profile
Resolves the person's member type, tags, and membership plans, then returns real access zones (origin=membership-plan, not absorbed) matched against include/exclude rules. The accessRestriction on each zone is trimmed to only the rules that matched the person. Child zone cameras are merged into parent zones.
Parameters
club `string` (required) Internal ID of the facility personID `string` (required) Person ID from the CCTV people tableEndpoint
GET /api/cctv/people/{club}/{personID}/allowed-zones
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people/{club}/{personID}/allowed-zones \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the current status of a merge job including per-source results. Poll this endpoint every 3-5 seconds while status is IN_PROGRESS.
Parameters
club `string` (required) mergeJobID `string` (required)Endpoint
GET /api/cctv/people/:club/merge-status/:mergeJobID
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people/:club/merge-status/:mergeJobID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initiates a background merge of multiple unidentified person profiles into one survivor. Responds 202 immediately with a mergeJobID. Poll /merge-status/:mergeJobID for progress.
Parameters
club `string` (required) body `string` (required)Endpoint
POST /api/cctv/people/:club/merge-unidentified
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/:club/merge-unidentified \
-H "x-api-key: YOUR_API_KEY"
Add a face to the blacklist collection for a facility
Parameters
facilityId `string` (required) Internal ID of the facilityRequest Body
Endpoint
POST /api/cctv/people/{facilityId}/blacklist
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/{facilityId}/blacklist \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Upsert an identified person in a facility — creates a new record or updates an existing one. Proxies to the upsertIdentifiedPerson Lambda, which writes the person record, uploads any supplied photo to Wasabi, and re-indexes the face in CompreFace. When `isNewRecord` is true (default) the Lambda runs the create branch (cctvPeople.save) and a `personID` is generated if not provided. When `isNewRecord` is false the Lambda runs the update branch (cctvPeople.update) — `personID` is required and must identify an existing record.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/cctv/people/{facilityId}/identified
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/{facilityId}/identified \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Update the set of optional partner fields synced into the CCTV people table for a facility.
Parameters
facilityId `string` (required) Internal ID of the facilityRequest Body
Endpoint
PUT /api/cctv/people/{facilityId}/sync-fields
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/cctv/people/{facilityId}/sync-fields \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Returns a list of people data of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/people/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/people/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search people in a facility by face image. Invokes the cctv-rekognition-api imageFaceSearch Lambda with the uploaded base64 image and facility ID from the path. Returns ranked matches plus a DeepFace attribute summary.
Parameters
club `string` (required) Facility / club ID body `string` (required)Endpoint
POST /api/cctv/people/{club}/search-by-face
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/{club}/search-by-face \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search people in a facility using OpenSearch
Parameters
facilityId `string` (required) Internal ID of the facility to search in query `string` (optional) Search term (e.g., name) page `string` (optional) Page number (default 1) limit `string` (optional) Results per page (default 20, max 100) filters `string` (optional) JSON-encoded filters object (e.g., {"membershipStatus":"active"}) sortBy `string` (optional) Field to sort by (created, lastName, firstName, membershipUpdatedOn). Default is created. sortOrder `string` (optional) Sort direction (asc or desc). Default is desc.Endpoint
GET /api/cctv/search/people/:facilityId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/search/people/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates face detection items with a new personID and associates rekognition records
Parameters
club `string` (required) Internal ID of the club that you wish to access. body `string` (required) Json Object of the new config block to add to the system.Endpoint
POST /api/cctv/people/:club/validate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/people/:club/validate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns an object of all availble filters for CCTV recordings data of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/recordings/filters/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/recordings/filters/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Stream recording.
Endpoint
GET /api/cctv/recordings/:club/:dir/:filename
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/recordings/:club/:dir/:filename \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update info about the recording.
Endpoint
PUT /api/cctv/recordings/:club/:dir/:filename
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/cctv/recordings/:club/:dir/:filename \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a summary of CCTV recordings data of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/recordings/:club/summary
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/recordings/:club/summary \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of CCTV recordings data of a club based on range relative to current time
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/recordings/:club/timeline
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/recordings/:club/timeline \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of CCTV recordings data of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/recordings/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/recordings/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Recordings are automatically deleted in a set period, use this function to retain recordings
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
POST /api/cctv/recordings/:club/:action
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/recordings/:club/:action \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search report snapshots for a facility within a date range
Parameters
facilityId `string` (required) Internal ID of the facility startDate `string` (required) Start date filter (YYYY-MM-DD) endDate `string` (required) End date filter (YYYY-MM-DD) deviceIds `string` (optional) Comma-separated list of camera/device IDs to filter by view `string` (optional) Alternate report view to compute (forwarded to the report Lambda)Endpoint
GET /api/cctv/reports/search-report-snapshots/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/reports/search-report-snapshots/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Vector search over a facility's indexed CCTV media. Responds with a text/event-stream relayed from the searchAnything Lambda, so the client can render progress while a cold container loads the encoder. Events are `status`, then either `result` or `error`. Three ways to ask, two of them on this verb. Send `query` to search by free text. Send `seedIndex` + `seedKey` to search by example — "more like this" — using the vector of a row already in the index, which is how you find more of a result the user is looking at. To search by an image the user has, `POST` the bytes to this same path instead. Send words with a picture to narrow one with the other: **text gates, image ranks**. Candidates come from the seed, the words decide which of them survive, and visual similarity decides the order — so the results still look like the picture and the words throw out the ones that do not match. The two are never blended into one vector, which is why `queryKind` stays `similar` for a combined search; the presence of `query` on the result is what tells you a text gate was applied. Expect combined searches to return nothing fairly often, and treat that as a distinct outcome: `perIndex.
Parameters
facilityId `string` (required) Internal ID of the facility to search in query `string` (optional) Free-text description of what to look for. Required unless warm=1 or a seed is sent. Combined with a seed it stops being the thing ranked and becomes a filter over the seed's candidates, dropping those whose text score falls below the index's relevance floor. seedIndex `string` (optional) Search by example instead of by text: the index the seed row lives in (person-crops, recording-frames, timelapse-frames). This is the `index` of the hit the user clicked. Must be sent with seedKey. seedKey `string` (optional) The seed row's `key`, taken verbatim from the hit. The seed is excluded from its own results — for a recording that means the whole clip, since its other frames are 2s apart and near-identical. seedFrameId `string` (optional) Required when seedIndex is recording-frames: that index stores one row per sampled frame and they all share the clip's key, so the key alone names a clip rather than a moment. Send the hit's `frameId`. Older rows have none — send seedOffsetMs instead. seedOffsetMs `string` (optional) Fallback frame identifier for recording-frames seeds whose row predates `frame_id`. Send the hit's `offsetMs`. Ignored when seedFrameId is supplied. warm `string` (optional) Prime a Lambda container without running a search. Fire this on page load. warmTarget `string` (optional) Which encoder `warm` loads: `text` (default), `image`, or `both`. The vision tower is 355 MB against the text tower's 283 MB, so priming it is opt-in — ask for `image` only once the user has actually staged a picture, not on page load. index `string` (optional) Comma-separated datasets to search: person-crops, recording-frames, timelapse-frames. Results are merged into one score-sorted list. All three are searched by default; pass an explicit list to narrow it. timelapse-frames covers cameras that record nothing and only produce a frame a minute, and its relevance floor is not yet calibrated. model `string` (optional) Encoder to query with. Must match the encoder the dataset was indexed by. limit `string` (optional) Results to return per index (default 50, max 100) — not a total, so searching all three indexes can return up to three times this. For recordings it counts clips rather than matched frames. from `string` (optional) Only match media captured at or after this time, in milliseconds since the epoch. Note this is capture time, not upload time. to `string` (optional) Only match media captured before this time (exclusive), in milliseconds since the epoch. cameraId `string` (optional) Comma-separated camera balenaUUIDs to narrow to — the `balenaUUID` field of each entry returned by /api/cctv/recordings/filters/:club. The preferred camera filter: every index stores this same value, so one filter narrows all of them. Note that only crops whose face-detection join resolved carry it (~1% today), so narrowing crops by camera will return few or none until the crop backfill runs; recordings are fully populated and filter exactly. camera `string` (optional) Comma-separated camera names to narrow to. Effectively recordings-only: person-crops stores an empty camera name on every row, so any value here excludes all crops. Prefer cameraId. cameraGroup `string` (optional) Comma-separated camera groups to narrow to. Populated on all recordings but only ~1% of crops, same cause as cameraId. minScore `string` (optional) Override the per-index cosine floor that filters out noise. Omit in production; each index carries a calibrated default (and a separate, uncalibrated one for seeded searches). Pass 0 to see unfiltered nearest neighbours when debugging relevance.Endpoint
GET /api/cctv/search/anything/:facilityId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/search/anything/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search by an image the user has, rather than by words or by a result already on screen. Identical to the GET in every other respect — same query parameters, same event stream, same result shape — so this documents only what differs. Send the **original file bytes** as the request body with an `image/*` Content-Type. Do not resize, crop or re-encode it in the browser first: the server matches a very specific resize (a squash to 256x256 with an antialiased bilinear kernel) that the indexed vectors were built with, and canvas scaling uses a different one. Measured, that substitution lands roughly 0.93 cosine away from the right answer, which is further apart than two genuinely different images — so the results come back ranked plausibly and wrongly, with no error. Limited to 4 MB, which is a transport constraint rather than a quality one: the bytes travel inside the Lambda invoke payload, which caps at 6 MB, and base64 inflates them by a third. Results are scored image-to-image, so `queryKind` is `image` and the scores are on the same much higher scale as a seeded search — never comparable with text scores. Expect them to run slightly *below* an equivalent seeded search: a seed's vector was written by the device itself, whereas an upload is re-encoded here by a different engine, which lands it a few hundredths away from where the device would have put it. Measured, the results are of equal quality despite that; they are simply not the identical set. Adding `query` gates the results by those words, exactly as it does for a seed. Sending a seed *and* an image is rejected: both are the thing being ranked, so the pair has no meaning. This is the most expensive request the endpoint serves. An uploaded image loads the vision tower, and adding words loads the text tower too — both on a cold container. `warm=1&warmTarget=image` once the user stages a picture takes that off the critical path.
Parameters
facilityId `string` (required) Internal ID of the facility to search in body `string` (required) Raw image bytes, unmodified, 4 MB maximum query `string` (optional) Optional words to narrow the image results by, dropping matches whose text score falls below the index's relevance floor.Endpoint
POST /api/cctv/search/anything/:facilityId
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/search/anything/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns storage details and other metric data for club CCTV
Endpoint
GET /api/cctv/storage-details/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/storage-details/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of timelapse upload records of a club
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/timelapse/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/timelapse/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List user actions performed on the recordings in CCTV Frontend or UI
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/cctv/ui/actions/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/ui/actions/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Record a user action performed on the recordings in CCTV Frontend or UI
Parameters
body `string` (required) Json Object of the new config block to add to the system.Endpoint
POST /api/cctv/ui/actions/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/ui/actions/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get user token for CCTV Frontend or UI
Parameters
club `string` (required) Club IDEndpoint
GET /api/cctv/ui/token/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/ui/token/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generate token for temporary or guest access
Parameters
club `string` (required) The unique identifier for the club. body `string` (required) JSON Object of the token details to issue.Endpoint
POST /api/cctv/token/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/cctv/token/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{
"accessID": "2cdfde23-5008-4ae7-b830-374abe8d509f"
}
Returns a list of records of tokens for temporary or guest access
Parameters
club `string` (required) The unique identifier for the club.Endpoint
GET /api/cctv/token/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/cctv/token/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get access token via access ID
Parameters
accessID `string` (required) ID of the token record in the DB.Endpoint
POST /guest/cctv/token/:accessID
Example Request
curl -X POST https://portal.hub.gymsystems.co/guest/cctv/token/:accessID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a facility access hours
Parameters
facilityId `string` (required) body `object` (required) Json Object of the new access hours.Endpoint
DELETE /api/ai/computer-vision/access-hours/:facilityId
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/ai/computer-vision/access-hours/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of facility access hours
Parameters
facilityId `string` (required)Endpoint
GET /api/ai/computer-vision/access-hours/:facilityId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ai/computer-vision/access-hours/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates or creates a facility access hours
Parameters
facilityId `string` (required) body `object` (required) Json Object of the new access hours.Endpoint
POST /api/ai/computer-vision/access-hours/:facilityId
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ai/computer-vision/access-hours/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a facility access zone
Parameters
facilityId `string` (required) body `object` (required) Json Object of the new access zone.Endpoint
DELETE /api/ai/computer-vision/access-zones/:facilityId
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/ai/computer-vision/access-zones/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of facility access zones
Parameters
facilityId `string` (required)Endpoint
GET /api/ai/computer-vision/access-zones/:facilityId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ai/computer-vision/access-zones/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates or creates a facility access zone
Parameters
facilityId `string` (required) body `object` (required) Json Object of the new access zone.Endpoint
POST /api/ai/computer-vision/access-zones/:facilityId
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ai/computer-vision/access-zones/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the union of all admin module IDs across brands and facilities for an organisation, populated as module objects.
Parameters
organisationId `string` (required) Organisation IDEndpoint
GET /api/organisations/{organisationId}/admin-modules
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/organisations/{organisationId}/admin-modules \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List org-level HQ canned response templates used as global suggestions in the customer review reply dialog.
Parameters
organisationId `string` (required)Endpoint
GET /api/organisations/{organisationId}/hq-canned-responses
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/organisations/{organisationId}/hq-canned-responses \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Replace the full list of HQ canned response templates for the organisation.
Parameters
organisationId `string` (required)Endpoint
PUT /api/organisations/{organisationId}/hq-canned-responses
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/organisations/{organisationId}/hq-canned-responses \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of all organisations
Parameters
includeBrands `string` (optional) Include brands associated with the organisation includeFacilities `string` (optional) Include facilities associated with the organisation includeRegions `string` (optional) Include regions associated with the organisationEndpoint
GET /api/organisations
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/organisations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert an organisation
Parameters
organisationId `string` (optional) The ID of the organisation to update logo `string` (optional) An s3 object including the key and bucket name or an object containing the url of the logo name `string` (required) The name of the organisation modules `string` (optional) A list of the modules the organisation has access to disabledModules `string` (optional) Deny list of catalog modules flagged defaultOn that this organisation has explicitly opted out of websiteDomain `string` (optional) The domain name of the organisation primaryContactName `string` (optional) The name of the primary contact for the organisation primaryContactPhone `string` (optional) The phone number of the primary contact for the organisation registeredAddress `string` (optional) The registered address of the organisation organisationType `string` (optional) The type of organisation organisationTypeOther `string` (optional) The type of organisation if other platformStack `string` (optional) The account type / platform stack for the organisation. Controls which modules are available: 'business' (Business Suite + Technology Stack, all modules, default) or 'technology' (Technology Stack only, limited subset).Endpoint
PUT /api/organisations
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/organisations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
A simple AI helper to analise the contents of a support ticket and create suggestions based on available topics as well as suggested algolia search topics...
Parameters
messageBody `string` (required) Body of the message to send topicData `string` (required) Json object/array of the topicData returned from osTicket (ticketing/support system) facilityId `string` (optional) The internal ID of the club needed to determine the correct Algolia index to search against.Endpoint
PUT /api/ai/helpers/analyse-support-ticket
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ai/helpers/analyse-support-ticket \
-H "x-api-key: YOUR_API_KEY"
Response
{}
A simple image generation api
Parameters
type `string` (required) Type of image to generate name `string` (required) Image name maxSize `string` (optional) Optional maximum response size, e.g. 200KB, 1MB or a plain byte count. The image is downscaled/compressed to fit.Endpoint
PUT /api/ai/images/:type/:name
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ai/images/:type/:name \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Simple LLM query
Lightweight endpoint for simple, stateless LLM queries. Uses a cheap, non-reasoning model (gpt-4o-mini) with strict token limits. No conversation history, no tools, no streaming — just prompt in, text out.
Request Body
Endpoint
POST /api/ai/llm/query
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ai/llm/query \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
A simple AI helper to analise the contents of a support ticket and create suggestions based on available topics as well as suggested algolia search topics...
Parameters
messageBody `string` (required) Body of the message to send topicData `string` (required) Json object/array of the topicData returned from osTicket (ticketing/support system)Endpoint
PUT /internal/ai/helpers/analyse-support-ticket
Example Request
curl -X PUT https://portal.hub.gymsystems.co/internal/ai/helpers/analyse-support-ticket \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the Algolia configuration including index name, app ID, and API key.
Parameters
facilityId `string` (required)Endpoint
GET /api/facilities/{facilityId}/algolia/config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/algolia/config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initializes the Algolia marketing print index
Parameters
organisationId `string` (required)Endpoint
PUT /api/algolia/index
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/algolia/index \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search for marketing print materials
Request Body
Endpoint
POST /algolia/search-marketing-print
Example Request
curl -X POST https://portal.hub.gymsystems.co/algolia/search-marketing-print \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Search for marketing print materials
Parameters
club `string` (optional) Club ID searchTerms `string` (optional) Search terms algoliaArgs `object` (optional) Additional Algolia search argumentsEndpoint
GET /algolia/search-marketing-print
Example Request
curl -X GET https://portal.hub.gymsystems.co/algolia/search-marketing-print \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bulk update marketing print objects for a specific club
Endpoint
POST /algolia/bulk-update-marketing-print
Example Request
curl -X POST https://portal.hub.gymsystems.co/algolia/bulk-update-marketing-print \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Fetches marketing print assets from Algolia.
Parameters
organisationId `string` (required) search `string` (optional) limit `string` (optional) brand `string` (optional) tag `string` (optional)Endpoint
GET /api/algolia/marketing/assets
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/algolia/marketing/assets \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initializes the Algolia marketing print index with the facility's configuration.
Parameters
organisationId `string` (required)Endpoint
POST /api/algolia/marketing/assets
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/algolia/marketing/assets \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Performs a search against a specified Algolia index based on search terms, club, and/or locale. The search can be further customized using additional Algolia arguments.
Parameters
searchTerms `string` (required) The terms to search for in the Algolia index. club `string` (optional) Internal ID of the club that is making the request. If specified, the search will be filtered based on the region associated with the club. locale `string` (optional) The locale to use for determining the region if a club is not specified. Derived from navigator.languages. algoliaArgs `string` (optional) Additional/custom arguments to pass through to the Algolia search request.Endpoint
POST /api/algolia/search-wiki
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/algolia/search-wiki \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Removes an announcement from the system.
Parameters
body `string` (required) Json Object of the design ID to remove.Endpoint
DELETE /api/announcements/delete
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/announcements/delete \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all announcements
Endpoint
GET /api/announcements/list
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/announcements/list \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Saves/Updates one or more announcements in the system.
Parameters
body `object` (required) Json object containing the announcement to add/update/save in the system...Endpoint
PUT /api/announcements/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/announcements/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Uploads an image for the announcements WYSIWYG editor, and returns response suitable for Froala Image Upload: [https://froala.com/wysiwyg-editor/docs/concepts/image/upload/](https://froala.com/wysiwyg-editor/docs/concepts/image/upload/)
Parameters
file `string` (optional) Name of the file/asset to be uploaded.Endpoint
POST /api/announcements/upload-image
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/announcements/upload-image \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Uploads an asset to a PUBLIC S3 BUCKET (via the Upload API) which then will post-process/optimise the file, generate thumbnails etc. *Note, Assets will be publicly available*
Parameters
file `string` (optional) Name of the file/asset to be uploaded.Endpoint
POST /api/asset-upload
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/asset-upload \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the status of upload by the given uuid of the upload record
Parameters
uuid `string` (required) UUID of the upload recordEndpoint
GET /api/asset-upload/:uuid
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/asset-upload/:uuid \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Send a command to club Sonos
Parameters
body `object` (required) Json Object of the command and input to send to Sonos.Endpoint
PUT /api/audio-control/command/:club
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/audio-control/command/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieve configuration for Audio Control Frontend
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/audio-control/config/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/audio-control/config/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Change configuration for Audio Control Frontend
Parameters
body `object` (required) Json Object of the new config block to add to the system.Endpoint
PUT /api/audio-control/config/:club/:section
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/audio-control/config/:club/:section \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieves brand settings for a specific region
Parameters
brandId `string` (optional) The ID of the brand regionCode `string` (optional) The ISO code of the region to retrieve settings forEndpoint
GET /api/brands/{brandId}/regions/{regionCode}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands/{brandId}/regions/{regionCode} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates multiple brand settings for a specific region
Parameters
brandId `string` (optional) The ID of the brand to update regionCode `string` (optional) The ISO code of the region to update settings for acceptFreeTrialBookingsVisibility `string` (optional) customTrackingCodeVisibility `string` (optional) displayDataSources `string` (optional) displayDefaultDataSource `string` (optional) displayDefaultUI `string` (optional) displayUIOptions `string` (optional) defaultAboutBusiness `string` (optional) defaultAboutBusinessFacebook `string` (optional) facilityCoverImage `string` (optional) digitalProfileSettingsVisibility `string` (optional) facilityHoursVisibility `string` (optional) facilityLocationVisibility `string` (optional) facilityPaymentMethods `string` (optional) facilityPrimaryLogo `string` (optional) facilityStatusVisibility `string` (optional) landingPagesVisibility `string` (optional) lineChatIntegrationVisibility `string` (optional) whatsAppIntegrationVisibility `string` (optional) defaultWhatsAppMessage `string` (optional) socialUrlsVisibility `string` (optional) yextApiKey `string` (optional) API key used by the Yext integration for this brand-region. Only consulted when `directorySyncMode` is `yext`. directorySyncMode `string` (optional) Which sync backend should run for facilities under this brand-region. Defaults to `yext` when missing for back-compat with brands that pre-date the Directory Publishers rollout. websiteUrl `string` (optional) androidAppUrl `string` (optional) iosAppUrl `string` (optional) featuredMessageDescription `string` (optional) yextCategoryIds `string` (optional) Legacy storage key — these are actually Google Business Profile category IDs (e.g. gcid:gym). The "yext" prefix predates the Yext deprecation; kept for back-compat with existing DB rows. customInputFields `string` (optional) customInputFieldsToRemove `string` (optional)Endpoint
PUT /api/brands/{brandId}/regions/{regionCode}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/brands/{brandId}/regions/{regionCode} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieves brand settings for a specific facility
Parameters
facilityId `string` (optional) The ID of the facility to retrieve brand settings forEndpoint
GET /api/facilities/{facilityId}/brand-settings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/brand-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a new brand
Parameters
name `string` (required) The name of the brand organisationId `string` (required) The ID of the organisation the brand belongs to redirectDashboard `string` (optional) The URL to redirect to after logging in instead of the default dashboardEndpoint
POST /api/brands
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/brands \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all brands
Endpoint
GET /api/brands
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the brand object
Parameters
brandId `string` (required) The ID of the brand to retrieve includeOrganisation `boolean` (optional) Whether to include the organisation data in the responseEndpoint
GET /api/brands/{brandId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands/{brandId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a brand by ID
Parameters
brandId `string` (optional) The ID of the brand to update name `string` (required) The name of the brand brandOrganisationId `string` (optional) The ID of the organisation the brand belongs to redirectDashboard `string` (optional) The URL to redirect to after logging in instead of the default dashboard yextApiKey `string` (optional) The API key used to access the Yext API for this brand adminModules `string` (optional) Admin-only module IDs (global admins only) customMenuLayout `object` (optional) Per-brand side-menu layout tree (sections / groups / items with refs to system modules or custom URLs). Only settable by a global admin or an organisation admin for this brand's organisation.Endpoint
PUT /api/brands/{brandId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/brands/{brandId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List facilities for a brand
Returns a lightweight list of facilities (id, name, region ISO code) belonging to the brand. Used to populate facility targeting selectors in brand config.
Parameters
brandId `string` (required) The ID of the brand to list facilities forEndpoint
GET /api/brands/{brandId}/facilities
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands/{brandId}/facilities \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all brands associated with the organisation of the club.
Endpoint
GET /api/clubs/{club}/brands
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/brands \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all calendar types
Endpoint
GET /api/programs/calendars/calendar-types
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/programs/calendars/calendar-types \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the KYC asset for a club.
Parameters
clubId `string` (required) The ID of the club. key `string` (required) The key of the KYC asset.Endpoint
GET /api/clubs/{clubId}/kyc-assets/{key}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubId}/kyc-assets/{key} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the club KYC information.
Endpoint
GET /api/clubs/{clubId}/kyc
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubId}/kyc \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the club KYC information.
Parameters
clubId `string` (required) The ID of the club to update. body `object` (required)Endpoint
PUT /api/clubs/{clubId}/kyc
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubId}/kyc \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Uploads a KYC asset for a club.
Parameters
clubId `string` (required) The ID of the club. file `string` (required) The file to upload.Endpoint
POST /api/clubs/{clubId}/kyc-assets
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubId}/kyc-assets \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the club preference settings.
Endpoint
GET /api/club/preferences/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/preferences/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates or updates club preferences entry.
Request Body
Endpoint
POST /api/club/preferences/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/club/preferences/:club \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Returns list of members with agreement.
Endpoint
GET /api/clubpass/user/email/exist/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubpass/user/email/exist/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of members with agreement.
Endpoint
GET /api/clubpass/user/phone/exist/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubpass/user/phone/exist/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of users that belong to the specified club
Parameters
club `string` (required) Internal ID of the club that you wish to accessEndpoint
GET /api/clubs/{club}/members
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/members \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns if club is open on given date.
Parameters
club `string` (required) Internal ID of the club that you wish to access. date `string` (required) Date to check for in unix formatEndpoint
GET /api/club-busy-hours/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club-busy-hours/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all metadata for the Club that is displayed on the UBX websites.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/clubs/clubpage/clubdata/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/clubpage/clubdata/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a club's Meta Data with new data provided from the front-end. Fields absent from the request body are preserved (no SET, no REMOVE). Fields sent as `null` or empty string are cleared. Pass `updateAll: false` to use the dedicated partial-merge path; either way, callers never need to send fields they don't own.
Parameters
club `string` (required) Internal ID of the club that you wish to access. body `string` (required) Json Object of club data that you wish to update.Endpoint
POST /api/clubs/clubpage/updateclub/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/clubpage/updateclub/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
add new custom tracking record
Parameters
club `string` (required) id of the club body `string` (required) Array of custom tracking items.Endpoint
POST /api/clubs/{club}/customtracking
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{club}/customtracking \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns custom tracking for specific club
Endpoint
GET /api/clubs/customtracking/:clubID
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/customtracking/:clubID \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update custom tracking entries
Parameters
club `string` (required) id of the club body `string` (required) Json Object of club data that you wish to update.Endpoint
POST /api/clubs/{club}/customtracking/update
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{club}/customtracking/update \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the default shop front image for a club.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/clubs/{club}/default-shop-front
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/default-shop-front \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List doors available in the facility
Parameters
body `object` (required) JSON Object of club data that you wish to update.Endpoint
POST /api/clubs/integrations/doors/:facilityId
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/integrations/doors/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Unlock a specific door in the facility
Parameters
body `object` (required) JSON Object of club data that you wish to update.Endpoint
POST /api/clubs/integrations/doors/unlock
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/integrations/doors/unlock \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all integrations and the configuration details for the specified club.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/clubs/integrations/list/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/integrations/list/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a club's Meta Data with new data provided from the front-end.
Parameters
club `string` (required) Internal ID of the club that you wish to access. body `object` (required) Json Object of club data that you wish to update.Endpoint
POST /api/clubs/integrations/update/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/integrations/update/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns boolean if club is a European country or not
Parameters
club `string` (required) Internal ID of the club that you wish to access. date `string` (required) Date to check for in unix formatEndpoint
GET /api/clubs/is-eu/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/is-eu/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns high level list of all clubs in our database.
Endpoint
GET /api/clubs/listclubs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/listclubs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns if club is open on given date.
Parameters
club `string` (required) Internal ID of the club that you wish to access. date `string` (required) Date to check for in unix formatEndpoint
GET /api/clubs/{club}/open-on/{date}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/open-on/{date} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the club reviews from dynamo db.
Parameters
club `string` (required) Club IDEndpoint
GET /api/clubs/{club}/reviews
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/reviews \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the club reviews settings from dynamo db.
Parameters
facilityId `string` (required) facility IDEndpoint
GET /api/clubs/{club}/reviews-settings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/reviews-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the club reviews settings on dynamo db.
Parameters
club `string` (required) Club IDEndpoint
PUT /api/clubs/{club}/reviews-settings
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Re-enable review settings auto pyblish.
Parameters
club `string` (required) Club IDEndpoint
PUT /api/clubs/{club}/reviews/publish-recent-reviews
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews/publish-recent-reviews \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Publishes a review
Parameters
club `string` (required) Internal ID of the club that you wish to access. review `string` (required) Internal ID of the review that you wish to publish.Endpoint
PUT /api/clubs/{club}/reviews/{review}/publish
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews/{review}/publish \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Re-enable review settings auto pyblish.
Parameters
club `string` (required) Club IDEndpoint
PUT /api/clubs/{club}/reviews-settings/re-enable-auto-publish
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews-settings/re-enable-auto-publish \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Post a response to a review back out through its originating publisher (Google etc.).
Parameters
club `string` (required) Facility ID reviewId `string` (required) PH review ID (looked up against the club-social-reviews table) body `string` (required)Endpoint
POST /api/clubs/{club}/reviews/{reviewId}/respond
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{club}/reviews/{reviewId}/respond \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Un-publishes a review
Parameters
club `string` (required) Internal ID of the club that you wish to access. review `string` (required) Internal ID of the review that you wish to un-publish.Endpoint
PUT /api/clubs/{club}/reviews/{review}/un-publish
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews/{review}/un-publish \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of owners that belong to the specified club from the PH db
Parameters
clubID `string` (required) Internal ID of the club that you wish to accessEndpoint
GET /api/clubs/{clubID}/owners
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/owners \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all membership plans for the facility.
Parameters
facilityId `string` (required) Internal ID of the facilityEndpoint
GET /api/facilities/membership-plans/:facilityId
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/membership-plans/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a membership plan record.
Parameters
facilityId `string` (required) Internal ID of the facility body `object` (required) JSON Object of membership plan data that you wish to update.Endpoint
PUT /api/facilities/membership-plans/:facilityId
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/facilities/membership-plans/:facilityId \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Re-enable review settings auto pyblish.
Parameters
club `string` (required) Club IDEndpoint
PUT /api/clubs/{club}/reviews/publish-recent-reviews
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews/publish-recent-reviews \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Re-enable review settings auto pyblish.
Parameters
club `string` (required) Club IDEndpoint
PUT /api/clubs/{club}/reviews-settings/re-enable-auto-publish
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{club}/reviews-settings/re-enable-auto-publish \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all available currencies
Endpoint
GET /api/currencies
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/currencies \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the geographical location using IP address.
Parameters
ip `string` (required) IP address to look upEndpoint
GET /api/geo/ip-location/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/geo/ip-location/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the geographical location of the current user based on their IP.
Endpoint
GET /api/geo/ip-current
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/geo/ip-current \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the requesting client's public IP address only (no geolocation lookup, no third-party API call). Used by the AI Agent applet to compare the browser's public IP with a device's beaconed WAN IP for same-network detection.
Endpoint
GET /api/geo/client-ip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/geo/client-ip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Phone parser.
Parameters
body `string` (required) Json Object of the number you wish to parse.Endpoint
POST /api/phone/parser
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/phone/parser \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns master clock device
Parameters
club_id `string` (required) Internal ID of the club that you wish to add the device under.Endpoint
GET /api/clubs/{club_id}/smart-club/health-check/master-clock
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club_id}/smart-club/health-check/master-clock \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns master sonos device
Parameters
club_id `string` (required) Internal ID of the club that you wish to add the device under.Endpoint
GET /api/clubs/{club_id}/smart-club/health-check/sonos-mqtt
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club_id}/smart-club/health-check/sonos-mqtt \
-H "x-api-key: YOUR_API_KEY"
Response
{}
get low battery duress notifications for a given club.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/clubs/{club}/smart-club/health-check/low-battery-duress
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/smart-club/health-check/low-battery-duress \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns network analysis data
Parameters
club_id `string` (required) Internal ID of the club that you wish to add the device under.Endpoint
GET /api/clubs/{club_id}/smart-club/health-check/network-analysis
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club_id}/smart-club/health-check/network-analysis \
-H "x-api-key: YOUR_API_KEY"
Response
{}
send low battery duress notifications for a given club.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/clubs/{club}/smart-club/health-check/send-low-battery-duress-notifs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club}/smart-club/health-check/send-low-battery-duress-notifs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns device speed test data for each device type
Parameters
club_id `string` (required) Internal ID of the club that you wish to add the device under.Endpoint
GET /api/clubs/{club_id}/smart-club/health-check/speed-test
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{club_id}/smart-club/health-check/speed-test \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List publisher configs for an organisation.
Parameters
organisationId `string` (required)Endpoint
GET /api/admin/directory-publishers/config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/directory-publishers/config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable/disable a publisher at org level, or store OAuth credentials.
Endpoint
PUT /api/admin/directory-publishers/config
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/directory-publishers/config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Connect Apple Business Connect for an organisation by storing the org's ABC Company ID. The org must delegate access to UBX's Partner ID in the Apple Business Connect portal before sync can succeed.
Parameters
organisationId `string` (required)Request Body
Endpoint
POST /api/admin/directory-publishers/{organisationId}/apple/connect
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/directory-publishers/{organisationId}/apple/connect \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Connect Facebook Pages for an organisation by accepting a Meta App's App ID, App Secret, and a long-lived user access token. Verifies scopes via /debug_token, exchanges the supplied token for a fresh 60-day token, fetches the user identity, and persists the credentials onto the directorypublisherconfig record.
Parameters
organisationId `string` (required)Request Body
Endpoint
POST /api/admin/directory-publishers/{organisationId}/facebook/connect
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/directory-publishers/{organisationId}/facebook/connect \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List candidate listings owned by the org's connected publisher account. Used by the Bind dialog to let admins attach an existing publisher entity to a PH facility instead of creating a duplicate.
Parameters
organisationId `string` (required) publisherId `string` (required)Endpoint
GET /api/admin/directory-publishers/{organisationId}/{publisherId}/listings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/directory-publishers/{organisationId}/{publisherId}/listings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generate OAuth URL for a publisher connection.
Parameters
publisherId `string` (required) organisationId `string` (required)Endpoint
GET /api/admin/directory-publishers/auth-url
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/directory-publishers/auth-url \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Handle OAuth callback from a publisher.
Parameters
code `string` (required) state `string` (required)Endpoint
GET /api/admin/directory-publishers/callback
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/directory-publishers/callback \
-H "x-api-key: YOUR_API_KEY"
Disconnect a publisher from an organisation.
Parameters
organisationId `string` (required) publisherId `string` (required)Endpoint
DELETE /api/admin/directory-publishers/{organisationId}/{publisherId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/directory-publishers/{organisationId}/{publisherId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Rotate the Facebook long-lived user token for an already-connected org without going through full disconnect/reconnect. Reuses the stored App ID + App Secret, verifies the pasted token has every required scope, exchanges it for a fresh 60-day token, and writes only the token-scoped fields onto authCredentials. connectedAt / connectedBy / enabled / createdAt are intentionally untouched so the publisher card "Connected by ..." identity stays put. 404s if the org has no existing Facebook config — admins must do a full /facebook/connect first to provide App ID + Secret.
Parameters
organisationId `string` (required)Request Body
Endpoint
POST /api/admin/directory-publishers/{organisationId}/facebook/refresh-token
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/directory-publishers/{organisationId}/facebook/refresh-token \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Returns the publishers enabled for the facility's organisation, with their connection status.
Parameters
facilityId `string` (required) organisationId `string` (required)Endpoint
GET /api/facilities/{facilityId}/directory-publishers/resolved
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/directory-publishers/resolved \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get listing insights for a facility. Returns aggregated daily totals across publishers by default, or a single publisher when `publisherId` is supplied.
Parameters
facilityId `string` (required) publisherId `string` (optional) startDate `string` (required) endDate `string` (required)Endpoint
GET /api/facilities/{facilityId}/directory-insights
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/directory-insights \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get aggregated listing insights for a brand across all publishers.
Parameters
brandId `string` (required) startDate `string` (required) endDate `string` (required)Endpoint
GET /api/brands/{brandId}/directory-insights
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands/{brandId}/directory-insights \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Top search keywords (with branded/unbranded split) for a facility, currently sourced from Google Business Profile.
Parameters
facilityId `string` (required) publisherId `string` (optional) Defaults to "google" — only Google is supported today. startDate `string` (required) endDate `string` (required) limit `string` (optional)Endpoint
GET /api/facilities/{facilityId}/directory-search-keywords
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/directory-search-keywords \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Top search keywords for a brand, aggregated across all facilities.
Parameters
brandId `string` (required) startDate `string` (required) endDate `string` (required) limit `string` (optional)Endpoint
GET /api/brands/{brandId}/directory-search-keywords
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/brands/{brandId}/directory-search-keywords \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List Q&A for a facility.
Parameters
facilityId `string` (required)Endpoint
GET /api/facilities/{facilityId}/qna
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/qna \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Answer a question.
Endpoint
POST /api/facilities/{facilityId}/qna/{questionId}/answer
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/facilities/{facilityId}/qna/{questionId}/answer \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete an answer.
Endpoint
DELETE /api/facilities/{facilityId}/qna/{questionId}/answer/{answerId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/facilities/{facilityId}/qna/{questionId}/answer/{answerId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all sync log entries, optionally filtered.
Parameters
publisherId `string` (optional) organisationId `string` (optional) facilityId `string` (optional) Restrict to a single facility (used by the customer Directory Management page).Endpoint
GET /api/admin/directory-sync/status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/directory-sync/status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually trigger sync for a specific facility or all facilities.
Endpoint
POST /api/admin/directory-sync/trigger
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/directory-sync/trigger \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Set or clear the publisher-side `externalId` for a (facility, publisher) pair. Used by the Bind dialog so admins can attach a PH facility to an existing publisher listing instead of letting the worker auto-create a duplicate. Pass `externalId: null` (or empty string) to unbind.
Endpoint
PUT /api/admin/directory-sync/binding
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/directory-sync/binding \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Fan out a sync for every enabled+connected (facility, publisher) pair under the given organisation.
Endpoint
POST /api/admin/directory-sync/trigger-all
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/directory-sync/trigger-all \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get Access Policies for a facility
Existing access configuration is automatically converted to equivalent enforced policies on first read.
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/policies/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Replace Access Policies using optimistic revision checking
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/door-access/policies/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Create an Access Policy
Parameters
facilityId `string` (required)Endpoint
POST /api/door-access/policies/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update one Access Policy
Parameters
facilityId `string` (required) policyId `string` (required)Endpoint
PATCH /api/door-access/policies/{facilityId}/{policyId}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId}/{policyId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete one Access Policy
Parameters
facilityId `string` (required) policyId `string` (required) revision `integer` (required)Endpoint
DELETE /api/door-access/policies/{facilityId}/{policyId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId}/{policyId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Duplicate an Access Policy with a new stable ID
Parameters
facilityId `string` (required) policyId `string` (required)Endpoint
POST /api/door-access/policies/{facilityId}/{policyId}/duplicate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId}/{policyId}/duplicate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Count affected users and doors for all Access Policies
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/policies/{facilityId}/impacts
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId}/impacts \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Count users and doors affected by an Access Policy
Parameters
facilityId `string` (required) policyId `string` (required)Endpoint
GET /api/door-access/policies/{facilityId}/{policyId}/impact
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/policies/{facilityId}/{policyId}/impact \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List door controllers at a facility with their effective Door/Gate Access rules
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/doors/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Save per-door overrides, icon, and device-side configuration
Single write surface for everything the DGA admin applet edits on a door: - `accessRulesOverride` / `geofenceOverride` — pass `null` to clear and fall back to the facility default. - `icon` — stable wire key (see services/door-access/door-icons.js); unknown values 400. - `holdTimeSeconds` (1\u201330), `maintenanceMode` (`off` / `force-open` / `force-closed`), `doorLocation` (free text, \u226464 chars), `playNotificationSoundOnRelayToggle` (boolean), `autoUnlockSchedule` (weekly window grid). These used to be Device-Management-only fields but the applet now writes them in-place so admins don't need to leave the door drawer for everyday config changes. When any of the device-side fields are touched the route also pushes the matching Balena env vars (`RELAY_NOTIFICATION_SOUND`, `DOOR_MAINTENANCE_MODE`, `DOOR_AUTO_UNLOCK_SCHEDULE`) and fires an `unlockUpdates` MQTT command so the device picks up the new config without waiting for the next Balena env refresh. Best-effort \u2014 the response 200s even if Balena is temporarily unreachable.
Parameters
facilityId `string` (required) doorId `string` (required)Request Body
Endpoint
PUT /api/door-access/doors/{facilityId}/{doorId}/override
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId}/{doorId}/override \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Lightweight Balena-status probe for the door drawer's reload notice
The DGA applet's drawer fetches this lazily when an admin opens a door so it can show the right "saving will reload the controller" copy: the default "a few seconds" variant, or the stronger "several minutes" variant when a release update is also pending. Returns a flat snapshot derived from `balena.models.device.get()`. Soft-fails to `data: null` (rather than 5xx-ing) so a Balena outage degrades the notice copy instead of blocking the drawer from opening.
Parameters
facilityId `string` (required) doorId `string` (required)Endpoint
GET /api/door-access/doors/{facilityId}/{doorId}/device-status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId}/{doorId}/device-status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Admin override — unlock a door from the applet
Briefly toggles the relay using the door's current `holdTimeSeconds`, writing an `admin-override` audit row to ph-door-app-access-events so the action is attributable in the Access Logs. Always succeeds regardless of `maintenanceMode === 'force-closed'` — this is the admin escape hatch. Returns 200 as soon as the MQTT publish is dispatched; confirmed / failed / timed_out states are not waited for here (the legacy /api/devices/door-controllers + /api/ics/devices/command flow is fire-and-forget too).
Parameters
facilityId `string` (required) doorId `string` (required)Endpoint
POST /api/door-access/doors/{facilityId}/{doorId}/unlock
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId}/{doorId}/unlock \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Play a locator beep pattern on the door controller
Publishes a `beep` MQTT command so the controller emits three medium-length beeps (~500 ms each, ~350 ms gap, ~2 s total). Used by admins to physically locate a door controller on-site. The legacy Device Management button uses a ~30 s burst of short beeps but the firmware buzzer driver only reliably emits the first one, so the applet sends a shorter, more reliable pattern instead. No audit row \u2014 diagnostic action with no access-control side effect.
Parameters
facilityId `string` (required) doorId `string` (required)Endpoint
POST /api/door-access/doors/{facilityId}/{doorId}/identify
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId}/{doorId}/identify \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remotely reboot a door controller
Publishes the same fire-and-forget `rebootDevice` MQTT command the legacy Device Management "Remotely Reboot Device" button sends, but gated by the `door-gate-access` module so DGA admins can reboot a controller from the door drawer's Advanced section without a separate `device-management` grant. Returns 200 as soon as the publish is dispatched; the device drops offline for the duration of the reboot.
Parameters
facilityId `string` (required) doorId `string` (required)Endpoint
POST /api/door-access/doors/{facilityId}/{doorId}/reboot
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/doors/{facilityId}/{doorId}/reboot \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List User Access rows at a facility
Returns every non-deleted user-access row at the facility. Supports client-side filters (source, search, accessEnabled, hasGrants). The Phase 4 `hideExcluded` server-side computation will be added once the hybrid grants evaluator lands; for now the param is accepted but returns the full set.
Parameters
facilityId `string` (required) search `string` (optional) source `string` (optional) accessEnabled `string` (optional) hasGrants `string` (optional) hideExcluded `boolean` (optional) When true, synced users (source != manual) who could not pass any door at any time at this facility are hidden. The response includes a `hidden: { count, sample }` envelope.Endpoint
GET /api/door-access/users/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/users/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Manually create a User Access row at a facility
Mints a new row with `source: 'manual'`. Returns 409 with `existingUserId` if the supplied phone or email already maps to a row at this facility.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/users/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Get a single User Access row
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
GET /api/door-access/users/{facilityId}/{userId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Partial update of a User Access row
Edits any subset of identity / authorization fields. Pass `null` to clear an optional field. Returns 409 if the new phone or email collides with another row at the same facility. `appMessage` accepts the same shape as the facility-wide message on PUT /api/door-access/rules/{facilityId} — body text, severity, optional link, optional start/end schedule. The mobile app shows this on the dashboard only for the targeted user.
Parameters
facilityId `string` (required) userId `string` (required)Request Body
Endpoint
PATCH /api/door-access/users/{facilityId}/{userId}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Soft-delete a User Access row
Marks the row `deleted: true` and disables access. Audit-log linkage to the userId is preserved; admins can re-enable manually.
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
DELETE /api/door-access/users/{facilityId}/{userId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Per-door access attribution for a user
For every door, returns current deterministic authorization (`allowedNow`, `allowedVia`, `deniedReason`) and configured paths for Access Policies, permanent grants, policy schedules, admin time-window grants, and fresh mapped partner source windows. Also returns active/next availability and source freshness. Door blockAllAccess and maintenance are evaluated before all allow paths.
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
GET /api/door-access/users/{facilityId}/{userId}/effective-access
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/effective-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bulk-create User Access rows from a CSV import
Creates multiple `source: 'manual'` rows in one request, reusing the same validation, phone/email normalisation, per-facility collision check, auto-messaging and (optional) invite logic as the single create. Rows are processed in order, so a later row colliding with an earlier-created one is reported as a duplicate. Grants are supplied as already-resolved door/group IDs (the client resolves names to IDs). Time-window grants are intentionally rejected in bulk and must be added through the per-user replacement endpoint after import. Never throws per-row; each row's outcome is reported individually.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/users/{facilityId}/bulk
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/bulk \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Replace additive Access Time Window grants on a User Access row
Replaces only `timeWindowGrants`; permanent `grants` and integration `sourceTimeWindows` are untouched. Each item requires a scope (`facilityWide`, `doors`, or `groups`) and an absolute or weekly `window`. Sending an empty array explicitly clears all admin windows.
Parameters
facilityId `string` (required) userId `string` (required)Request Body
Endpoint
PUT /api/door-access/users/{facilityId}/{userId}/time-window-grants
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/time-window-grants \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Freeze a User Access row against source-driven sync updates
Sets `decoupledFromSource: true`, clears all integration-owned `sourceTimeWindows`, and makes sync (cron + streams) log + skip this row until an admin clears the flag via /recouple.
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
POST /api/door-access/users/{facilityId}/{userId}/decouple
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/decouple \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Re-attach a User Access row to source-driven sync updates
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
POST /api/door-access/users/{facilityId}/{userId}/recouple
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/recouple \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Revoke all Door/Gate Access app refresh tokens for a user
Revokes by the user's stored phone/email (the refresh-token table is keyed by `sha256(plaintext)`; the byMobilePhone / byEmail GSIs let us fan-out delete from a single user). Other users sharing the same phone/email at a different facility would also be signed out.
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
POST /api/door-access/users/{facilityId}/{userId}/logout
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/logout \
-H "x-api-key: YOUR_API_KEY"
Response
{}
(Re)send the Door/Gate Access app invitation email to a user
Force-sends the app-download invitation email to the user's stored email address (email only; no SMS). Ignores the eligibility and already-sent guards used by the automatic sync path — this is an explicit admin action. Returns 400 if the user has no email on file.
Parameters
facilityId `string` (required) userId `string` (required)Endpoint
POST /api/door-access/users/{facilityId}/{userId}/resend-invite
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/{userId}/resend-invite \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Preview the recipients of a bulk app-invitation send
Computes the set of users who would receive an app invitation email. The base pool is every non-deleted user with an email who has never used the app (`appLastSeenAt` empty). By default the pool is narrowed to users who currently have access (rule match or grant) and have never been invited; `includeAlreadyInvited` and `includeNoAccess` widen it. No emails are sent — returns counts, a small sample, and the candidate userIds for the execute endpoint.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/users/{facilityId}/bulk-invite/preview
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/bulk-invite/preview \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Send app invitation emails to a batch of users
Sends the app-download invitation email to each of the supplied userIds (max 50 per request; the client batches the full candidate list from the preview). Each user is re-validated at send time — rows that no longer exist, have no email, or have used the app since the preview are skipped, never failed. Per-user outcomes are reported individually so the client can summarise sent / failed / skipped.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/users/{facilityId}/bulk-invite
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/users/{facilityId}/bulk-invite \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List Door Groups at a facility
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/door-groups/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/door-groups/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a Door Group
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/door-groups/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/door-groups/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Get a single Door Group
Parameters
facilityId `string` (required) groupId `string` (required)Endpoint
GET /api/door-access/door-groups/{facilityId}/{groupId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/door-groups/{facilityId}/{groupId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a Door Group
Parameters
facilityId `string` (required) groupId `string` (required)Request Body
Endpoint
PATCH /api/door-access/door-groups/{facilityId}/{groupId}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/door-access/door-groups/{facilityId}/{groupId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Soft-delete a Door Group
Parameters
facilityId `string` (required) groupId `string` (required)Endpoint
DELETE /api/door-access/door-groups/{facilityId}/{groupId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/door-access/door-groups/{facilityId}/{groupId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List the partner integrations configured at a facility
Returns the facility's partner integrations (id, name, logo, enabled) by joining ph-facility-partner-config with the ph-partners catalog. Door-gate-access-scoped (so admins without external-integrations access can still render partner badges and the per-partner sync list).
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/partners/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/partners/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Read the User Access sync config for a facility
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/sync-config/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/sync-config/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the User Access sync config for a facility
Only the admin-controlled fields (`enabled`, `requireIdentifier`, and the partner `partners` map) are accepted; `lastRunAt` and `lastRunCounts` are written by the sync engine itself. `partner.partners` is a per-partner enable map keyed by partnerId (opt-out): when the master `partner.enabled` is on, a partner syncs unless it has an explicit `{ enabled: false }` entry here.
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/door-access/sync-config/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/sync-config/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Read the automated per-user messaging config for a facility
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/auto-messages/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/auto-messages/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the automated per-user messaging config for a facility
Saves the rules, then immediately re-evaluates every User Access row at the facility so existing users get/lose their automated message right away. Manual messages and decoupled rows are left untouched.
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/door-access/auto-messages/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/auto-messages/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Status of the background auto-message re-evaluation sweep
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/auto-messages/{facilityId}/sweep-status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/auto-messages/{facilityId}/sweep-status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Run an on-demand User Access sync for a facility
Synchronously sweeps every enabled source (partner / cctv) at the facility and converges ph-door-access-users rows via the dedup waterfall. Returns per-source counts. Disabled sources show up as `skippedSyncDisabled: 1` rather than absent so the UI can render both rows consistently.
Parameters
facilityId `string` (required)Endpoint
POST /api/door-access/sync/{facilityId}/run
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/sync/{facilityId}/run \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Dry-run preview of a partner-synced bulk delete
Returns the count + a sample of the user-access rows that would be soft-deleted, plus a confirmToken that must be echoed back to the execute endpoint. No data is modified. Access logs are never affected.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/sync/{facilityId}/bulk-delete/preview
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/sync/{facilityId}/bulk-delete/preview \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Execute a partner-synced bulk delete (soft delete)
Soft-deletes every partner-synced user-access row in scope. Requires the confirmToken returned by the preview; if the live set has changed since the preview the token won't match and the request is rejected (409) so the admin re-reviews. Access logs are preserved.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/door-access/sync/{facilityId}/bulk-delete
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/sync/{facilityId}/bulk-delete \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Recent User Access sync activity (troubleshooting log)
Returns the most recent sync outcomes for a facility (created / skipped / disabled) with the reason, so admins can see why a member did or didn't sync. Newest first.
Parameters
facilityId `string` (required) limit `integer` (optional)Endpoint
GET /api/door-access/sync/{facilityId}/log
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/sync/{facilityId}/log \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List Door/Gate Access events for a facility
Returns mobile, admin override, and external Partner API unlock events in one reverse-chronological feed.
Parameters
facilityId `string` (required) from `integer` (optional) to `integer` (optional) limit `integer` (optional)Endpoint
GET /api/door-access/events/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/events/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Dry-run a geofence evaluation for the admin test-mode pin
Request Body
Endpoint
POST /api/door-access/geofence/test
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/door-access/geofence/test \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get the onboarding / activation status for a facility
Drives the applet's "Get Started" landing and setup-progress banner. Returns live door + user counts, the two derived core steps (a user exists, a door exists), the persisted optional "reviewed" flags, and whether the facility is activated (both core steps done). The first time a facility becomes activated the activatedAt timestamp is stamped.
Parameters
facilityId `string` (required)Endpoint
GET /api/door-access/onboarding/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/door-access/onboarding/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the optional onboarding "reviewed" flags for a facility
Persists the optional setup-checklist flags an admin ticks off (access rules, sync settings, geofencing). The core steps and activation are derived live from data counts and cannot be set here. Returns the full refreshed onboarding status.
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/door-access/onboarding/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/door-access/onboarding/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/lead-events
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/lead-events \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/page-views
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/page-views \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/referrers
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/referrers \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/socials
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/socials \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/top-cities
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/top-cities \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/total-page-views
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/total-page-views \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a JSON response of club analytics data.
Parameters
clubId `string` (optional) The club ID of the club to retrieve analytics data for. fromDate `string` (optional) The start date of the analytics data to retrieve. toDate `string` (optional) The end date of the analytics data to retrieve.Endpoint
GET /clubs/{clubId}/analytics/traffic
Example Request
curl -X GET https://portal.hub.gymsystems.co/clubs/{clubId}/analytics/traffic \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generates a temporary front-end JWT (Json Web Token) for Google Analytics embeddable charts in the front-end 'analytics' page.
Endpoint
GET /api/ga/onetimetoken
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ga/onetimetoken \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns dashboard widgets from 'The Training Camp' if the club has any active members.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/reporting/apps/widgets/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/apps/widgets/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all unreviewed club holidays.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/reporting/club/{club}/unreviewed-holidays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/club/{club}/unreviewed-holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Set all unreviewed club holidays to reviewed.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
PUT /api/reporting/club/{club}/review-holidays
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/reporting/club/{club}/review-holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the KPI Report in a CSV format, broken down in a month-by-month basis over the last 12 months. *NOTE* This creates a single report for ALL Clubs in the system - Do not run this multiple times in parallel or you will over-load GymMaster!
Parameters
months `string` (optional) Number of months (from current date) to fetch (defaults to 12)Endpoint
GET /api/reporting/gymmaster/all-clubs-kpi-report
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/gymmaster/all-clubs-kpi-report \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the MMS's revenue graph(s) for a given club.
Parameters
club `string` (required) Internal ID of the club that you wish to access. range `string` (optional) Range in days (counting back from the current date) that we wan to fetchEndpoint
GET /api/reporting/gymmaster/revenuegraph/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/gymmaster/revenuegraph/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the dashboard's MMS (Member Management System) data/analytics for a given club. Data includes GymMaster/Perfect Gym statistics as well as other internal metrics collected by our system.
Parameters
club `string` (required) Internal ID of the club that you wish to access. range `string` (optional) Range in days (counting back from the current date) that we wan to fetchEndpoint
GET /api/reporting/gymmaster/widgets/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/gymmaster/widgets/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the dashboard's Myzone widget data for a given club.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/reporting/myzone/widgets/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/myzone/widgets/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns an object of services which are deemed offline from one or more of our status page/monitoring endpoints - configured via internal 'Uptime Kuma' tool.
Endpoint
GET /api/reporting/statuspage/events
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/statuspage/events \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns upcoming workout bookings for the next 7 days.
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/reporting/clubs/{club}/workout-bookings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/reporting/clubs/{club}/workout-bookings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of historical club holidays for a club.
Parameters
clubId `string` (optional) Club ID fromDate `string` (optional) Unix timestamp of the start date of the range of holidays to return. toDate `string` (optional) Unix timestamp of the end date of the range of holidays to return.Endpoint
GET /api/clubs/{clubId}/historical-holidays
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubId}/historical-holidays \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns device automations associated with club.
Parameters
club `string` (required) Internal ID of the club that you wish to list devices from.Endpoint
GET /api/ics/automations/list/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/automations/list/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the device configuration for an existing display/device.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/ics/automations/update/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/automations/update/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add a new data source for the screen display UI.
Parameters
name `string` (required) Name of the data source type `string` (required) Data source type langShort `string` (required) Short language name lang `string` (optional) Language code data `string` (optional) JSON string of data for static typesEndpoint
POST /api/ics/data-sources
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/data-sources \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List data sources for the screen display UI.
Endpoint
GET /api/ics/data-sources
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/data-sources \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update data source for the screen display UI.
Parameters
id `string` (required) Unique identifier of the data source generated upon creation name `string` (optional) Name of the data source type `string` (optional) Data source type langShort `string` (optional) Short language name lang `string` (optional) Language code data `string` (optional) JSON string of data for static typesEndpoint
PUT /api/ics/data-sources
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ics/data-sources \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/associates a physical screen device/computer with your club.
Parameters
club `string` (required) Internal ID of the club that you wish to add the device under. body `string` (required) Json Object of the new screen to associate with.Endpoint
POST /api/ics/devices/add/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/devices/add/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Instructs device to connect to new SSID based on parameters.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/ics/devices/changewifi/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/devices/changewifi/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the device configuration for an existing display/device.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/ics/devices/command/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/devices/command/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Loads a URL/webpage on a specific device screen.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
POST /api/ics/devices/loadurl/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/devices/loadurl/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the device configuration for an existing display/device.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) Json Object of the update parameters.Endpoint
PUT /api/ics/devices/update/{club}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ics/devices/update/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Renames a display/device. Registration-only - unlike the update endpoint this pushes nothing to the device, so it is also available for screens running an end-of-life software build.
Parameters
club `string` (required) Internal ID of the club the device belongs to. body `string` (required) Json Object of the rename parameters.Endpoint
PUT /api/ics/devices/rename/{club}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ics/devices/rename/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets widgets and links to off-line media for a club, based on the supplied date.
Parameters
club `string` (required) Internal ID of the club that you wish to change the workout program to. date `string` (required) Date to return widget URLs - Use `YYYY-MM-DD` format.Endpoint
GET /api/ics/external-resources/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/external-resources/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets widgets and links to off-line media for a club, based on the supplied date.
Parameters
club `string` (required) Internal ID of the club that you wish to change the workout program to.Endpoint
GET /api/ics/list-scheduled-workouts/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/list-scheduled-workouts/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Changes the workout program for a given club.
Parameters
club `string` (required) Internal ID of the club that you wish to change the workout program to. body `string` (required) Json Object of the new workout to change.Endpoint
POST /api/ics/loadprogram/{club}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/loadprogram/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieves the program configuration for an existing display/device.
Parameters
club `string` (required) Internal ID of the club that you wish to retrieve program data of.Endpoint
GET /api/ics/programs/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/programs/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the program configuration for an existing display/device.
Parameters
club `string` (required) Internal ID of the club that you wish to update the device. body `string` (required) JSON Object of the update parameters.Endpoint
PUT /api/ics/programs/{club}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ics/programs/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieves the program configuration options.
Endpoint
GET /api/ics/programs/options/{facilityID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/programs/options/{facilityID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add a new UI option for the screen displays.
Parameters
name `string` (required) Name of the UI Option description `string` (required) Short description about this UI url `string` (required) Base URL of the UIEndpoint
POST /api/ics/ui-options
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ics/ui-options \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List UI options for the screen displays.
Endpoint
GET /api/ics/ui-options
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ics/ui-options \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update UI option for the screen displays.
Parameters
id `string` (required) Unique identifier of the data source generated upon creation name `string` (optional) Name of the UI Option description `string` (optional) Short description about this UI url `string` (optional) Base URL of the UIEndpoint
PUT /api/ics/ui-options
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/ics/ui-options \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Queue wiki articles for embedding by synchronising embedding track entries
Request Body
Endpoint
POST /api/llm/articles/queue-sync
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/articles/queue-sync \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Chat with RAG context - This does not have access to tools - only a simple API request|response tool that lets you directly pull knowledge from the knowledge base.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Request Body
Endpoint
POST /api/llm/chat
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/chat \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete article embeddings from vector store and update embedding track status
Request Body
Endpoint
DELETE /api/llm/delete-article
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/llm/delete-article \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List embedding tracker records by organisation and status
Parameters
organisationId `string` (optional) Organisation ID (auto-resolved if omitted) status `string` (required) Status to filter by (must be one of in_queue, done, anomaly, fail, deleted) Limit `string` (optional) Max items per page LastEvaluatedKey `string` (optional) JSON of DynamoDB LastEvaluatedKey for paginationEndpoint
GET /api/llm/embedding-track/by-org-and-status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/embedding-track/by-org-and-status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List embedding tracker records by organisation (optionally filter by resource type)
Parameters
organisationId `string` (optional) Organisation ID (auto-resolved if omitted) resourceType `string` (optional) Optional resource type (e.g., "article"). When provided, filters where resourceTypeId begins with "{type}#". Limit `string` (optional) Max items per page LastEvaluatedKey `string` (optional) JSON of DynamoDB LastEvaluatedKey for paginationEndpoint
GET /api/llm/embedding-track/by-org
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/embedding-track/by-org \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initialize organization vector database collection
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Endpoint
POST /api/llm/init-org
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/init-org \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Trigger reindex of knowledge base
Fetches all published wiki articles for the organisation and generates/updates embeddings in the vector store. This process can take several minutes depending on the number of articles.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Request Body
Endpoint
POST /api/llm/reindex
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/reindex \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Semantic search in knowledge base
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Request Body
Endpoint
POST /api/llm/semantic-search
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/semantic-search \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Start streaming processing of queued articles for embedding with real-time progress updates
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Endpoint
POST /api/llm/start-embedding-stream
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/start-embedding-stream \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upsert article embeddings into vector database
Handles article embedding based on current state: - If article is unpublished OR private: deletes embeddings - If article is published AND public: re-embeds with full content Always requires full article body.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Request Body
Endpoint
POST /api/llm/upsert-embeddings
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/upsert-embeddings \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Test endpoint to batch delete article embeddings by organization and optional status
Parameters
organisationId `string` (optional) Organisation ID (auto-resolved from user context if omitted) status `string` (optional) Status to filter by (optional - if omitted, deletes ALL articles for the organization regardless of status) hardDelete `string` (optional) Whether to hard delete embedding track records (true) or soft delete by updating status (false)Endpoint
DELETE /api/llm/test/batch-delete-by-status
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/llm/test/batch-delete-by-status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Transform and chunk text with detailed statistics
Test endpoint that transforms text and chunks it, then provides detailed statistics about chunk distribution including character counts, percentages, and quality metrics to help evaluate chunking effectiveness.
Request Body
Endpoint
POST /api/llm/test/transform-chunk
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/test/transform-chunk \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get total count of vectors in vector index for organization
Test endpoint to count all vectors in the vector index for the current user's organization
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Endpoint
GET /api/llm/test/vector-count
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/test/vector-count \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete all vectors for a specific articleId from vector index
Test endpoint to delete all vectors associated with a specific articleId from the vector index for the current user's organization.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided) articleId `string` (required) The articleId to delete vectors for dryRun `string` (optional) If true, only shows what would be deleted without actually deletingEndpoint
DELETE /api/llm/test/vector-delete-article
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/llm/test/vector-delete-article \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Test Vector SDK by listing all indexes
Test endpoint to verify Vector SDK connectivity and list all indexes in the vector bucket
Endpoint
GET /api/llm/test/vector-indices
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/test/vector-indices \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initialize Vector index for an organization
Creates the Vector bucket and index for the current user's organization
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided)Endpoint
POST /api/llm/test/vector-init-index
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/llm/test/vector-init-index \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get all vector metadata for a specific articleId
Test endpoint to retrieve all vector chunks and their metadata for a specific articleId from the vector index. Useful for inspecting how an article is chunked and stored. Filtering is handled by the vector store service.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided) articleId `string` (required) The article ID to retrieve vector metadata forEndpoint
GET /api/llm/test/vector-metadata-by-article
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/test/vector-metadata-by-article \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get recent vectors with metadata from vector index
Test endpoint to retrieve the 10 most recent vectors with metadata (but without vector data) from the vector index for the current user's organization. Useful for inspecting metadata structure.
Parameters
organisationId `string` (optional) The organisation ID (will be auto-detected if not provided) limit `string` (optional) Number of recent vectors to return (max 100)Endpoint
GET /api/llm/test/vector-recent
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/llm/test/vector-recent \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Uploads an asset for the Marketing Manager/Designer to S3 Storage.
Parameters
file `string` (optional) Name of the file/asset to be uploaded.Endpoint
POST /api/marketing/design/static/download
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/marketing/design/static/download \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the individual assets JSON format to be loaded into the asset manager.
Parameters
id `string` (required) ID of the asset to get. organisationId `string` (required) The organisation ID of the facility that the asset belongs to.Endpoint
GET /api/marketing/assets/get/{id}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/assets/get/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retuns all design assets.
Parameters
body `string` (required) Json Object of club data that you wish to save. organisationId `string` (required) The organisation ID of the facility that the asset belongs to. useCache `string` (optional) search `string` (optional) The search query to filter assets by name or tags. brand `string` (optional) The brand to filter assets by. tag `string` (optional) The tag to filter assets by.Endpoint
GET /api/marketing/assets/get
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/assets/get \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a single page of marketing print assets for an organisation. Uses Algolia for relevance search + page-based pagination (with total counts), and falls back to DynamoDB when Algolia is unavailable.
Parameters
organisationId `string` (required) The organisation ID of the facility that the assets belong to. search `string` (optional) The search query to filter assets by name or tags. brand `string` (optional) The brand to filter assets by. tag `string` (optional) The tag to filter assets by. page `string` (optional) Zero-indexed page number to fetch. limit `string` (optional) Number of assets per page (max 300). useCache `string` (optional) When false, bypasses Algolia and queries DynamoDB directly.Endpoint
GET /api/marketing/assets
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/assets \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of available assets that have been uploaded via the asset manager.
Parameters
organisationId `string` (required)Endpoint
GET /api/marketing/assets/list
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/assets/list \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Saves an asset.
Parameters
body `string` (required) Json Object of club data that you wish to save. organisationId `string` (required) The organisation ID of the facility that the asset belongs to.Endpoint
PUT /api/marketing/assets/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/marketing/assets/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Uploads an asset for the Marketing Manager/Designer to S3 Storage.
Parameters
file `string` (optional) Name of the file/asset to be uploaded. organisationId `string` (optional) The ID of the organisation the asset belongs to.Endpoint
POST /api/marketing/assets/upload
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/marketing/assets/upload \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of all custom pages for an organisation.
Parameters
organisationId `string` (required) Internal ID of the organisation to return custom pages for.Endpoint
GET /api/marketing/custom-pages
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/custom-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Upserts a custom page for an organisation.
Parameters
organisationId `string` (required) Internal ID of the organisation to return custom pages for. body `object` (required) Custom page data to upsert.Endpoint
PUT /api/marketing/custom-pages
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/marketing/custom-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of all custom pages for a facility.
Parameters
facilityId `string` (required) Internal ID of the facility to return custom pages for.Endpoint
GET /api/facilities/{facilityId}/marketing/custom-pages
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/facilities/{facilityId}/marketing/custom-pages \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all exported/rendered designs for a specific club id.
Parameters
club `string` (required) Internal ID of the club that is making the request. sort `string` (optional) Filter to sort designs by, 'oldest', 'newest', or 'design' supported.Endpoint
GET /api/marketing/designs/{club}/exports
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/{club}/exports \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the individual HTML contents for a design in JSON format to be loaded into the editor.
Parameters
id `string` (required) ID of the design to get.Endpoint
GET /api/marketing/designs/get/{id}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/get/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of input mapping in marketing and print designs and design templates
Parameters
clubId `string` (required) Internal ID of the club that is making the request. availableFeatures `string` (optional) Return all items with specific features brand `string` (optional) Filters designs by brand features `string` (optional) Filter results based on featuresEndpoint
GET /api/marketing/designs/input-mapping/{clubId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/input-mapping/{clubId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of available designs for a given club, that may be used within designs (Print Designs) created within the hub's marketing/print editor.
Parameters
club `string` (required) Internal ID of the club that is making the request. designAdmin `string` (optional) Return all design data (admin view / requires user to be administrator). brand `string` (optional) Filters designs by brandEndpoint
GET /api/marketing/designs/{club}/list
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/{club}/list \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Forces the system to render/re-render all design thumbnails & previews (Used mainly if we change 'upstream' assets in S3 etc)... **NOTE** You can only call this function once per X minutes (or if a render is already-running you can't call this function). This is to ensure that we don't put excess load on our servers rendering all designs...
Endpoint
GET /api/marketing/designs/render-all-thumbnails
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/render-all-thumbnails \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Initiates render of a Dynamic Design
Parameters
body `string` (required) Json Object of club data you wish to send to the design render processor...Endpoint
POST /api/marketing/designs/dynamic/render-design
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/marketing/designs/dynamic/render-design \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Saves/Updates a design.
Parameters
body `string` (required) Json Object of club data that you wish to save.Endpoint
PUT /api/marketing/designs/{club}/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/marketing/designs/{club}/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the individual static design JSON format to be loaded
Parameters
id `string` (required) ID of the static design to get.Endpoint
GET /api/marketing/designs/static/get/{id}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/designs/static/get/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Saves/Updates an static design template.
Parameters
body `string` (required) Json Object of club data that you wish to save.Endpoint
PUT /api/marketing/designs/static/{club}/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/marketing/designs/static/{club}/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Removes a user set variable from the system.
Parameters
club `string` (required) Internal ID of the club that is making the request. body `string` (required) Json containing the variable ID to remove.Endpoint
DELETE /api/marketing/variables/{club}/delete
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/marketing/variables/{club}/delete \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of available variables for a given club, that may be used within designs (Print Designs) created within the hub's marketing/print editor.
Parameters
club `string` (required) Internal ID of the club that is making the request.Endpoint
GET /api/marketing/variables/{club}/list
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/marketing/variables/{club}/list \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a single new user based 'variable' for the given club.
Parameters
club `string` (required) Internal ID of the club that is making the request. body `string` (required) Json Object of the new variable.Endpoint
POST /api/marketing/variables/{club}/new
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/marketing/variables/{club}/new \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Adds/Saves/Updates one or more design variables in the system via an array of objects.
Parameters
club `string` (required) Internal ID of the club that is making the request. body `string` (required) Array of One or more Json Object's to be added/updated (This allows for saving of multiple items/objects in one API request).Endpoint
PUT /api/marketing/variables/{club}/save
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/marketing/variables/{club}/save \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the MCP documentation manifest for the signed-in user
Powers the in-app `/mcp-docs` page. Returns the MCP server URL, the supported auth headers, the caller's identity/admin flag, and the filtered tool list (filtered identically to `/mcp/tools/list`, so the docs page never shows a tool the caller cannot actually use).
Endpoint
GET /api/mcp/docs-manifest
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/mcp/docs-manifest \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create user agreement.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
POST /api/member-agreements/contracts-tna/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/member-agreements/contracts-tna/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of agreement.
Endpoint
GET /api/member-agreements/contracts-tna/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/member-agreements/contracts-tna/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete user agreement.
Endpoint
DELETE /api/member-agreements/contracts-tna/:club/:id
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/member-agreements/contracts-tna/:club/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns specific of agreement.
Endpoint
GET /api/member-agreements/contracts-tna/:club/:id
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/member-agreements/contracts-tna/:club/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update user agreement.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
PATCH /api/member-agreements/contracts-tna/:club/:id
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/member-agreements/contracts-tna/:club/:id \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get default agreeents of the club.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
GET /api/member-agreements/default-tna/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/member-agreements/default-tna/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Set default agreeent of the club.
Parameters
body `object` (required) Json Object of club data that you wish to save.Endpoint
POST /api/member-agreements/default-tna/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/member-agreements/default-tna/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of global or region agreement.
Endpoint
GET /api/member-agreements/global-tna/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/member-agreements/global-tna/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of members with agreement.
Endpoint
GET /api/member-agreements/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/member-agreements/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all members, combined from all GymMaster API Endpoints configured in the system.
Parameters
export `string` (optional) Return/Export results as a CSV File for import to other systems. trainingcamp `string` (optional) Choses to export the data from the DB "as is", or in a format that can be imported into MailChimp for "The Training Camp". status `string` (optional) Allows to filter members by a specific status - ie "Expired", "Current" etc draw `string` (optional) Enable/disable Datatables Response Pagination by specifying the Draw search `string` (optional) Search Database for specific querystring... length `integer` (optional) Number of items to return when using Datatables pagination ExclusiveStartKey `string` (optional) The "start" key/index (should be an object) to start returning data from (in the database) when paging through multiple pages...Endpoint
GET /api/members-leads/gymmaster/all/members
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/gymmaster/all/members \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of ALL train at home registrations from the mobile v1 app.
Parameters
export `string` (optional) Return/Export results as a CSV File for import to other systems. draw `string` (optional) Enable/disable Datatables Response Pagination by specifying the Draw search `string` (optional) Search Database for specific querystring... length `integer` (optional) Number of items to return when using Datatables pagination ExclusiveStartKey `string` (optional) The "start" key/index (should be an object) to start returning data from (in the database) when paging through multiple pages...Endpoint
GET /api/members-leads/train-at-home/all/users
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/train-at-home/all/users \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of ALL Training Camp App members (For Hub admin Tools)
Parameters
export `string` (optional) Return/Export results as a CSV File for import to other systems. trainingcamp `string` (optional) Choses to export the data from the DB "as is", or in a format that can be imported into MailChimp for "The Training Camp". draw `string` (optional) Enable/disable Datatables Response Pagination by specifying the Draw search `string` (optional) Search Database for specific querystring... length `integer` (optional) Number of items to return when using Datatables pagination ExclusiveStartKey `string` (optional) The "start" key/index (should be an object) to start returning data from (in the database) when paging through multiple pages...Endpoint
GET /api/members-leads/trainingcamp/all/app-members
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/trainingcamp/all/app-members \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of ALL Training Camp leads from the 12RND/UBX Websites (For Hub admin Tools)
Parameters
export `string` (optional) Return/Export results as a CSV File for import to other systems. trainingcamp `string` (optional) Choses to export the data from the DB "as is", or in a format that can be imported into MailChimp for "The Training Camp". draw `string` (optional) Enable/disable Datatables Response Pagination by specifying the Draw search `string` (optional) Search Database for specific querystring... length `integer` (optional) Number of items to return when using Datatables pagination ExclusiveStartKey `string` (optional) The "start" key/index (should be an object) to start returning data from (in the database) when paging through multiple pages...Endpoint
GET /api/members-leads/trainingcamp/all/leads
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/trainingcamp/all/leads \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of club members by season for the training camp's app.
Parameters
club `string` (required) Internal ID of the club that you wish to access. season `string` (optional) Season of the training camp that you wish to filter. userIds `string` (optional) Array of user ids to filter. useCache `string` (optional) Whether to use the cache. isUserMemberInfo `string` (optional) If enabled, it will filter the data based on userIds (recommended to use only one user id) and include necessary data such as leaderboard and user preferences.Endpoint
GET /api/members-leads/trainingcamp/club/season-members/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/trainingcamp/club/season-members/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of ALL Training Camp leads from the 12RND/UBX Websites (For Hub admin Tools)
Parameters
export `string` (optional) Return/Export results as a CSV File for import to other systems. draw `string` (optional) Enable/disable Datatables Response Pagination by specifying the Draw search `string` (optional) Search Database for specific querystring... length `integer` (optional) Number of items to return when using Datatables pagination ExclusiveStartKey `string` (optional) The "start" key/index (should be an object) to start returning data from (in the database) when paging through multiple pages...Endpoint
GET /api/members-leads/website/all/leads
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/website/all/leads \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deletes multiple workout booking leads.
Parameters
club `string` (required) Internal ID of the club that you wish to access. body `string` (required)Endpoint
DELETE /api/members-leads/workout-booking/club/leads/{club}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/members-leads/workout-booking/club/leads/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of a club's workout booking leads.
Parameters
club `string` (required) Internal ID of the club that you wish to access. all `string` (optional) To show all the leads or just the upcoming ones.Endpoint
GET /api/members-leads/workout-booking/club/leads/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/members-leads/workout-booking/club/leads/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a workout booking lead.
Parameters
club `string` (required) Internal ID of the club that you wish to access. body `string` (required)Endpoint
PUT /api/members-leads/workout-booking/club/leads/{club}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/members-leads/workout-booking/club/leads/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Toggles the flagged state of a workout booking lead.
Parameters
club `string` (required) Internal ID of the club. body `string` (required)Endpoint
PATCH /api/members-leads/workout-booking/club/leads/{club}/flag
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/members-leads/workout-booking/club/leads/{club}/flag \
-H "x-api-key: YOUR_API_KEY"
Response
{}
get notification categories.
Endpoint
GET /api/notification/categories
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/notification/categories \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete notification consumed.
Endpoint
DELETE /api/club/notification/consumed/:club
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/club/notification/consumed/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
creates notification message.
Endpoint
POST /api/club/notification/consumed/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/club/notification/consumed/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns array of notification consumed.
Endpoint
GET /api/club/notification/consumed/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/notification/consumed/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete notification message.
Endpoint
DELETE /api/club/notification/messages/:club
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/club/notification/messages/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns array of notification messages.
Endpoint
GET /api/club/notification/messages/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/notification/messages/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
updates notification message.
Endpoint
PATCH /api/club/notification/messages/:club
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/club/notification/messages/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
creates notification message.
Parameters
body `string` (required)Endpoint
POST /api/club/notification/messages/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/club/notification/messages/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
get the viewers of notification by club.
Endpoint
POST /api/club/notification/viewers/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/club/notification/viewers/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
get notification categories by user.
Endpoint
GET /api/club/notification/user-categories/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/club/notification/user-categories/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
creates notification message.
Endpoint
POST /api/notification/webhook
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/notification/webhook \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get VAPID public key for HTML5 push
Returns the VAPID public key used to create browser push subscriptions.
Endpoint
GET /html5-push/vapid-public-key
Example Request
curl -X GET https://portal.hub.gymsystems.co/html5-push/vapid-public-key \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Save or update a HTML5 push subscription
Persists a browser push subscription for the current user.
Request Body
Endpoint
POST /html5-push/subscribe
Example Request
curl -X POST https://portal.hub.gymsystems.co/html5-push/subscribe \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete a HTML5 push subscription
Removes a browser push subscription for the current user.
Request Body
Endpoint
POST /html5-push/unsubscribe
Example Request
curl -X POST https://portal.hub.gymsystems.co/html5-push/unsubscribe \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get the location onboarding status for the calling user
Returns the two onboarding portions for a facility — setup (details + product selections, stored on club preferences) and payment (derived live from the SaaS billing payment-settings record) — plus a caller personalised `required` flag the app shell gates on. Technology-stack locations only; business-stack locations always return required=false. Global admins are never gated.
Parameters
facilityId `string` (required)Endpoint
GET /api/onboarding/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/onboarding/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Save in-flight onboarding wizard progress for a facility
Persists partial wizard state (product selections, "Other" free text, reviewed business details, current step) so refresh/abandon resumes where the user left off. Never stamps completion — see the complete endpoint.
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/onboarding/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/onboarding/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Generate AI prefill suggestions for the onboarding wizard
Uses the existing club/brand/organisation context to propose facility details (about copy, tidied contact fields), suggested product selections, and short personalised tips. Results are cached in Redis for 7 days. Suggestions are advisory only — the client renders them into an editable review form. Always responds 200; `suggestions` is null when AI is unavailable so the wizard degrades gracefully.
Parameters
facilityId `string` (required)Endpoint
POST /api/onboarding/{facilityId}/ai-prefill
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/onboarding/{facilityId}/ai-prefill \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Complete the setup portion of location onboarding
Validates the confirmed selections/details, persists the business details to the club record, seeds the facility tech-menu layout from the product selections (unless a customised layout already exists), and stamps setup completion. The payment portion is intentionally NOT completable here — it is derived live from the SaaS billing payment-settings record, so the mandatory card requirement cannot be bypassed by calling this endpoint. Returns the refreshed status.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/onboarding/{facilityId}/complete
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/onboarding/{facilityId}/complete \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Trigger a declared partner integration action for a facility
Runs a "Run integration" action declared on the partner record (ph-partners.actions[]), scoped to a facility. A Redis single-flight lock prevents concurrent manual runs for the same action+facility.
Parameters
partnerId `string` (required) actionId `string` (required)Request Body
Endpoint
POST /api/partners/{partnerId}/actions/{actionId}/run
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/{partnerId}/actions/{actionId}/run \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Read the run status of a partner integration action
Returns whether a manual run is currently in flight (single-flight lock held) plus the last requested run, for the settings button to poll.
Parameters
partnerId `string` (required) actionId `string` (required) facilityId `string` (required)Endpoint
GET /api/partners/{partnerId}/actions/{actionId}/status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/{partnerId}/actions/{actionId}/status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add a new partner.
Parameters
name `string` (required) Name of the partner description `string` (optional) Short description of the partner details `string` (optional) Detailed information about the partner logoUrl `string` (optional) URL to the partner's logo image website `string` (optional) Partner's website URL category `string` (optional) Categories the partner belongs to allowedOrganisations `string` (optional) Array of organisation IDs that this partner is restricted to. Omit or pass empty array for no restriction. facilityConfigHtmlEmbed `string` (optional) Optional HTML snippet shared with facilities. Maximum size is 150 KB to respect DynamoDB item limits.Endpoint
POST /api/partners
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all partners.
Endpoint
GET /api/partners
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a partner.
Parameters
partnerId `string` (required) ID of the partner name `string` (optional) Name of the partner description `string` (optional) Short description of the partner details `string` (optional) Detailed information about the partner logoUrl `string` (optional) URL to the partner's logo image website `string` (optional) Partner's website URL category `string` (optional) Categories the partner belongs to. Pass empty array to remove categories. allowedOrganisations `string` (optional) Array of organisation IDs that this partner is restricted to. Pass empty array to remove restriction. facilityConfigHtmlEmbed `string` (optional) Optional HTML snippet shared with facilities. Maximum size is 150 KB to respect DynamoDB item limits.Endpoint
PUT /api/partners
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/partners \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get all partner configurations for a brand
Parameters
brandId `string` (required) The brand IDEndpoint
GET /api/partners/brand-config/{brandId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/brand-config/{brandId} \
-H "x-api-key: YOUR_API_KEY"
Response
[]
Create or update a brand partner configuration
Parameters
body `object` (required)Endpoint
PUT /api/partners/brand-config
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/partners/brand-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a partner.
Parameters
partnerId `string` (required) ID of the partnerEndpoint
DELETE /api/partners/{partnerId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/partners/{partnerId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Generate an admin token for accessing partner console
Parameters
partnerId `string` (required) ID of the partnerEndpoint
POST /api/partners/generate-admin-token
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/generate-admin-token \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Migrate GymMaster integration data to facility-partner-config
Queries all clubs with gymMasterAPI and gymMasterDomain fields and creates/updates corresponding facility-partner-config records. This is a one-time migration endpoint.
Parameters
partnerId `string` (required) The GymMaster partner ID to use for all migrated records dryRun `boolean` (optional) If true, only reports what would be migrated without writing to databaseEndpoint
GET /api/partners/migrate-gymmaster
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/migrate-gymmaster \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable a partner for an organisation.
Parameters
partnerId `string` (required) ID of the partnerEndpoint
POST /api/partners/organisation/enable
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/organisation/enable \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List organisation partners. Global admins see all, organisation admins see only their organisation's partners.
Endpoint
GET /api/partners/organisation
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/organisation \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Remove an organisation partner.
Parameters
keyId `string` (required) Key ID of the organisation partner organisationId `string` (required) Organisation ID of the partnerEndpoint
DELETE /api/partners/organisation/{keyId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/partners/organisation/{keyId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update organisation partner access mode and modules.
Parameters
keyId `string` (required) Key ID of the organisation partner organisationId `string` (required) Organisation ID of the partner partnerId `string` (required) Partner ID accessMode `string` (required) Access mode for the partner modules `string` (optional) List of modules for LIMITED access modeEndpoint
PUT /api/partners/organisation/update-access
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/partners/organisation/update-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Send welcome email to a partner
Parameters
partnerId `string` (required) ID of the partnerEndpoint
POST /api/partners/send-welcome-email
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/send-welcome-email \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create check-ins for a facility
Accepts an array of check-in objects and forwards them to the Partner API for processing. Maximum of 25 check-ins per request.
Request Body
Endpoint
POST /api/partners/check-ins
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/check-ins \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete a partner configuration for a facility
Removes the configuration for a partner integration at a facility
Parameters
facilityId `string` (required) Facility ID (club ID) partnerId `string` (required) Partner IDEndpoint
DELETE /api/partners/facility-config/{facilityId}/{partnerId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/partners/facility-config/{facilityId}/{partnerId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List all partner configurations for a facility
Returns all partner integrations configured for the given facility
Parameters
facilityId `string` (required) Facility ID (club ID)Endpoint
GET /api/partners/facility-config/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/facility-config/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create or update a partner configuration for a facility
Upserts the configuration for a partner integration at a facility
Request Body
Endpoint
POST /api/partners/facility-config
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/facility-config \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete a member by memberId
Deletes an existing member record using the memberId.
Parameters
memberId `string` (required) Unique identifier for the memberEndpoint
DELETE /api/partners/members/{memberId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/partners/members/{memberId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a member by memberId
Updates an existing member record using the memberId.
Parameters
memberId `string` (required) Unique identifier for the memberRequest Body
Endpoint
PUT /api/partners/members/{memberId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/partners/members/{memberId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Get the status of a member-sync operation
Returns the current state of an asynchronous member create/delete operation that was started via POST /api/partners/members or DELETE /api/partners/members/{memberId}. The frontend polls this endpoint to replace the legacy list-polling + name-matching flow. NOTE Row-level partnerId/facilityId scoping is mandated by the multi-tenant isolation rules but deferred to a Phase 3a.1 hardening PR — operationIds are 128-bit UUIDs and the route is already gated by `external-integrations` module access. Anyone with a valid operationId and admin module access can query its status.
Parameters
operationId `string` (required) UUID returned from POST/DELETEEndpoint
GET /api/partners/members/operations/{operationId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/partners/members/operations/{operationId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create or update members for a facility
Accepts an array of member objects and forwards them to the Partner API for processing. Maximum of 25 members per request.
Request Body
Endpoint
POST /api/partners/members
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/members \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Create or update membership plans for a facility
Accepts an array of membership plan objects and forwards them to the Partner API for processing. Maximum of 25 membership plans per request.
Request Body
Endpoint
POST /api/partners/membership-plans
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/partners/membership-plans \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Creates a new role
Parameters
body `string` (required) Role objectEndpoint
POST /api/roles
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/roles \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all roles
Endpoint
GET /api/roles
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/roles \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deletes an role by ID
Endpoint
DELETE /api/roles/{roleId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/roles/{roleId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates an role by ID
Parameters
body `string` (required) Role objectEndpoint
PUT /api/roles/{roleId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/roles/{roleId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a new additional line item for the saas billing invoice
Parameters
organisationId `string` (optional) The organisation ID to create the additional line item for body `string` (optional) Body of the requestEndpoint
POST /api/saas-billing/additional-line-items
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/saas-billing/additional-line-items \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of additional line items for the saas billing invoice
Parameters
organisationId `string` (required) The organisation IDEndpoint
GET /api/saas-billing/additional-line-items
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/additional-line-items \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of additional line items for club's saas billing invoice
Endpoint
GET /api/clubs/{clubId}/saas-billing/additional-line-items
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubId}/saas-billing/additional-line-items \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates an additional line item for the saas billing invoice
Parameters
itemId `string` (required) The ID of the additional line item to update body `string` (required) The body of the requestEndpoint
PUT /api/saas-billing/additional-line-items/{itemId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/saas-billing/additional-line-items/{itemId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Combined Cloud Agent hourly rates for Your Rates
Returns offered Cloud Agent sizes with a single combined hourly price (hosting + software). The split is not included. usedPlans are SKUs this facility ran in the last 30 days.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/cloud-agent-rates
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/cloud-agent-rates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete imported monthly report
Parameters
club `string` (optional) Club ID reportId `string` (optional) Report IDEndpoint
DELETE /api/saas-billing/extended-access/monthly-usage-report/{reportId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/{reportId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the latest CCTV storage report for a club
Returns the most recent daily CCTV storage snapshot for the club from stored billing logs (up to the last 31 days). Includes totalStorage, date, and storage-related charges.
Parameters
club `string` (required) Club IDEndpoint
GET /api/saas-billing/extended-access/latest-cctv-storage-report/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/latest-cctv-storage-report/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a pdf invoice for the club for the given period.
Parameters
club `string` (optional) Club ID month `string` (optional) month of the report in number format. 1 = January, 2 = February etc. year `string` (optional) year of the report in number format. e.g. 2021Endpoint
GET /api/saas-billing/extended-access/monthly-usage-report/:club/invoice
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/:club/invoice \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bundle of platform invoice PDFs for the selected usage months, as a ZIP. Bulk counterpart of the single .../invoice endpoint — powers the multi-select download on the Billing & Cost Management applet's Invoices & Receipts tab.
Parameters
club `string` (optional) Club ID months `string` (optional) Comma-separated usage/report months in YYYY-MM format (max 24)Endpoint
GET /api/saas-billing/extended-access/monthly-usage-report/{club}/invoices.zip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/{club}/invoices.zip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns monthly usage reports for multiple usage months in one call. Powers the Cost History chart and month-over-month deltas in the Billing & Cost Management applet. Months with no usage yet return report: null (matching the single-month endpoint's 404 → $0 UI).
Parameters
club `string` (optional) Club ID months `string` (optional) Comma-separated usage months in YYYY-MM format (max 12)Endpoint
GET /api/saas-billing/extended-access/monthly-usage-report/{club}/batch
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/{club}/batch \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Import monthly reports for the club.
Parameters
club `string` (optional) Club IDEndpoint
PUT /api/saas-billing/extended-access/usage-report/:club
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/saas-billing/extended-access/usage-report/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a CSV report of the CCTV Usage for the last 30 days for all clubs.
Endpoint
GET /api/saas-billing/extended-access/usage-report/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/usage-report/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all the daily reports of the month for the club.
Parameters
club `string` (optional) Club ID month `string` (optional) month of the report in number format. 1 = January, 2 = February etc. year `string` (optional) year of the report in number format. e.g. 2021Endpoint
GET /api/saas-billing/extended-access/monthly-usage-report/{club}/daily-reports
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/{club}/daily-reports \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of imported monthly reports for the admin
Parameters
organisationId `string` (required) Organisation IDEndpoint
GET /api/saas-billing/extended-access/usage-report/imported
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/usage-report/imported \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a CSV report of the CCTV Usage for the last 30 days for all clubs.
Parameters
club `string` (optional) Club ID month `string` (optional) month of the report in number format. 1 = January, 2 = February etc. year `string` (optional) year of the report in number format. e.g. 2021Endpoint
GET /api/saas-billing/extended-access/monthly-usage-report/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/monthly-usage-report/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the periodical usage report for the club.
Parameters
club `string` (optional) Club ID periodStart `string` (optional) Start of the period in the format of YYYY-MM-DD periodEnd `string` (optional) End of the period in the format of YYYY-MM-DDEndpoint
GET /api/saas-billing/extended-access/periodical-usage-report/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/extended-access/periodical-usage-report/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bundle of billing-document PDFs as a single ZIP, mixing document types: platform invoices (by usage month), SaaS-wallet top-up receipts, and Model Router top-up receipts. Bulk counterpart of the per-type invoices.zip / receipts.zip endpoints for the consolidated Invoices & Receipts tab. Every requested month/id must resolve to a document the facility owns — any bad value fails the whole bundle.
Parameters
clubID `string` (required) invoiceMonths `string` (optional) Comma-separated usage months in YYYY-MM format walletIds `string` (optional) Comma-separated SaaS-wallet top-up transaction ids aiIds `string` (optional) Comma-separated Model Router top-up transaction idsEndpoint
GET /api/clubs/{clubID}/saas-billing/documents.zip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/documents.zip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add a note to a monthly record
Parameters
recordID `string` (optional) The ID of the record to get note `string` (optional) The note to add to the recordEndpoint
POST /api/saas-billing/monthly-records/{recordID}/notes
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/saas-billing/monthly-records/{recordID}/notes \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of saas billing monthly records
Parameters
club `string` (optional) The ID of the club to get month `string` (optional) The billing month in YYYY-MM formatEndpoint
GET /api/saas-billing/monthly-records/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/monthly-records/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of saas billing monthly records that have failed or require 3d secure
Parameters
clubID `string` (optional) The ID of the club to get the failed monthly records forEndpoint
GET /api/clubs/:clubID/saas-billing/flagged
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/:clubID/saas-billing/flagged \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns ALL saas billing monthly records (the invoice ledger) for a club, newest billing month first. Club-scoped counterpart of the admin-only paginate-monthly-records endpoint — powers the customer "Invoices & Receipts" tab in the Billing & Cost Management applet.
Parameters
clubID `string` (optional) The ID of the club to list the monthly records forEndpoint
GET /api/clubs/{clubID}/saas-billing/monthly-records
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/monthly-records \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of saas billing monthly records
Parameters
organisationId `string` (optional) Organisation ID month `string` (optional) Month in MM format. year `string` (optional) Year in YYYY format. filters `string` (optional) Datatable created query string filters. order `string` (optional) Datatable created query string.Endpoint
GET /api/saas-billing/monthly-records
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/monthly-records \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retry failed payments for a club
Parameters
clubID `string` (optional) The ID of the club to get the failed monthly records forEndpoint
PUT /api/clubs/:clubID/saas-billing/retry-failed-payments
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/:clubID/saas-billing/retry-failed-payments \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a monthly record
Parameters
recordID `string` (optional) The ID of the record to get status `string` (optional) The status to update the record toEndpoint
PUT /api/saas-billing/monthly-records/{recordID}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/saas-billing/monthly-records/{recordID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Checks if payments have succeeded and updates the status of the record
Parameters
clubID `string` (optional) recordID `string` (optional) The ID of the record to getEndpoint
PUT /api/clubs/{clubID}/saas-billing/monthly-records/{recordID}/validate
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/monthly-records/{recordID}/validate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add a payment method for a club.
Parameters
clubID `string` (optional)Endpoint
POST /api/clubs/{clubID}/saas-billing/payment-settings/payment-methods
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/payment-methods \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Syncs the payment methods for a club with Stripe.
Parameters
clubID `string` (optional)Endpoint
PUT /api/clubs/{clubID}/saas-billing/payment-settings/payment-methods
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/payment-methods \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns the facility's spend budget plus computed MTD/forecast.
Parameters
clubID `string` (optional)Endpoint
GET /api/clubs/{clubID}/saas-billing/budget
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/budget \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create/update/clear the facility spend budget.
Parameters
clubID `string` (optional) body `object` (optional)Endpoint
PUT /api/clubs/{clubID}/saas-billing/budget
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/budget \
-H "x-api-key: YOUR_API_KEY"
Delete a payment method from the club's payment settings.
Parameters
clubID `string` (optional) paymentMethodID `string` (optional)Endpoint
DELETE /api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{paymentMethodID}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{paymentMethodID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the payment settings for a club.
Parameters
clubID `string` (optional)Endpoint
GET /api/clubs/{clubID}/saas-billing/payment-settings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a club's payment settings.
Parameters
clubID `string` (optional) lockedOut `boolean` (optional) Whether the club will be locked out of the system. pauseBilling `boolean` (optional) Whether automatic billing for the club will be paused. customerID `string` (optional) Adding this will update the stripe customer ID for the club. deleteSourceID `string` (optional) Wether to delete the source customer from stripe.Endpoint
PUT /api/clubs/{clubID}/saas-billing/payment-settings
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the earliest billed month for all clubs.
Parameters
clubID `string` (optional)Endpoint
GET /api/saas-billing/payment-settings/earliest-billed-month
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/payment-settings/earliest-billed-month \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List the accounts that can clear a billing lockout for a club, tiered: users holding the billing module first, organisation admins only as a fallback when nobody does. Platform super admins are never returned.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/lockout-contacts
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/lockout-contacts \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Paginate through all clubs in the system and return the customer IDs for each club.
Parameters
clubID `string` (optional) organisationId `string` (optional) Organisation IDEndpoint
GET /api/saas-billing/payment-settings/customer-ids
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/payment-settings/customer-ids \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Set the primary payment method for a club.
Parameters
clubID `string` (optional)Endpoint
PUT /api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{paymentMethodID}/primary
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{paymentMethodID}/primary \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the billing profile for a club.
Parameters
clubID `string` (optional) invoiceEntity `string` (optional) billingContacts `string` (optional) List of uuids of kyc contacts ccEmails `string` (optional) List of emails to cc on invoicesEndpoint
PUT /api/clubs/{clubID}/saas-billing/payment-settings/billing-profile
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/billing-profile \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a payment method for a club.
Parameters
clubID `string` (optional) cardID `string` (optional)Endpoint
PUT /api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{cardID}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/payment-settings/payment-methods/{cardID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Soft-delete a rate block. Blocks derived from it are detached (they keep their current values).
Parameters
configId `string` (optional) The configId of the config to delete.Endpoint
DELETE /api/admin/saas-billing/charges-config/{configId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/saas-billing/charges-config/{configId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a per-facility breakdown of all applicable product charges and additional line items for CSV export. Resolves the global/region/facility override hierarchy for every facility the user has access to.
Parameters
organisationId `string` (required) Organisation ID for ACLEndpoint
GET /api/saas-billing/charges-config/export
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/charges-config/export \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns charges config of specific target
Parameters
clubId `string` (optional) The club ID of the club to get the charges config forEndpoint
GET /api/saas-billing/charges-config/{clubId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/saas-billing/charges-config/{clubId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns list of all charges config.
Parameters
organisationId `string` (required)Endpoint
GET /api/admin/saas-billing/charges-config
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/saas-billing/charges-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update charges config of an organisation
Parameters
organisationId `string` (optional) The organisation ID to update the charges config for body `object` (optional) Body of the requestEndpoint
PUT /api/admin/saas-billing/charges-config
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/saas-billing/charges-config \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Organisation billing summary for this facility's org — effective payer scope, any scheduled consolidation change, and whether the caller may manage the consolidation toggle (super-admin only for now — see the org-admin applet TODO in this file).
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/org/summary
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/org/summary \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable/disable consolidated billing for this facility's ORGANISATION. Platform super-admins only (moving to the org-admin applet — see the TODO in this file). The change is always scheduled for the next month boundary so wallets/statements never switch payer mid-month.
Parameters
clubID `string` (required) body `string` (optional) { enabled: boolean }Endpoint
PUT /api/clubs/{clubID}/saas-billing/org/consolidation
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/org/consolidation \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Consolidated organisation monthly records (statements) with the per-facility breakdown, newest first. Empty until the org's first consolidated month settles.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/org/monthly-records
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/org/monthly-records \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Prepaid wallet summary — balance, month-to-date usage debits, auto-top-up config, billing method.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/wallet
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Wallet ledger, newest first. Org-scoped wallets include all facilities' rows (each carries its originating clubID).
Parameters
clubID `string` (required) limit `string` (optional) types `string` (optional) comma-separated transaction types from `string` (optional) to `string` (optional) cursor `string` (optional) nextCursor from a previous pageEndpoint
GET /api/clubs/{clubID}/saas-billing/wallet/transactions
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/transactions \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Branded PDF receipt for a single wallet transaction (top-ups and credits).
Parameters
clubID `string` (required) txId `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/wallet/transactions/{txId}/receipt.pdf
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/transactions/{txId}/receipt.pdf \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Bundle of branded PDF receipts for the selected wallet top-up transactions, as a ZIP. Every id must be a top-up (card or invoice) belonging to this facility's wallet — usage debits and adjustments have no receipts and are rejected.
Parameters
clubID `string` (required) ids `string` (required) Comma-separated transaction ids (max 50)Endpoint
GET /api/clubs/{clubID}/saas-billing/wallet/transactions/receipts.zip
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/transactions/receipts.zip \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Charge a stored SaaS-billing card to add prepaid balance. Returns requires_action + clientSecret when 3DS is needed.
Parameters
clubID `string` (required) body `object` (optional)Endpoint
POST /api/clubs/{clubID}/saas-billing/wallet/topup
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/topup \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Finalise a wallet top-up after the applet completes 3DS authentication. Idempotent.
Parameters
clubID `string` (required)Endpoint
POST /api/clubs/{clubID}/saas-billing/wallet/topup/confirm
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/topup/confirm \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update the facility's auto-top-up rule (stored on its billing-profile override row).
Parameters
clubID `string` (required) body `object` (optional)Endpoint
PATCH /api/clubs/{clubID}/saas-billing/wallet/auto-topup
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/auto-topup \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Top-up invoices for this facility's wallet (invoice payment method), newest first.
Parameters
clubID `string` (required)Endpoint
GET /api/clubs/{clubID}/saas-billing/wallet/invoices
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/invoices \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Request a pay-by-reference top-up invoice (invoice payment method only). At most one pending invoice per wallet — a second request returns the existing one with alreadyPending=true.
Parameters
clubID `string` (required) body `string` (optional) { amountCents: number }Endpoint
POST /api/clubs/{clubID}/saas-billing/wallet/topup-invoice
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/clubs/{clubID}/saas-billing/wallet/topup-invoice \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deletes a secure upload record
Parameters
type `string` (required) key `string` (required) permanent `string` (optional)Endpoint
DELETE /api/admin/secure-upload/{type}/{key}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/secure-upload/{type}/{key} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns object information
Parameters
type `string` (required) key `string` (required)Endpoint
GET /api/admin/secure-upload/{type}/{key}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/{type}/{key} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a signed URL for uploading a file to S3
Parameters
fileName `string` (required) The name of the file to be uploaded including the extension public `string` (optional) Whether the file should be uploaded to the public bucketEndpoint
GET /api/admin/secure-upload/token
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/token \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of files uploaded using the old php uploader that now reside in S3
Endpoint
GET /api/admin/secure-upload/legacy-files
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/legacy-files \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of files uploaded to S3
Endpoint
GET /api/admin/secure-upload/files
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/files \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates/updates a secure upload record
Parameters
body `object` (required)Endpoint
POST /api/admin/secure-upload/files
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/secure-upload/files \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Proxy a file from S3
Parameters
type `string` (optional) The type of file to retrieve key `string` (optional) The key of the file to retrieveEndpoint
GET /api/admin/secure-upload/private/{type}/{key}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/private/{type}/{key} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Proxy a file from S3
Parameters
type `string` (optional) The type of file to retrieve key `string` (optional) The key of the file to retrieveEndpoint
GET /api/admin/secure-upload/public/{type}/{key}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/secure-upload/public/{type}/{key} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Converts pending videos and audio into small chunks and places them in S3
Endpoint
POST /api/admin/media-convert
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/admin/media-convert \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates the progress of a file conversions
Endpoint
PUT /api/admin/media-convert/progress
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/media-convert/progress \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of orders for the facility.
Parameters
facilityID `string` (optional)Endpoint
GET /api/store/facilities/:facilityID/orders
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/store/facilities/:facilityID/orders \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of products available to the club.
Parameters
clubID `string` (required) search `string` (optional) limit `string` (optional) page `string` (optional) The page number for pagination (starts at 1).Endpoint
GET /api/store/clubs/{clubID}/products
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/store/clubs/{clubID}/products \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates club info in expresscart store v2.
Parameters
clubID `string` (required)Endpoint
PUT /api/admin/store/clubs/{clubID}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/admin/store/clubs/{clubID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns all ticket history based on the Club ID
Parameters
club `string` (required) Internal ID of the club that you wish to access.Endpoint
GET /api/ticketing/clubtickets/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ticketing/clubtickets/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets the departments
Endpoint
GET /api/ticketing/departments
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ticketing/departments \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets the details of a single ticket
Parameters
user `string` (required) email of the user. ticketNumber `string` (required) 6-digit ID of the ticket you wish to access. club `string` (required) the selected club id.Endpoint
GET /api/ticketing/ticket-details/:ticketNumber/:club
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ticketing/ticket-details/:ticketNumber/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets the topics
Endpoint
GET /api/ticketing/topics
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ticketing/topics \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Gets all the tickets created by the current logged in user - Note this is set from the headers provided by our google SSO service.
Parameters
user `string` (required) Email of the user that is currently logged-inEndpoint
GET /api/ticketing/usertickets
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/ticketing/usertickets \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a new ticket
Parameters
club `string` (required) the selected club id.Endpoint
POST /api/ticketing/clubticket/:club
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ticketing/clubticket/:club \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a new ticket
Parameters
subject `string` (required) Subject of the ticket. message `string` (required) Full message of the ticket.Endpoint
POST /api/ticketing/userticket
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ticketing/userticket \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a reply to an existing ticket
Parameters
subject `string` (required) Subject of the ticket. message `string` (required) Full message of the ticket.Endpoint
POST /api/ticketing/user-reply
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/ticketing/user-reply \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Retrieves a user's preferences
Endpoint
GET /api/user-preferences
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/user-preferences \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates a user's preferences
Parameters
body `string` (required)Endpoint
PUT /api/user-preferences
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/user-preferences \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Change user password
Changes the user's password. Requires OTP verification if user has a phone number, or requires phone number to be added if not present.
Request Body
Endpoint
POST /api/user/change-password
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/change-password \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Check user's 2FA status
Returns whether 2FA is enabled for the user and if any of their roles force 2FA
Endpoint
GET /api/user/check-2fa-status
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/user/check-2fa-status \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List the organisations, facilities, and regions the user has access to for a specific module.
Parameters
moduleId `string` (required)Endpoint
POST /api/user/me/modules/{moduleId}/org-access
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/me/modules/{moduleId}/org-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Creates a 'Linking Request' from an end user, requesting to 'Join' a club.
Parameters
body `string` (required) Json Object of the new club to add to the system.Endpoint
POST /api/user/linkclub
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/linkclub \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Lists all clubs authorised to the user.
Endpoint
GET /api/user/listauthorised
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/user/listauthorised \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Send dual-channel OTP (email + SMS)
Sends OTP codes to both the user's email address and a specified phone number. Used for high-security operations like first-time phone number verification. This endpoint only sends OTPs and does not modify any user data.
Request Body
Endpoint
POST /api/user/send-dual-otp
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/send-dual-otp \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Send OTP to phone number or email
Sends an OTP code to the user's phone number (SMS) or email address for verification
Request Body
Endpoint
POST /api/user/send-otp
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/send-otp \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Check if user has valid sensitive page access
Returns whether the user has a valid OTP-verified session for accessing sensitive pages
Endpoint
GET /api/user/sensitive-page-access
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/user/sensitive-page-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Verify OTP and grant sensitive page access
Verifies the OTP code and grants 1-hour access to sensitive pages if valid
Request Body
Endpoint
POST /api/user/sensitive-page-access/verify
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/sensitive-page-access/verify \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Revoke sensitive page access (logout from sensitive pages)
Revokes the user's current sensitive page access session
Endpoint
POST /api/user/sensitive-page-access/revoke
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/sensitive-page-access/revoke \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable or disable 2FA
Enables or disables two-factor authentication for the user. Requires phone number and OTP verification.
Request Body
Endpoint
POST /api/user/toggle-2fa
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/user/toggle-2fa \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Update user's own profile
Allows a user to update their own profile information (first name, last name, phone number). When adding a phone number for the first time, dual-channel OTP verification is required (both email and SMS codes). When changing an existing phone number, only email OTP is required.
Request Body
Endpoint
PATCH /api/user/update-profile
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/user/update-profile \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Retrieve an icon based on the url.
Endpoint
GET /api/website-icon
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/website-icon \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List password vault entry templates
Parameters
organisationId `string` (optional) Organisation context for module access checksEndpoint
GET /api/vault/templates
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/vault/templates \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List visible password vault entries
Parameters
organisationId `string` (required) scope `string` (optional)Endpoint
GET /api/vault/entries
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/vault/entries \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a password vault entry
Endpoint
POST /api/vault/entries
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/vault/entries \
-H "x-api-key: YOUR_API_KEY"
Get a password vault entry without revealed secret values
Parameters
entryId `string` (required) organisationId `string` (required)Endpoint
GET /api/vault/entries/{entryId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/vault/entries/{entryId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Update a password vault entry
Endpoint
PUT /api/vault/entries/{entryId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/vault/entries/{entryId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a password vault entry
Endpoint
DELETE /api/vault/entries/{entryId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/vault/entries/{entryId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Reveal selected concealed or secret fields
Endpoint
POST /api/vault/entries/{entryId}/reveal
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/vault/entries/{entryId}/reveal \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List password vault folder summaries
Endpoint
GET /api/vault/folders
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/vault/folders \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List entries with authenticator codes
Endpoint
GET /api/vault/authenticator
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/vault/authenticator \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List registered workflow node types
Endpoint
GET /api/workflow-engine/node-types
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/node-types \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get the facility-hours projection used by workflow blocks
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/facility-hours/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/facility-hours/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Preview the facility-branded workflow email sender
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/email-branding/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/email-branding/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List workflow event trigger definitions (global admin)
Endpoint
GET /api/workflow-engine/trigger-catalog
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/trigger-catalog \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create or update a workflow event trigger definition (global admin)
Parameters
triggerType `string` (required)Endpoint
PUT /api/workflow-engine/trigger-catalog/{triggerType}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/workflow-engine/trigger-catalog/{triggerType} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Deactivate a workflow event trigger definition (global admin)
Parameters
triggerType `string` (required)Endpoint
DELETE /api/workflow-engine/trigger-catalog/{triggerType}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/workflow-engine/trigger-catalog/{triggerType} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List facility resources for trigger configuration
Parameters
facilityId `string` (required) resourceType `string` (required)Endpoint
GET /api/workflow-engine/resources/{facilityId}/{resourceType}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/resources/{facilityId}/{resourceType} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List workflows for a facility
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/workflows/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a draft workflow from a non-empty graph
The editor keeps a new workflow local until it has at least one block, so the first save creates it with its graph in one call. A body with no `nodes` is rejected rather than stored.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List credentials a facility's workflows may use
Returns the facility's own credentials plus any shared at its brand or organisation. Secrets are never returned; `hasValue` reports only that one is stored.
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/credentials/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/credentials/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a workflow credential
The scope level comes from `scopeType`; the brand and organisation ids are resolved from the facility rather than accepted from the caller.
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/credentials/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/credentials/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Facility-wide workflow settings (failure-notification recipients)
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/facility-settings/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/facility-settings/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Store facility-wide failure notifications recipients
Parameters
facilityId `string` (required)Request Body
Endpoint
PUT /api/workflow-engine/facility-settings/{facilityId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/workflow-engine/facility-settings/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Replace a workflow credential
An empty `secret` keeps the stored one, so a credential can be renamed without re-entering it. There is no way to read a secret back.
Parameters
facilityId `string` (required) credentialId `string` (required)Endpoint
PUT /api/workflow-engine/credentials/{facilityId}/{credentialId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/workflow-engine/credentials/{facilityId}/{credentialId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a workflow credential
Nodes referencing it fail closed on the next call, including in already published workflows, because a snapshot stores only the reference.
Parameters
facilityId `string` (required) credentialId `string` (required)Endpoint
DELETE /api/workflow-engine/credentials/{facilityId}/{credentialId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/workflow-engine/credentials/{facilityId}/{credentialId} \
-H "x-api-key: YOUR_API_KEY"
Get a workflow trigger's webhook URL
Parameters
facilityId `string` (required) workflowId `string` (required) nodeId `string` (required)Endpoint
GET /api/workflow-engine/workflows/{facilityId}/{workflowId}/nodes/{nodeId}/webhook
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/nodes/{nodeId}/webhook \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Rotate a workflow trigger's webhook URL
Immediately invalidates the previous URL.
Parameters
facilityId `string` (required) workflowId `string` (required) nodeId `string` (required)Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/nodes/{nodeId}/webhook/rotate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/nodes/{nodeId}/webhook/rotate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get a workflow by id
Parameters
facilityId `string` (required) workflowId `string` (required)Endpoint
GET /api/workflow-engine/workflows/{facilityId}/{workflowId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create or update a draft workflow
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
PUT /api/workflow-engine/workflows/{facilityId}/{workflowId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Update workflow name and/or description
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
PATCH /api/workflow-engine/workflows/{facilityId}/{workflowId}
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Delete a workflow and its versions
Parameters
facilityId `string` (required) workflowId `string` (required)Endpoint
DELETE /api/workflow-engine/workflows/{facilityId}/{workflowId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Duplicate a workflow into a new inactive draft
Parameters
facilityId `string` (required) workflowId `string` (required)Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/duplicate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/duplicate \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Publish the current draft (immutable version snapshot)
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/publish
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/publish \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Reset the draft to the last published version
Parameters
facilityId `string` (required) workflowId `string` (required)Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/discard
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/discard \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Enable or disable a workflow
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
PATCH /api/workflow-engine/workflows/{facilityId}/{workflowId}/active
Example Request
curl -X PATCH https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/active \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Generate or revise a workflow graph with AI
Parameters
facilityId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/generate/{facilityId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/generate/{facilityId} \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List models an Agent node can run on for this facility
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/agent-models/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/agent-models/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List MCP tools an Agent node may attach for this facility
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/agent-tools/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/agent-tools/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search this facility's persisted Agent conversations (Conversation key bindings)
Parameters
facilityId `string` (required) deviceId `string` (optional) Restrict to one Agent device's conversations (the node's configured deviceId) q `string` (optional) Case-insensitive substring match on the Conversation key, session id, or device name limit `integer` (optional) offset `integer` (optional)Endpoint
GET /api/workflow-engine/agent-conversations/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/agent-conversations/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search the conversations held on the facility's Agent device itself
Lists the device's own sessions (the Agent UI sidebar conversations) so a workflow can continue an existing conversation with its context. The device owns the history; when the facility has several devices, `deviceId` picks which one (the node's configured device). Unreachable device → 502.
Parameters
facilityId `string` (required) deviceId `string` (optional) The node's configured Agent device; omit to resolve the facility's single device q `string` (optional) Case-insensitive substring match on the session title or id limit `integer` (optional) offset `integer` (optional)Endpoint
GET /api/workflow-engine/agent-device-sessions/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/agent-device-sessions/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search the boards on the facility's Agent device kanban
Feeds the Agent: Kanban block's Board ID picker. Case-insensitive substring match on the board name or slug; `current` is the device's active board slug so the task picker can default its scope. When the facility has several devices, `deviceId` picks which one. Unreachable device → 502.
Parameters
facilityId `string` (required) deviceId `string` (optional) The node's configured Agent device; omit to resolve the facility's single device q `string` (optional) Case-insensitive substring match on the board name or slug limit `integer` (optional) offset `integer` (optional)Endpoint
GET /api/workflow-engine/kanban-boards/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/kanban-boards/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Search one board's tasks on the facility's Agent device kanban
Feeds the Agent: Kanban block's Task ID picker. Case-insensitive substring match on the task id, title, or body; tasks live per board (the device has no cross-board search), so `board` scopes the fetch — omit it for the device's active board. Unreachable device → 502.
Parameters
facilityId `string` (required) deviceId `string` (optional) The node's configured Agent device; omit to resolve the facility's single device board `string` (optional) The board slug to list; omit for the device's active board q `string` (optional) Case-insensitive substring match on the task id, title, or body limit `integer` (optional) offset `integer` (optional)Endpoint
GET /api/workflow-engine/kanban-tasks/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/kanban-tasks/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List curated workflow templates, filtered for this facility
Parameters
facilityId `string` (required)Endpoint
GET /api/workflow-engine/templates/{facilityId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/templates/{facilityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Instantiate a template into a graph fragment for the open draft
Parameters
facilityId `string` (required) templateId `string` (required)Endpoint
POST /api/workflow-engine/templates/{facilityId}/{templateId}
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/templates/{facilityId}/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Scope picker context for the template admin page (admin tiers)
Endpoint
GET /api/workflow-engine/template-admin/context
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/template-admin/context \
-H "x-api-key: YOUR_API_KEY"
Response
{}
List templates the caller may administer, with permission flags
Endpoint
GET /api/workflow-engine/template-admin
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/template-admin \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a template (admin tiers)
Request Body
Endpoint
POST /api/workflow-engine/template-admin
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/template-admin \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Template detail incl. graph, for the admin editor
Endpoint
GET /api/workflow-engine/template-admin/{templateId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/template-admin/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Replace a template (owner org or global admin)
Endpoint
PUT /api/workflow-engine/template-admin/{templateId}
Example Request
curl -X PUT https://portal.hub.gymsystems.co/api/workflow-engine/template-admin/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Soft-delete a template (owner org or global admin)
Endpoint
DELETE /api/workflow-engine/template-admin/{templateId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/workflow-engine/template-admin/{templateId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Duplicate a visible template into a target scope the caller may use
Request Body
Endpoint
POST /api/workflow-engine/template-admin/{templateId}/duplicate
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/template-admin/{templateId}/duplicate \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Run a workflow's published graph from a manual trigger
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/run
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/run \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Test the saved draft without publishing it
Executes the current draft graph and records the result with `mode: test` and no `versionId`. Publishing, the live flag, and `publishedVersionId` are never touched. Side effects are simulated by default; `sideEffects: live` additionally requires `confirmLiveSideEffects: true`.
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/test
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/test \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Test one allowlisted workflow node
Executes one independently testable node from the saved draft. Variable values may be supplied from recorded run steps. Mutating HTTP methods require explicit confirmation.
Parameters
facilityId `string` (required) workflowId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/test-node
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/test-node \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
List recent runs for a workflow
Parameters
facilityId `string` (required) workflowId `string` (required)Endpoint
GET /api/workflow-engine/workflows/{facilityId}/{workflowId}/runs
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/runs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Read one run (status + ordered steps)
Parameters
facilityId `string` (required) workflowId `string` (required) executionId `string` (required)Endpoint
GET /api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Cancel the pending Delay a waiting run is sitting on
Parameters
facilityId `string` (required) workflowId `string` (required) executionId `string` (required)Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId}/cancel
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId}/cancel \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Replay a finished run from its recorded trigger payload
`mode: published` re-executes the exact version the original run was pinned to, with real side effects. `mode: draft-test` re-executes the current draft as a simulated test. A run whose trigger payload was truncated on write cannot be replayed.
Parameters
facilityId `string` (required) workflowId `string` (required) executionId `string` (required)Request Body
Endpoint
POST /api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId}/retry
Example Request
curl -X POST https://portal.hub.gymsystems.co/api/workflow-engine/workflows/{facilityId}/{workflowId}/runs/{executionId}/retry \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Indexed lookup of workflows containing a node type
Parameters
nodeType `string` (required) facilityId `string` (optional) organisationId `string` (optional)Endpoint
GET /api/workflow-engine/master-view/{nodeType}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/workflow-engine/master-view/{nodeType} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Create a new location entity on yext.
Parameters
facilityId `string` (optional) The facility ID to create the location for.Endpoint
GET /api/admin/yext/location
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/yext/location \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Delete a location entity on yext.
Parameters
entityId `string` (optional) facilityId `string` (optional) The facility ID to delete the location for.Endpoint
DELETE /api/admin/yext/location/{entityId}
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/api/admin/yext/location/{entityId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Updates an existing location entity on yext.
Parameters
id `string` (required) Location id facilityId `string` (optional) The facility ID to update the location for.Endpoint
GET /api/admin/yext/location/{id}
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/yext/location/{id} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
list all listings given a club.
Parameters
clubId `string` (required)Endpoint
GET /api/admin/club/{clubId}/yext/listings
Example Request
curl -X GET https://portal.hub.gymsystems.co/api/admin/club/{clubId}/yext/listings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
White-label OAuth redirect proxy (Connected Apps)
Public unauthenticated 302 that forwards an OAuth provider callback to the upstream tool platform's auth callback, preserving the query string. Lets PH-owned OAuth apps register a performancehub.co redirect URI so the upstream vendor's domain never appears in the address bar (needed for the future custom-OAuth-apps project; harmless under managed auth).
Endpoint
GET /guest/connected-apps/oauth-callback
Example Request
curl -X GET https://portal.hub.gymsystems.co/guest/connected-apps/oauth-callback \
-H "x-api-key: YOUR_API_KEY"
Connect-chain finish page (Connected Apps)
Lightweight "you can close this window" landing for the OAuth tab a connect chain ran in. Posts the result (connected suite/toolkit + new account ids, or the failed toolkit) back to the marketplace tab via same-origin window.opener.postMessage; when the opener was severed it falls back to a deep link into the ph-ai-agent applet that reproduces the in-app landing. Purely informational — holds no secrets and performs no writes.
Parameters
connected `string` (optional) Suite id or toolkit slug that finished connecting (success case). accounts `string` (optional) Comma-separated connected account ids the chain created. connectError `string` (optional) Toolkit slug whose step failed (failure case).Endpoint
GET /guest/connected-apps/finish
Example Request
curl -X GET https://portal.hub.gymsystems.co/guest/connected-apps/finish \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Suite connect chaining callback (Connected Apps)
OAuth-callback hop for the one-click suite connect flow. The signed state JWT (HS256, 30 min TTL) encodes { clubID, deviceId, suite, toolkits, step, caids } — the accounts connect to that one agent device, and caids accumulates the account ids each hop created (the final applet redirect carries them so the marketplace can offer to label the new accounts). Marks the step's toolkit connected, then 302s into the next toolkit's Connect Link — or to the ph-ai-agent applet page (deep-linked to the agent) when the suite is finished. Single-toolkit connects run through the same handler with a one-toolkit suite.
Parameters
state `string` (required) Signed connect-chain state JWT.Endpoint
GET /guest/connected-apps/connect-next
Example Request
curl -X GET https://portal.hub.gymsystems.co/guest/connected-apps/connect-next \
-H "x-api-key: YOUR_API_KEY"
Trigger password setup email
Validates the signed link from a welcome email, triggers a password reset email, and shows a confirmation page. No authentication required.
Parameters
email `string` (required) User email address sig `string` (required) HMAC signature for the emailEndpoint
GET /guest/setup-password
Example Request
curl -X GET https://portal.hub.gymsystems.co/guest/setup-password \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns metadata for the selected Club's ID.
Parameters
clubID `string` (required) Internal ID of the club that you wish to return data on.Endpoint
GET /internal/clubs/club-data/{clubID}
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/clubs/club-data/{clubID} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns data for the Facility
Parameters
facilityId `string` (optional) The ID of the facility to retrieve data for. slug `string` (optional) The slug of the facility to retrieve data for.Endpoint
GET /internal/facilities
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/facilities \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of all clubs in the system.
Endpoint
GET /internal/clubs/list-clubs
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/clubs/list-clubs \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns an array of user emails that have permission to a club
Parameters
club `string` (optional) Internal ID of the club that you wish to access.Endpoint
GET /internal/clubs/list-user-access/{club}
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/clubs/list-user-access/{club} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of all users and what clubs they have permission to access.
Endpoint
GET /internal/clubs/list-user-access
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/clubs/list-user-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Notifies the requester that a device-replacement restore reached a terminal state. Called by universal-api's backup restore-status handler; the outcome is read from the registration's restoreRequest, not from the request body.
Parameters
body `object` (optional)Endpoint
POST /internal/devices/ph-ai-agent/restore-complete
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/devices/ph-ai-agent/restore-complete \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns brand settings for the selected facility.
Parameters
facilityId `string` (required) Internal ID of the facility that you wish to return data on.Endpoint
GET /internal/facilities/{facilityId}/brand-settings
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/facilities/{facilityId}/brand-settings \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Internal API to delete article embeddings from vector store
Request Body
Endpoint
DELETE /internal/llm/delete-article
Example Request
curl -X DELETE https://portal.hub.gymsystems.co/internal/llm/delete-article \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Internal API to upsert article embeddings into vector database
Handles article embedding based on current state: - If article is unpublished OR private: deletes embeddings - If article is published AND public: re-embeds with full content Always requires full article body.
Request Body
Endpoint
POST /internal/llm/upsert-embeddings
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/llm/upsert-embeddings \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Return organisation data
Parameters
orgId `string` (optional) ID of the organisation you wish to retrieve.Endpoint
GET /internal/organisations/{orgId}
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/organisations/{orgId} \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Returns a list of organisations.
Parameters
orgId `string` (optional) ID of the organisation you wish to retrieve.Endpoint
GET /internal/organisations
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/organisations \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get simplified list of roles for an organisation
Returns a simplified list of roles available to an organisation without user access filtering
Parameters
organisationId `string` (required) The organisation ID to get roles forEndpoint
GET /internal/organisations/{organisationId}/roles
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/organisations/{organisationId}/roles \
-H "x-api-key: YOUR_API_KEY"
Response
[]
Returns the data of user preferences.
Endpoint
GET /user-preferences/get-user-preferences
Example Request
curl -X GET https://portal.hub.gymsystems.co/user-preferences/get-user-preferences \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Return user data and their access to modules
Parameters
email `string` (required) Email of the user you wish to check access for. moduleId `string` (required) Internal ID of the module that you wish to check access for (can be multiple).Endpoint
GET /internal/clubs/get-user-access
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/clubs/get-user-access \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Get user record by email address
Returns the user record from access permissions by email address
Parameters
email `string` (required) Email address of the user you wish to get the record for.Endpoint
GET /internal/users/by-email
Example Request
curl -X GET https://portal.hub.gymsystems.co/internal/users/by-email \
-H "x-api-key: YOUR_API_KEY"
Response
{}
Add or update login provider user ID for a user
Associates a login provider's user ID with an existing user account
Request Body
Endpoint
POST /internal/users/update-login-provider
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/users/update-login-provider \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Check if a user requires 2FA
Returns whether 2FA is required for a given user email (either enabled by user or forced by role)
Request Body
Endpoint
POST /internal/sso-service/check-2fa-status
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/check-2fa-status \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Request password reset
Generates a password reset token and sends an email with reset link to the user
Request Body
Endpoint
POST /internal/sso-service/forgot-password
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/forgot-password \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Reset user password using reset token
Validates a password reset token and updates the user's password. The token must be valid, not expired, and not previously used.
Request Body
Endpoint
POST /internal/sso-service/reset-password
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/reset-password \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Send OTP to user via SMS or email
Sends an OTP code to the user. Attempts SMS first using the user's phone number, then falls back to email if SMS fails or no phone number is available.
Request Body
Endpoint
POST /internal/sso-service/send-otp
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/send-otp \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Validate a user's password
Validates a password against the stored hash for a given user email
Request Body
Endpoint
POST /internal/sso-service/validate-password
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/validate-password \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}
Verify OTP for SSO password validation
Verifies the OTP code sent after successful password validation when 2FA is required
Request Body
Endpoint
POST /internal/sso-service/verify-otp
Example Request
curl -X POST https://portal.hub.gymsystems.co/internal/sso-service/verify-otp \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
Response
{}