Classes and calendars
The Club API exposes a club’s published Classes through calendar operations.
Each Class is one scheduled activity with a stable ClassId, start and end
instants, trainer information, capacity, and payment configuration.
The API does not create or edit Classes. Use the calendar as the authoritative read model and the participant operations to book or cancel athletes.
See the data model for a representative Class object, Class participants for booking flows, and Bulk summaries and bookings for paginated booking imports.
Choose a calendar
Section titled “Choose a calendar”The route identifies which public calendar to read:
| Calendar type | Use |
|---|---|
Club |
Activities published in the club’s main class calendar. |
PT |
Personal-training appointments. |
Services |
Service appointments published by the club. |
Only the calendar types listed above are accepted. Any other value returns
400 Bad Request.
Read a calendar window
Section titled “Read a calendar window”Open
GET /Classes/Calendars/{calendarType}
for all parameters and response fields. For a finite calendar window, supply
both time boundaries:
curl --request GET \ --url "https://api-gw.uptivo.fit/club/Classes/Calendars/Club?from=2030-10-01T00%3A00%3A00%2B02%3A00&to=2030-11-01T00%3A00%3A00%2B01%3A00&count=500" \ --header "X-Sub-Key: <subscription-key>" \ --header "Authorization: Bearer <club-api-key>"from is inclusive and to is exclusive. A Class is selected using its
Begin instant:
from <= Begin < toA Class that starts before from is not returned even if it ends inside the
window. Supply complete ISO 8601 timestamps with Z or an explicit offset.
The API compares them as absolute instants; use the club’s TimeZoneCode when
constructing local calendar boundaries.
The endpoint returns only published Classes belonging to the club selected by
the Club API Key. An empty window returns 200 OK with an empty Results
array.
Paginate the calendar
Section titled “Paginate the calendar”The response includes opaque cursors for forward and backward traversal:
{ "NextCursor": "<opaque-next-cursor>", "PrevCursor": "<opaque-prev-cursor>", "Results": [ { "ClassId": 700001, "Name": "Evening yoga", "Begin": "2030-10-12T18:30:00+02:00" } ], "Continue": true}The default count is 100 and the maximum is 500. Repeat all parameters from
the first request, then send the opaque token:
GET /Classes/Calendars/Club?from=2030-10-01T00:00:00+02:00&to=2030-11-01T00:00:00+01:00&count=500&cursor=<NextCursor>The cursor preserves the exact (Begin, ClassId) position. The endpoint also
allows open-ended date traversal or ID windows when no dates are supplied.
Calendar from remains inclusive and to remains exclusive.
For durable synchronization, periodically rescan a bounded rolling window and
upsert by ClassId: Begin is schedule time, not a change timestamp. See
Pagination and synchronization.
Interpret a Class
Section titled “Interpret a Class”A result resembles this object:
{ "ClassId": 700001, "Name": "Evening yoga", "Begin": "2030-10-12T18:30:00+02:00", "End": "2030-10-12T19:15:00+02:00", "ActivityType": "Yoga", "Color": "#54e5cd", "PictureUri": null, "TrainerId": 800001, "TrainerName": "Example Trainer", "TrainerPictureUri": null, "CreditsCostLocal": 2, "CreditsCostRemote": 1, "TicketsCostLocal": 1, "TicketsCostRemote": 1, "MaxLocalParticipants": 12, "MaxRemoteParticipants": 20}| Property | Meaning |
|---|---|
ClassId |
Stable identifier used by participant operations and Class webhook subjects. |
Begin, End |
Complete start and end instants, including their UTC offset. |
ActivityType |
Activity classification; use the API reference for the complete enum. |
TrainerId |
Uptivo user identifier of the trainer, when linked to a user. |
TrainerName |
Display name; it can be present even when TrainerId is null. |
CreditsCostLocal, CreditsCostRemote |
Club credits charged for in-site or remote attendance. |
TicketsCostLocal, TicketsCostRemote |
Activities consumed from a limited UserSubscription for in-site or remote attendance. |
MaxLocalParticipants, MaxRemoteParticipants |
Confirmed-place capacity for each attendance mode. Queued athletes are not included. |
Local in calendar property names corresponds to the participant mode
InSite. Costs and capacities are independent for InSite and Remote.
Request optional fields
Section titled “Request optional fields”Calendar responses are compact by default. Add expansions only when needed:
GET /Classes/Calendars/Club ?from=2030-10-01T00:00:00+02:00 &to=2030-11-01T00:00:00+01:00 &withDescriptions=true &withSubscriptions=true &withParticipants=true| Option | Additional properties |
|---|---|
withDescriptions=true |
Description. |
withSubscriptions=true |
LocalSubscriptionIds and RemoteSubscriptionIds. |
withParticipants=true |
ParticipantUserIds. |
When an option is omitted or false, the related properties can be absent
from JSON rather than present with null. Do not erase previously stored
expanded data merely because a later compact response omits it.
The subscription arrays contain ClassSubscriptionId values accepted for the
corresponding attendance mode. Resolve them through
Subscriptions. ParticipantUserIds contains only
athletes with a confirmed Participant state; queued athletes are excluded.
Use GET /Classes/{classId}/Participants when you need state, payment, trial,
or no-show details.
Read a single Class
Section titled “Read a single Class”When you already know the identifier, retrieve the current published Class directly:
curl --request GET \ --url https://api-gw.uptivo.fit/club/Classes/700001 \ --header "X-Sub-Key: <subscription-key>" \ --header "Authorization: Bearer <club-api-key>"GET /Classes/{classId} returns the same
ClubActivityForCalendarDTO representation used by calendar results. The
Description is populated, while the optional subscription and participant
ID arrays are not expanded. It returns 404 when the Class is absent,
unpublished, uses a non-public calendar type, or belongs to another club.
Refresh and remove local Classes
Section titled “Refresh and remove local Classes”Use GET /Classes/{classId} for targeted refreshes triggered by a known
ClassId. Calendar windows remain necessary for initial discovery, scheduled
reconciliation, and detecting Classes that moved into or out of a time window.
Class webhook events provide low-latency change signals, but calendar rescans remain the recovery mechanism:
- Keep a rolling window covering the dates relevant to your application.
- Upsert every result by
ClassId. - Process Class webhook events idempotently and use the detail operation when an event supplies a specific identifier.
- Periodically rescan the window to recover missed or out-of-order events.
- Remove a local Class after
Class.Deleted, or after authoritative reconciliation confirms that it is no longer present.
Because Classes can move between time windows, avoid assuming that absence from
one new window proves deletion. Retain the previous Begin value or consume
webhooks so the old window can also be reconciled.
Permissions and errors
Section titled “Permissions and errors”Calendar reads require Read or ReadWrite access. Missing or invalid
credentials return 401; an inactive Club API license or insufficient key
permission returns 403.
The endpoint returns 400 for an invalid range or cursor, or when the calendar
type is unsupported. Open-ended date or ID traversal follows the rules in
Pagination and synchronization. See
Errors for the common response rules.