Data model
The Club API exposes the Uptivo entities needed for club-management integrations. Every request is scoped to the club selected by the Club API Key.
The examples below are representative, anonymized responses. They deliberately
show only the fields that are useful for understanding each entity. Properties
may be omitted when they are not requested, do not apply, or are configured to
be excluded when their value is null. Use the
API reference as the authoritative source for complete
schemas, enum values, validation limits, and nullability.
The examples reproduce the public API’s PascalCase property names exactly.
A Club is the scope of every Club API operation. The Club API Key determines which club is selected; callers do not pass a club ID to switch scope.
GET /Profile returns the selected club:
{ "ClubId": 100001, "BrandId": 200001, "ClubCode": "EXAMPLE", "Name": "Example Fitness Club", "PictureUri": "https://cdn.example.test/clubs/example/profile.png", "Address": "1 Example Street\nMilan\nItaly", "Latitude": 45.4642, "Longitude": 9.19, "Phone": "+390200000000", "Email": "club@example.test", "WebSiteUri": "https://club.example.test", "CountryCode": "IT", "TimeZoneCode": "Europe/Rome", "FirstDayOfWeek": "Monday", "DateFormat": "ddmmyyyy", "TimeFormat": "h24", "UnitsSystem": "Metric", "Language": "Italian", "DefaultCurrency": "EUR"}Use ClubId as the stable Uptivo identifier and verify it before performing
write operations. TimeZoneCode, DateFormat, TimeFormat, and UnitsSystem
describe club settings; they do not change the ISO 8601 representation used by
API timestamps. Latitude and Longitude are either both populated or both
null. The profile always contains every ClubProfileDTO property; optional
values are serialized as null.
A User is a person with an Uptivo account. A user may belong to one, multiple, or no clubs. The Club API cannot access users globally.
Athlete
Section titled “Athlete”An Athlete is a user associated with the selected club. The same UserId
identifies the person in athlete, training, subscription, and participation
responses within the public API.
An existing user can be invited to join a club by email. A user that does not exist can instead be created and immediately associated with the club. The Club API operates only on the resulting Athlete relationship; removing an athlete from a club does not delete the global Uptivo user.

Representative ClubAthleteDTO response:
{ "UserId": 300001, "Email": "athlete@example.test", "FirstMidName": "Alex", "LastName": "Example", "Nickname": null, "Phone": null, "Gender": "Unspecified", "Weight": 70, "Height": 180, "IsDemo": false, "JoinMode": "System", "IsGuest": false, "CreatedAt": "2026-01-15T09:30:00+01:00", "QualifiedUtc": null, "ProspectUtc": null, "ClientUtc": "2026-01-20T10:00:00Z", "ClientStage": "Client", "TaxId": null, "BirthDate": "1990-06-15"}Age is returned only for demo athletes, while BirthDate is omitted for demo
athletes. IsGuest and ClientStage describe this club’s Athlete relationship,
not the global User. ClientStage is Lead, Qualified, Prospect, or
Client. The corresponding UTC milestone is retained once the Athlete first
reaches Qualified, Prospect, or Client. See the
Athletes guide for the complete workflow.
Contact
Section titled “Contact”A Contact is a non-demo Uptivo user associated with the selected club without
an Athlete membership there. It has the same global UserId if it later
becomes an Athlete, but its club relationship is separate. Contact access does
not expose training, telemetry, subscriptions, or engagement data.
Representative ClubContactDTO response:
{ "ClubId": 100001, "UserId": 300001, "Email": "contact@example.test", "FirstMidName": "Alex", "LastName": "Example", "Nickname": null, "Phone": "+390200000001", "CreatedAt": "2026-02-10T09:00:00+01:00", "JoinedAt": null, "ClientStage": "Lead"}CreatedAt is when the Contact relationship began. JoinedAt may contain
the original joining date when this person was previously an Athlete.
ClientStage is specific to the club, may be unassigned, and can be set
through a dedicated Contact operation without converting the user to an
Athlete. The
Contacts guide explains lookups and reconciliation.
Training
Section titled “Training”A Training represents one athlete workout. A workout may have been recorded at
the club or outside it, depending on its origin and ClubId. The API can return
trainings with or without raw telemetry.
Representative partial ClubTrainingDTO response:
{ "TrainingId": 400001, "UserId": 300001, "ClubId": 100001, "GroupTrainingId": null, "IsSubTraining": false, "IsLive": false, "Title": "Indoor cycling", "TrainingType": "IndoorCycling", "Begin": "2026-02-10T17:00:00Z", "BeginDateLocal": "2026-02-10", "End": "2026-02-10T17:45:00Z", "Duration": "0.00:45:00.000", "MinBpm": 82, "MaxBpm": 176, "AvgBpm": 142, "TargetZoneLowBpm": 130, "TargetZoneHighBpm": 160, "TargetZoneTime": "0.00:27:30.000", "Points": 245, "CaloriesTotal": 410, "Distance": 18750, "AvgPower": 165, "MaxPower": 420, "AvgCadence": 84}Begin and End are ISO 8601 timestamps. BeginDateLocal is a calendar
date in the athlete’s timezone (YYYY-MM-DD), which can differ from the UTC
date of Begin. Duration and heart-rate/power-zone times use the .NET
duration format shown above, not an ISO timestamp. Every Training operation
returns this same flat representation. withTelemetry=true adds an optional
Telemetry object containing HeartBeats, GeoPositions, Powers,
Cadences, and Hits; withUser=true independently adds the current
ClubAthleteDTO as User. See the Trainings guide for
retrieval and synchronization.
Telemetry
Section titled “Telemetry”Telemetry is the raw time series associated with an athlete’s activity. The available series are heart rate, geolocation, power, cadence, and HIT data. Each series is represented as compact numeric arrays whose first value is a Unix timestamp in milliseconds.
Telemetry can be large. Request it only when the integration needs raw samples, and keep time ranges as narrow as possible. Prefer normal training responses when aggregate values are sufficient. The Telemetry guide defines every public tuple position and its unit.
Subscription
Section titled “Subscription”A Subscription is a commercial definition owned by the club. It describes a membership or activity package; it is not an athlete’s purchased or assigned instance.
Representative SubscriptionForListDTO response:
{ "ClassSubscriptionId": 500001, "Name": "Monthly classes", "ShortDescription": "Eight classes over 30 days", "MaxWeeklyBookings": 3, "MaxMonthlyBookings": 8, "AutoAssign": false, "LongDescription": "Access to eligible on-site classes.", "PublishState": "Published", "Type": "Membership", "Plans": [ { "UnitMultiplier": 100, "ClassSubscriptionPlanId": 510001, "DurationDays": 30, "MaxActivities": 8, "Amount": 12000, "Currency": "eur", "Interval": "None", "IntervalCount": 0, "Iterations": 0 } ]}LongDescription and Plans are included only when their corresponding query
options are enabled. PublishState may be omitted when the request already
filters by that value. Type identifies the catalog entry as Other, Trial,
or Membership. Monetary Amount uses the currency’s smallest unit; divide it
by UnitMultiplier for the major-unit value. In the example, 12000 / 100 is
EUR 120.00. A MaxActivities value of 0 means unlimited activities.
See Subscriptions for catalog filtering and plan
interpretation, then User subscriptions for
assignment workflows.
UserSubscription
Section titled “UserSubscription”A UserSubscription associates an Athlete with a Subscription for a defined period. It is the athlete-specific entitlement used when eligibility and remaining activities are evaluated.

Representative UserClassSubscriptionDTO response:
{ "UserClassSubscriptionId": 600001, "ClassSubscriptionId": 500001, "UserId": 300001, "From": "2026-02-01T00:00:00+01:00", "To": "2026-03-03T00:00:00+01:00", "DurationDays": 30, "MaxActivities": 8, "AvailableActivities": 5, "ClassSubscriptionPlanId": 510001, "SuspendedAtUTC": null, "ReactivationDate": null, "Interval": "None", "IntervalCount": 0, "PaymentAccount": null, "ExtSubscriptionId": null, "ExtStatus": null, "Disabled": false, "ExtInvoiceId": null, "DueDateUTC": null, "IsSuspended": false, "SuspendedDays": 0}AvailableActivities is the current remaining allowance and cannot exceed
MaxActivities; 0 for MaxActivities means unlimited. A deleted source plan
can leave ClassSubscriptionPlanId as null. IsSuspended and
SuspendedDays are calculated response fields. The active endpoint applies
the server’s current active-subscription rules; do not reproduce those rules by
checking only From and To locally.
The User subscriptions guide
defines the complete active predicate and synchronization strategy.
Membership summary
Section titled “Membership summary”ClubAthleteMembershipSummaryDTO describes an Athlete’s effective membership
in the selected club at CalculatedAtUtc. Status is None, Active,
Paused, Pending, Expired, or Canceled. It is derived from all club
assignments, not from a single representative Subscription.
Memberships contains the assignment IDs, Subscription name, dates, ticket
balances, and suspension information, including disabled and exhausted
assignments. Its suspension field is SuspendedAtUtc; use this exact casing
when mapping the summary. ActiveFrom, ActiveUntil, NextPendingStart, and
MostRecentEnd describe assignment boundaries, not state-transition dates.
Individual and bulk reads return this same representation. See Read effective membership states for precedence, empty assignments, and reconciliation.
A Class is one scheduled club activity, such as a lesson, course occurrence,
personal-training session, or service appointment. The public calendar returns
ClubActivityForCalendarDTO objects.
Representative response from a calendar endpoint:
{ "ClassId": 700001, "Name": "Evening yoga", "Description": "A guided 45-minute session.", "Begin": "2026-02-12T18:30:00+01:00", "End": "2026-02-12T19:15:00+01: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, "LocalSubscriptionIds": [500001], "RemoteSubscriptionIds": [500001], "ParticipantUserIds": [300001]}Description, eligible subscription ID arrays, and participant IDs are
conditional fields controlled by the calendar request options. If an option is
not enabled, the related property can be omitted. Begin and End include the
applicable UTC offset and should be treated as complete instants.
GET /Classes/{classId} returns the same public representation for one
published Class. Its Description is populated; subscription and participant
ID arrays are not expanded.
ClassParticipant
Section titled “ClassParticipant”A ClassParticipant is the association between an Athlete and a Class. It records how the athlete attends, whether the athlete has a confirmed place or is queued, and how participation was booked.

GET /Classes/{classId}/Participants returns a complete, non-paginated array
of ClubClassParticipationDTO objects. The same item representation is used by
the individual and paginated booking reads:
{ "ClubId": 100001, "ClassId": 700001, "ClassName": "Evening yoga", "ClassBegin": "2026-02-12T18:30:00+01:00", "UserId": 300001, "Mode": "InSite", "State": "Participant", "CreatedAtUtc": "2026-02-01T14:05:00Z", "CreditsCost": 0, "ClassSubscriptionId": 500001, "NoShow": false, "Trial": false, "BookActorId": 800001, "BookActorName": "Example Trainer"}Mode is InSite or Remote; State is Participant or InQueue.
Subscription properties are nullable because participation does not always
consume a subscription. BookActorId and BookActorName are retained for
existing clients and omitted when no booking actor is available.
Adding or removing a participant returns ClassParticipantOpResultDTO, a
different operation-result schema. Consult the API reference
for that response and Errors for the domain conflicts that can
prevent a booking.
GET /Classes/{classId}/Participants/{userId}, the complete participant array,
GET /Classes/Participants/Recent, and the three /Bookings operations all
return ClubClassParticipationDTO. It includes the Class interval, calendar
and activity types, location, trainer, costs, and associated UserSubscription
information. Nullable subscription properties are null when the booking is
free, credit-only, or its assignment is unavailable. CreditsCost and
SubscriptionCost describe the booking; they are not signed transaction
amounts.
GET /Athletes/{userId}/AttendanceSummary returns
ClubAttendanceSummaryDTO: lifetime first/last check-in and total count, plus
counts for the last days elapsed UTC days and the days days before them
(default 30). Check-ins require confirmed NoShow=false bookings whose Classes
have started. Dates use Class Begin and reflect current saved booking flags;
there is no arbitrary Class date filter.
The bulk summary operations return these same engagement and attendance DTOs for every current, non-demo Athlete. They include explicit zero rows so absence from the result is not used to infer inactivity.
Challenge and Challenge result
Section titled “Challenge and Challenge result”A Challenge defines a time-bounded activity goal or ranking owned by a club or
brand. Its public identifier is TrainingChallengeId. ClubChallengeDTO
contains its interval, display content, ranking criterion, Training origin,
assignment mode, eligibility, and award-policy settings.
A Challenge result associates the Challenge with an Athlete through UserId.
TrainingChallengeRankingDTO contains the Athlete’s score, rank, percentage,
Training totals, display data, and optional badge image. Result lists are
paginated by UserId, not rank. Rank, RankPrc, and Participants remain
relative to all scored participants in the Challenge, including eligible
participants from other clubs of the same brand.
Ranks are live calculations rather than saved award records. Use
Badge awards for award history and
Badge.Awarded for notifications.
See Challenges and results for visibility,
pagination, and synchronization rules.
Badge award
Section titled “Badge award”ClubBadgeAwardDTO identifies one challenge badge award through
AchievedBadgeId. BadgeId identifies the design; repeated awards of that
design have different award IDs. AchievedAt is the effective award date,
not the list ordering position. Id is the equivalent string
badge-<AchievedBadgeId>.
Club-wide, Athlete-specific, and individual reads use this same DTO. Optional
challenge, goal, and ranking context may be null. The Badge.Awarded event
also supplies TrainingChallengeId and AwardType, which are not in the
read response. See Badge awards for visibility and
reconciliation.