Organization and people
Read a customer's organization, its athletes with their sport profile, coaches and teams.
Athletes and coaches are users with a membership in the customer's organization. Athletes carry the ids of their teams, and a team carries the ids of its athletes. People are not limited by the customer's history: you always see the current members.
Get the organization
Call it first with a new key: it tells you which organization the key opens.
Returns the organization that owns the API key. Use it to confirm a key works and which organization it is scoped to.
Request
curl "https://api-integrations-next.vitruve.fit/v1/organization" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/organization',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/organization",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"id": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"name": "Northgate Performance",
"category": "professional-team",
"measurementSystem": "metric",
"phoneNumber": null,
"createdAt": "2025-06-10T09:00:00.000Z",
"updatedAt": "2026-01-21T15:40:12.000Z",
"deletedAt": null
}
}Response fields
iduuid- Organization id.
namestring- Organization name.
categorystring- Organization category chosen at sign-up.
measurementSystemstring- The organization’s default measurement system.
Failures are described in error codes.
List athletes
Active athletes of your organization, ordered by surname, then name. Each athlete carries their membership and the ids of their teams.
Request
curl "https://api-integrations-next.vitruve.fit/v1/athletes?limit=2&teamId=9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/athletes?limit=2&teamId=9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/athletes?limit=2&teamId=9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": [
{
"id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"name": "Marta",
"surname": "Ibáñez",
"email": "marta.ibanez@example.com",
"isVerified": true,
"profession": "athlete",
"gender": "female",
"measurementSystem": "metric",
"avatarPath": null,
"height": 172,
"weight": 64,
"birthDate": "1998-04-12T00:00:00.000Z",
"dominantSide": "right",
"createdAt": "2025-09-02T08:14:31.402Z",
"updatedAt": "2026-03-18T10:22:05.117Z",
"deletedAt": null,
"organizationsToUsers": [
{
"id": "0d2f6b8e-5a17-4c93-b4e1-93a7c0d58f21",
"userId": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"roleId": "dc82d01f-1136-4fcb-97dc-11a8b2203d98",
"createdAt": "2025-09-02T08:14:31.402Z",
"updatedAt": "2025-09-02T08:14:31.402Z",
"deletedAt": null
}
],
"teams": [
{
"id": "9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64"
}
]
}
],
"meta": {
"limit": 2,
"hasMore": true,
"nextCursor": "ZTU2M2ZlYzMtM2IxYy00…"
}
}Query parameters
searchstring- Case-insensitive. Every word must match the name, surname or email, so a full name such as
Ana Garcíaworks. teamIduuid- Only athletes in this team.
limitintegerdefault50- Page size, 1–100.
cursorstringmeta.nextCursorfrom the previous page. Omit it to get the first page.
Response fields
iduuid- Athlete id. Pass it as
userIdto the workout, metric and wellness endpoints. namestring- First name.
surnamestring- Last name.
emailstringnullable- Email address, if the athlete has one.
isVerifiedboolean- Whether the athlete has verified their email.
genderstringnullable- Gender as entered in the athlete profile.
birthDatedatetimenullable- Date of birth, serialized as a UTC timestamp at midnight.
heightintegernullable- Height in cm, whatever the athlete’s
measurementSystem: convert for display. weightintegernullable- Body weight in kg, whatever the athlete’s
measurementSystem: convert for display. dominantSidestringnullable- Dominant side,
leftorright. measurementSystemstringnullable- The athlete’s preferred measurement system.
organizationsToUsers[]object[]- The athlete’s membership in your organization.
roleIdis always the Athlete role. teams[].iduuid- Teams the athlete belongs to. Resolve with
GET /teams/{id}.
Failures are described in error codes.
Get an athlete
One athlete of your organization.
Request
curl "https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"name": "Marta",
"surname": "Ibáñez",
"email": "marta.ibanez@example.com",
"isVerified": true,
"profession": "athlete",
"gender": "female",
"measurementSystem": "metric",
"avatarPath": null,
"height": 172,
"weight": 64,
"birthDate": "1998-04-12T00:00:00.000Z",
"dominantSide": "right",
"createdAt": "2025-09-02T08:14:31.402Z",
"updatedAt": "2026-03-18T10:22:05.117Z",
"deletedAt": null,
"organizationsToUsers": [
{
"id": "0d2f6b8e-5a17-4c93-b4e1-93a7c0d58f21",
"userId": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"roleId": "dc82d01f-1136-4fcb-97dc-11a8b2203d98",
"createdAt": "2025-09-02T08:14:31.402Z",
"updatedAt": "2025-09-02T08:14:31.402Z",
"deletedAt": null
}
],
"teams": [
{
"id": "9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64"
}
]
}
}Path parameters
iduuidrequired- Resource id.
Response fields
iduuid- Athlete id. Pass it as
userIdto the workout, metric and wellness endpoints. namestring- First name.
surnamestring- Last name.
emailstringnullable- Email address, if the athlete has one.
isVerifiedboolean- Whether the athlete has verified their email.
genderstringnullable- Gender as entered in the athlete profile.
birthDatedatetimenullable- Date of birth, serialized as a UTC timestamp at midnight.
heightintegernullable- Height in cm, whatever the athlete’s
measurementSystem: convert for display. weightintegernullable- Body weight in kg, whatever the athlete’s
measurementSystem: convert for display. dominantSidestringnullable- Dominant side,
leftorright. measurementSystemstringnullable- The athlete’s preferred measurement system.
organizationsToUsers[]object[]- The athlete’s membership in your organization.
roleIdis always the Athlete role. teams[].iduuid- Teams the athlete belongs to. Resolve with
GET /teams/{id}.
Failures are described in error codes.
Get an athlete’s sport profile
The athlete’s sport profile with its dated versions. The version with validTo: null is the current one.
Request
curl "https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62/profile" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62/profile',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/athletes/3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62/profile",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"id": "6e0b9d41-c2a8-4f35-8b17-d5a3e92c0f68",
"userId": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"revision": 2,
"createdAt": "2025-09-02T08:20:00.000Z",
"updatedAt": "2026-02-01T09:00:00.000Z",
"deletedAt": null,
"versions": [
{
"id": "b3a8d5f0-71e2-4c69-90a4-e1c7f2d83b56",
"profileId": "6e0b9d41-c2a8-4f35-8b17-d5a3e92c0f68",
"validFrom": "2026-02-01T00:00:00.000Z",
"validTo": null,
"sport": "basketball",
"position": "guard",
"competitionLevel": "professional",
"squad": "first-team",
"strengthTrainingStartedYear": 2016,
"recordedAt": "2026-02-01T09:00:00.000Z",
"recordedByUserId": "5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47"
}
]
}
}Path parameters
iduuidrequired- Resource id.
Response fields
revisioninteger- Increments every time the profile changes.
versions[]object[]- Profile history, newest
validFromfirst. versions[].validFromdatetime- First day this version applies.
versions[].validTodatetimenullablenullfor the current version.versions[].recordedByUserIduuid- Who recorded the version: the athlete themselves, or a staff member. Resolve with
GET /athletes/{id}orGET /coaches/{id}.
Failures are described in error codes.
List coaches
Owners and coaches of your organization, with their membership.
Request
curl "https://api-integrations-next.vitruve.fit/v1/coaches?limit=25" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/coaches?limit=25',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/coaches?limit=25",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": [
{
"id": "5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47",
"name": "Daniel",
"surname": "Okafor",
"email": "daniel.okafor@northgate.example",
"isVerified": true,
"profession": "coach",
"organizationsToUsers": [
{
"id": "9c4e1a73-d085-4b2f-a6e8-31f7b5d02c94",
"userId": "5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47",
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"roleId": "ef736bad-c98e-410e-bf26-af834332153b",
"deletedAt": null
}
]
}
],
"meta": {
"limit": 25,
"hasMore": true,
"nextCursor": "ZTU2M2ZlYzMtM2IxYy00…"
}
}Query parameters
searchstring- Case-insensitive. Every word must match the name, surname or email, so a full name such as
Ana Garcíaworks. roleIduuid- Only owners (
4aa018e6-8b22-40b1-8d07-ab4f1af51330) or only coaches (ef736bad-c98e-410e-bf26-af834332153b). limitintegerdefault50- Page size, 1–100.
cursorstringmeta.nextCursorfrom the previous page. Omit it to get the first page.
Response fields
iduuid- Coach id. Matches
createdByand, when a staff member recorded it,recordedByUserIdon other resources. organizationsToUsers[].roleIduuid- Owner or Coach role id.
Failures are described in error codes.
Get a coach
One owner or coach of your organization.
Request
curl "https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"id": "5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47",
"name": "Daniel",
"surname": "Okafor",
"email": "daniel.okafor@northgate.example",
"isVerified": true,
"profession": "coach",
"organizationsToUsers": [
{
"userId": "5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47",
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"roleId": "ef736bad-c98e-410e-bf26-af834332153b"
}
]
}
}Path parameters
iduuidrequired- Resource id.
Failures are described in error codes.
List a coach's athletes
The ids of the athletes a coach is assigned to: every athlete of your organization except those unassigned from them. The owner’s id answers every athlete: the owner is never unassigned.
Request
curl "https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47/athletes" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47/athletes',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/coaches/5e2a7b90-4c13-4f8d-a6b1-d93f0e8c2a47/athletes",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"athleteIds": [
"3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62",
"c81d5f07-92ab-4e63-b0d4-7a3e6c1f9e28"
]
}
}Path parameters
iduuidrequired- Resource id.
Response fields
athleteIdsuuid[]- Resolve with
GET /athletes/{id}.
Failures are described in error codes.
List teams
Teams of your organization, ordered by name, each with the ids of its athletes.
Request
curl "https://api-integrations-next.vitruve.fit/v1/teams?limit=10" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/teams?limit=10',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/teams?limit=10",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": [
{
"id": "9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64",
"name": "First team",
"avatarPath": null,
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"createdAt": "2025-09-01T10:00:00.000Z",
"updatedAt": "2025-09-01T10:00:00.000Z",
"deletedAt": null,
"users": [
{
"id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62"
},
{
"id": "c81d5f07-92ab-4e63-b0d4-7a3e6c1f9e28"
}
]
}
],
"meta": {
"limit": 10,
"hasMore": true,
"nextCursor": "ZTU2M2ZlYzMtM2IxYy00…"
}
}Query parameters
searchstring- Case-insensitive match on the team name.
limitintegerdefault50- Page size, 1–100.
cursorstringmeta.nextCursorfrom the previous page. Omit it to get the first page.
Response fields
users[].iduuid- Athletes in the team. Resolve with
GET /athletes/{id}.
Failures are described in error codes.
Get a team
One team with the ids of its athletes.
Request
curl "https://api-integrations-next.vitruve.fit/v1/teams/9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64" \
-H "X-API-Key: CUSTOMER_INTEGRATION_KEY" \
-H "X-Partner-Secret: YOUR_PARTNER_SECRET"const response = await fetch(
'https://api-integrations-next.vitruve.fit/v1/teams/9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64',
{
headers: {
'X-API-Key': customer.vitruveKey,
'X-Partner-Secret': process.env.VITRUVE_PARTNER_SECRET
}
}
)
const body = await response.json()
if (!response.ok) throw new Error(`${response.status}: ${body.message}`)
console.log(body.data)import os
import requests
response = requests.get(
"https://api-integrations-next.vitruve.fit/v1/teams/9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64",
headers={
"X-API-Key": customer.vitruve_key,
"X-Partner-Secret": os.environ["VITRUVE_PARTNER_SECRET"],
},
timeout=30,
)
response.raise_for_status()
print(response.json()["data"])Response 200
{
"ok": true,
"timestamp": 1738247125207,
"data": {
"id": "9a4f6d13-8b25-4c7e-93a0-1f5d2e8b7c64",
"name": "First team",
"avatarPath": null,
"organizationId": "7d3f8a52-1c0e-4b8e-9f4a-2e6b1d9c5a10",
"users": [
{
"id": "3b9c1e24-6f7a-4d2b-8c15-a40e9d7f1b62"
},
{
"id": "c81d5f07-92ab-4e63-b0d4-7a3e6c1f9e28"
}
]
}
}Path parameters
iduuidrequired- Resource id.
Failures are described in error codes.