> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fitsociety.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Coaches

> List coaches through the FITsociety Public API.

## List coaches

```http theme={null}
GET /public/v1/coaches
Authorization: Bearer <access_token>
```

Required scope:

```txt theme={null}
coaches:read
```

Query parameters:

| Parameter | Type    | Notes                                     |
| :-------- | :------ | :---------------------------------------- |
| `page`    | integer | 1-based page number                       |
| `limit`   | integer | Defaults to 100, maximum 500              |
| `search`  | string  | Searches first name, last name, and email |
| `role`    | string  | One of `Coach`, `Manager`, or `Admin`     |

Example:

<CodeGroup>
  ```bash cURL theme={null}
  curl -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
    "https://api.fitsociety.io/public/v1/coaches?page=1&limit=50&search=doe"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.fitsociety.io/public/v1/coaches?page=1&limit=50&search=doe",
    {
      headers: {
        Authorization: `Bearer ${process.env.FITSOCIETY_ACCESS_TOKEN}`,
      },
    },
  );

  const body = await response.json();
  console.log(body.data.total, body.data.data);
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.get(
      "https://api.fitsociety.io/public/v1/coaches",
      headers={"Authorization": f"Bearer {os.environ['FITSOCIETY_ACCESS_TOKEN']}"},
      params={"page": 1, "limit": 50, "search": "doe"},
  )
  response.raise_for_status()

  body = response.json()
  print(body["data"]["total"], body["data"]["data"])
  ```
</CodeGroup>

Response:

```json theme={null}
{
  "data": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "totalPages": 1,
    "hasNextPage": false,
    "hasPrevPage": false,
    "data": [
      {
        "_id": "64b64c0f2f5f4c0012345671",
        "firstName": "John",
        "lastName": "Doe",
        "email": "john@example.com",
        "role": "Coach",
        "language": "nl",
        "trainerStatus": true,
        "image": null,
        "lastActive": "2026-08-22T14:05:00.000Z",
        "online": false
      }
    ]
  },
  "meta": {
    "requestId": "req_0123456789abcdef",
    "rateLimit": { "limit": 10, "remaining": 9, "resetSeconds": 1 }
  }
}
```

## Get a coach

```http theme={null}
GET /public/v1/coaches/{coachId}
Authorization: Bearer <access_token>
```

Required scope:

```txt theme={null}
coaches:read
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -H "Authorization: Bearer $FITSOCIETY_ACCESS_TOKEN" \
    "https://api.fitsociety.io/public/v1/coaches/64b64c0f2f5f4c0012345671"
  ```

  ```javascript JavaScript theme={null}
  const coachId = "64b64c0f2f5f4c0012345671";
  const response = await fetch(
    `https://api.fitsociety.io/public/v1/coaches/${coachId}`,
    {
      headers: {
        Authorization: `Bearer ${process.env.FITSOCIETY_ACCESS_TOKEN}`,
      },
    },
  );

  const body = await response.json();
  console.log(body.data.coach);
  ```

  ```python Python theme={null}
  import os
  import requests

  coach_id = "64b64c0f2f5f4c0012345671"
  response = requests.get(
      f"https://api.fitsociety.io/public/v1/coaches/{coach_id}",
      headers={"Authorization": f"Bearer {os.environ['FITSOCIETY_ACCESS_TOKEN']}"},
  )
  response.raise_for_status()

  body = response.json()
  print(body["data"]["coach"])
  ```
</CodeGroup>

Response:

```json theme={null}
{
  "data": {
    "coach": {
      "_id": "64b64c0f2f5f4c0012345671",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john@example.com",
      "role": "Coach",
      "language": "nl",
      "trainerStatus": true,
      "image": null,
      "lastActive": "2026-08-22T14:05:00.000Z",
      "online": false
    }
  },
  "meta": {
    "requestId": "req_0123456789abcdef",
    "rateLimit": { "limit": 10, "remaining": 8, "resetSeconds": 1 }
  }
}
```

## Coach output fields

List response fields:

| Field                       | Type          | Nullable | Description                                                   |
| :-------------------------- | :------------ | :------- | :------------------------------------------------------------ |
| `data.page`                 | integer       | no       | Current page.                                                 |
| `data.limit`                | integer       | no       | Page size after cap, maximum `500`.                           |
| `data.total`                | integer       | no       | Total matching coaches.                                       |
| `data.totalPages`           | integer       | no       | Total pages.                                                  |
| `data.hasNextPage`          | boolean       | no       | Next page availability.                                       |
| `data.hasPrevPage`          | boolean       | no       | Previous page availability.                                   |
| `data.data[]._id`           | string        | no       | Coach ID.                                                     |
| `data.data[].firstName`     | string        | no       | First name.                                                   |
| `data.data[].lastName`      | string        | no       | Last name.                                                    |
| `data.data[].email`         | string        | no       | Coach email.                                                  |
| `data.data[].role`          | string        | no       | `Coach`, `Manager`, or `Admin`.                               |
| `data.data[].language`      | string        | no       | Coach language.                                               |
| `data.data[].trainerStatus` | boolean       | no       | Trainer active flag.                                          |
| `data.data[].image`         | string/object | yes      | Stored profile image metadata as returned by the coach model. |
| `data.data[].lastActive`    | string        | yes      | Last active timestamp.                                        |
| `data.data[].online`        | boolean       | yes      | Online flag.                                                  |

Detail response fields:

| Field                      | Type          | Nullable | Description                                                   |
| :------------------------- | :------------ | :------- | :------------------------------------------------------------ |
| `data.coach._id`           | string        | no       | Coach ID.                                                     |
| `data.coach.firstName`     | string        | no       | First name.                                                   |
| `data.coach.lastName`      | string        | no       | Last name.                                                    |
| `data.coach.email`         | string        | no       | Coach email.                                                  |
| `data.coach.role`          | string        | no       | `Coach`, `Manager`, or `Admin`.                               |
| `data.coach.language`      | string        | no       | Coach language.                                               |
| `data.coach.trainerStatus` | boolean       | no       | Trainer active flag.                                          |
| `data.coach.image`         | string/object | yes      | Stored profile image metadata as returned by the coach model. |
| `data.coach.lastActive`    | string        | yes      | Last active timestamp.                                        |
| `data.coach.online`        | boolean       | yes      | Online flag.                                                  |

Coach responses are company-scoped and do not return password/auth state,
device tokens, refresh tokens, private permissions internals, phone numbers,
address fields, payout data, or notification preferences.
