# Trainerize API

> Every Trainerize endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/trainerize

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

14 endpoints for Trainerize. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/trainerize`
- Connects with: Your Trainerize trainer, admin or owner account on the web
- Integration page: https://cotlet.dev/integrations/trainerize-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_clients` | read | Clients with client type, trainer, tags and last activity. |
| `get_client` | read | Client profile: contact, client type, trainer, tags, goals, and main and add-on programs. |
| `get_body_stats` | read | Body weight, body fat, body measurements and caliper entries for a date range. |
| `list_check_ins` | read | Check-in forms a client submitted, with each question and answer. |
| `list_conversations` | read | Your message conversations with clients and groups, newest first, with unread count. |
| `get_conversation` | read | Messages in one conversation, with sender, time and attachment names. |
| `list_master_programs` | read | Master programs in your library, with program tags and subscriber count. |
| `list_appointments` | read | Appointments on the schedule for a date range, with type, trainer and client. |
| `send_message` | write | Send a message to a client as you in the Trainerize messenger. |
| `subscribe_to_program` | write | Subscribe one or more clients to a master program from a start date. |
| `log_body_stats` | write | Enter body stats for a client on a date, in the client's units. |
| `schedule_appointment` | write | Book an appointment with a client, optionally weekly or monthly. |
| `add_client_tags` | write | Add custom client tags to one or more clients. |
| `set_client_status` | write | Deactivate a client (they lose app access, history is kept) or reactivate them. |

## List clients

`POST https://cotlet.dev/api/v1/trainerize/list_clients`

Access: read.

Lists the clients you can see, in the order Trainerize shows them. Deactivated clients are left out unless you ask for them with client_type. Filter by tag to get a group, or search by name or email. Pages hold up to 200 clients; pass next_cursor back as cursor for the next page.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_type` | enum | no | full_access, offline, basic, prospect, pending or deactivated. Default: all except deactivated. |
| `tag` | string | no | Only clients with this custom or auto client tag. |
| `search` | string | no | Match on name or email. |
| `limit` | integer | no | 1 to 200. Default: 50. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/list_clients \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("trainerize", "list_clients")
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'list_clients');
```

**CLI**

```bash
cotlet call trainerize list_clients
```

### Example response

```json
{
  "clients": [
    {
      "client_id": "4821937",
      "name": "Alex Rivera",
      "email": "alex@example.com",
      "client_type": "full_access",
      "trainer": "yourname",
      "tags": [
        "Challenge"
      ],
      "last_active": "2026-10-08T17:40:00Z"
    },
    {
      "client_id": "4821944",
      "name": "Sam Carter",
      "email": "sam@example.com",
      "client_type": "full_access",
      "trainer": "yourname",
      "tags": [
        "Challenge",
        "Online"
      ],
      "last_active": "2026-10-09T06:12:00Z"
    }
  ],
  "next_cursor": null
}
```

## Get client

`POST https://cotlet.dev/api/v1/trainerize/get_client`

Access: read.

Returns one client profile with contact details, client type, trainer, tags, goals and the main and add-on programs the client is on. Use it before a message or a program change to see where the client stands.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/get_client \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2"}'
```

**Python**

```python
result = client.call("trainerize", "get_client", {"client_id":"client_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'get_client', {"client_id":"client_8c41d2"});
```

**CLI**

```bash
cotlet call trainerize get_client --data '{"client_id":"client_8c41d2"}'
```

### Example response

```json
{
  "client_id": "4821937",
  "name": "Alex Rivera",
  "email": "alex@example.com",
  "client_type": "full_access",
  "trainer": "yourname",
  "tags": [
    "Challenge"
  ],
  "goals": [
    "Lose 5 kg",
    "Run 5 km"
  ],
  "main_program": {
    "program_id": "552012",
    "name": "4-week Base"
  },
  "add_on_programs": []
}
```

## Get body stats

`POST https://cotlet.dev/api/v1/trainerize/get_body_stats`

Access: read.

Returns the entries a client logged in the range, oldest first, grouped by date. Default range is the last 90 days.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |
| `from` | date | no | Start date. Default: 90 days ago. |
| `to` | date | no | End date. Default: today. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/get_body_stats \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"4821937","from":"2026-08-17","to":"2026-10-12"}'
```

**Python**

```python
result = client.call("trainerize", "get_body_stats", {"client_id":"4821937","from":"2026-08-17","to":"2026-10-12"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'get_body_stats', {"client_id":"4821937","from":"2026-08-17","to":"2026-10-12"});
```

**CLI**

```bash
cotlet call trainerize get_body_stats --data '{"client_id":"4821937","from":"2026-08-17","to":"2026-10-12"}'
```

### Example response

```json
{
  "client_id": "4821937",
  "entries": [
    {
      "date": "2026-09-12",
      "body_weight": 84.1,
      "waist": 90
    },
    {
      "date": "2026-09-26",
      "body_weight": 83.2,
      "waist": 89
    }
  ]
}
```

## List check-ins

`POST https://cotlet.dev/api/v1/trainerize/list_check_ins`

Access: read.

Lists submitted check-in forms, newest first, each with every question and the answer. Leave client_id empty to read all clients. Use since to read only what is new since your last run.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | no | One client. Default: all clients. |
| `since` | date | no | Only check-ins submitted on or after this date. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/list_check_ins \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"since":"2026-10-05"}'
```

**Python**

```python
result = client.call("trainerize", "list_check_ins", {"since":"2026-10-05"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'list_check_ins', {"since":"2026-10-05"});
```

**CLI**

```bash
cotlet call trainerize list_check_ins --data '{"since":"2026-10-05"}'
```

### Example response

```json
{
  "check_ins": [
    {
      "check_in_id": "7710342",
      "client_id": "4821937",
      "client_name": "Alex Rivera",
      "submitted_at": "2026-10-06T08:15:00Z",
      "answers": [
        {
          "question": "How is your energy this week?",
          "answer": "2 out of 5"
        },
        {
          "question": "Anything getting in the way?",
          "answer": "Two late shifts, skipped Thursday."
        }
      ]
    }
  ]
}
```

## List conversations

`POST https://cotlet.dev/api/v1/trainerize/list_conversations`

Access: read.

Lists your conversations in the Trainerize messenger, newest first, with the other person or group, unread count and a preview of the last message. Set unread_only to see only what needs an answer.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `unread_only` | boolean | no | Only conversations with unread messages. |
| `limit` | integer | no | 1 to 100. Default: 30. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/list_conversations \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("trainerize", "list_conversations")
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'list_conversations');
```

**CLI**

```bash
cotlet call trainerize list_conversations
```

### Example response

```json
{
  "conversations": [
    {
      "conversation_id": "3390127",
      "with": {
        "client_id": "4821937",
        "name": "Alex Rivera"
      },
      "unread": 1,
      "last_message": "Can I swap lunges for something easier on my knee?",
      "updated_at": "2026-10-10T07:02:00Z"
    }
  ]
}
```

## Get conversation

`POST https://cotlet.dev/api/v1/trainerize/get_conversation`

Access: read.

Returns the most recent messages of one conversation, oldest first, so your agent reads the thread in order. Attachments are listed by file name only.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `conversation_id` | string | yes | Conversation ID from list_conversations. |
| `limit` | integer | no | Most recent messages, 1 to 200. Default: 50. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/get_conversation \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"conversation_id":"3390127","limit":30}'
```

**Python**

```python
result = client.call("trainerize", "get_conversation", {"conversation_id":"3390127","limit":30})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'get_conversation', {"conversation_id":"3390127","limit":30});
```

**CLI**

```bash
cotlet call trainerize get_conversation --data '{"conversation_id":"3390127","limit":30}'
```

### Example response

```json
{
  "conversation_id": "3390127",
  "messages": [
    {
      "from": "Alex Rivera",
      "body": "Can I swap lunges for something easier on my knee?",
      "sent_at": "2026-10-10T07:02:00Z",
      "attachments": []
    }
  ]
}
```

## List master programs

`POST https://cotlet.dev/api/v1/trainerize/list_master_programs`

Access: read.

Lists the master programs in your library, with tags and how many clients are subscribed. Use the program_id with subscribe_to_program.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Match on program name. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/list_master_programs \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("trainerize", "list_master_programs")
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'list_master_programs');
```

**CLI**

```bash
cotlet call trainerize list_master_programs
```

### Example response

```json
{
  "programs": [
    {
      "program_id": "552031",
      "name": "6-week Shred",
      "tags": [
        "fat loss"
      ],
      "subscribers": 14
    },
    {
      "program_id": "552012",
      "name": "4-week Base",
      "tags": [
        "beginner"
      ],
      "subscribers": 31
    }
  ]
}
```

## List appointments

`POST https://cotlet.dev/api/v1/trainerize/list_appointments`

Access: read.

Lists appointments in the range, earliest first, with type, trainer and client. Admins and managers can read another trainer's schedule with trainer_id; other roles see their own.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `from` | date | yes | Start date. |
| `to` | date | yes | End date. |
| `trainer_id` | string | no | Admins and managers: another trainer. Default: you. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/list_appointments \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"2026-10-01","to":"2026-10-01"}'
```

**Python**

```python
result = client.call("trainerize", "list_appointments", {"from":"2026-10-01","to":"2026-10-01"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'list_appointments', {"from":"2026-10-01","to":"2026-10-01"});
```

**CLI**

```bash
cotlet call trainerize list_appointments --data '{"from":"2026-10-01","to":"2026-10-01"}'
```

### Example response

```json
{
  "appointments": [
    {
      "appointment_id": "90311102",
      "client_id": "4821944",
      "appointment_type": "1-on-1 Appointment",
      "start": "2026-10-13T08:00:00-04:00",
      "end": "2026-10-13T09:00:00-04:00",
      "trainer": "yourname"
    }
  ]
}
```

## Send message

`POST https://cotlet.dev/api/v1/trainerize/send_message`

Access: write. Confirm: waits for the user's OK before it runs.

Sends a message to one client in the Trainerize messenger under your name. The client sees it in the app. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |
| `body` | string | yes | Message text. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/send_message \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","body":"body"}'
```

**Python**

```python
result = client.call("trainerize", "send_message", {"client_id":"client_8c41d2","body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'send_message', {"client_id":"client_8c41d2","body":"body"});
```

**CLI**

```bash
cotlet call trainerize send_message --data '{"client_id":"client_8c41d2","body":"body"}'
```

### Example response

```json
{
  "conversation_id": "3390127",
  "message_id": "88120045",
  "status": "sent",
  "sent_at": "2026-10-10T09:05:00-04:00"
}
```

## Subscribe to program

`POST https://cotlet.dev/api/v1/trainerize/subscribe_to_program`

Access: write. Confirm: waits for the user's OK before it runs.

Subscribes the clients to a master program as their main program or as an add-on, starting on the date you give. The program appears in each client's app. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `program_id` | string | yes | Program ID from list_master_programs. |
| `client_ids` | string[] | yes | Clients to subscribe. |
| `start_date` | date | yes | First day of the program. |
| `program_type` | enum | no | main or add_on. Default: main. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/subscribe_to_program \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"program_id":"552047","client_ids":["4821937","4821944"],"start_date":"2026-10-19","program_type":"main"}'
```

**Python**

```python
result = client.call("trainerize", "subscribe_to_program", {"program_id":"552047","client_ids":["4821937","4821944"],"start_date":"2026-10-19","program_type":"main"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'subscribe_to_program', {"program_id":"552047","client_ids":["4821937","4821944"],"start_date":"2026-10-19","program_type":"main"});
```

**CLI**

```bash
cotlet call trainerize subscribe_to_program --data '{"program_id":"552047","client_ids":["4821937","4821944"],"start_date":"2026-10-19","program_type":"main"}'
```

### Example response

```json
{
  "program_id": "552031",
  "program_type": "main",
  "start_date": "2026-10-19",
  "subscribed": [
    {
      "client_id": "4821937",
      "status": "subscribed"
    },
    {
      "client_id": "4821944",
      "status": "subscribed"
    }
  ]
}
```

## Log body stats

`POST https://cotlet.dev/api/v1/trainerize/log_body_stats`

Access: write. Confirm: waits for the user's OK before it runs.

Enters body stats for one client on one date, in the client's units. The entry shows in the client's progress. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |
| `date` | date | yes | Day of the measurement. |
| `stats` | object | yes | Any of body_weight, body_fat_percent, waist, hips, chest, neck and other body measurements. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/log_body_stats \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","date":"2026-10-01","stats":"stats"}'
```

**Python**

```python
result = client.call("trainerize", "log_body_stats", {"client_id":"client_8c41d2","date":"2026-10-01","stats":"stats"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'log_body_stats', {"client_id":"client_8c41d2","date":"2026-10-01","stats":"stats"});
```

**CLI**

```bash
cotlet call trainerize log_body_stats --data '{"client_id":"client_8c41d2","date":"2026-10-01","stats":"stats"}'
```

### Example response

```json
{
  "client_id": "4821937",
  "date": "2026-10-10",
  "status": "logged",
  "stats": {
    "body_weight": 82.4,
    "waist": 88
  }
}
```

## Schedule appointment

`POST https://cotlet.dev/api/v1/trainerize/schedule_appointment`

Access: write. Confirm: waits for the user's OK before it runs.

Books an appointment of the type you name, with the client, at the start time you give. A weekly or monthly repeat creates one appointment per date up to repeat_until. Notes are visible to the client. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |
| `appointment_type` | string | yes | Appointment type name, e.g. 1-on-1 Appointment. |
| `start` | datetime | yes | ISO 8601 with time zone. |
| `repeat` | enum | no | none, weekly or monthly. Default: none. |
| `repeat_until` | date | no | Last date of a repeating appointment. |
| `notes` | string | no | Appointment notes. The client can see them. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/schedule_appointment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"4821937","appointment_type":"1-on-1 Appointment","start":"2026-10-13T07:00:00-04:00","repeat":"weekly","repeat_until":"2026-11-10"}'
```

**Python**

```python
result = client.call("trainerize", "schedule_appointment", {"client_id":"4821937","appointment_type":"1-on-1 Appointment","start":"2026-10-13T07:00:00-04:00","repeat":"weekly","repeat_until":"2026-11-10"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'schedule_appointment', {"client_id":"4821937","appointment_type":"1-on-1 Appointment","start":"2026-10-13T07:00:00-04:00","repeat":"weekly","repeat_until":"2026-11-10"});
```

**CLI**

```bash
cotlet call trainerize schedule_appointment --data '{"client_id":"4821937","appointment_type":"1-on-1 Appointment","start":"2026-10-13T07:00:00-04:00","repeat":"weekly","repeat_until":"2026-11-10"}'
```

### Example response

```json
{
  "appointment_id": "90311284",
  "client_id": "4821937",
  "appointment_type": "1-on-1 Appointment",
  "start": "2026-10-13T07:00:00-04:00",
  "end": "2026-10-13T08:00:00-04:00",
  "repeat": "weekly",
  "occurrences": 5,
  "trainer": "yourname"
}
```

## Add client tags

`POST https://cotlet.dev/api/v1/trainerize/add_client_tags`

Access: write. Confirm: waits for the user's OK before it runs.

Adds existing custom client tags to the clients. Tags group clients for list_clients and for your own filters in Trainerize. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_ids` | string[] | yes | Clients to tag. |
| `tags` | string[] | yes | Existing custom client tag names. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/add_client_tags \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_ids":["client ids"],"tags":["tags"]}'
```

**Python**

```python
result = client.call("trainerize", "add_client_tags", {"client_ids":["client ids"],"tags":["tags"]})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'add_client_tags', {"client_ids":["client ids"],"tags":["tags"]});
```

**CLI**

```bash
cotlet call trainerize add_client_tags --data '{"client_ids":["client ids"],"tags":["tags"]}'
```

### Example response

```json
{
  "tags": [
    "Challenge"
  ],
  "tagged": [
    "4821937",
    "4821944"
  ],
  "status": "tagged"
}
```

## Set client status

`POST https://cotlet.dev/api/v1/trainerize/set_client_status`

Access: write. Confirm: waits for the user's OK before it runs.

Deactivates a client, who then loses access to the app while the history is kept, or reactivates a deactivated one. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `client_id` | string | yes | Client ID from list_clients. |
| `status` | enum | yes | deactivated or active. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/trainerize/set_client_status \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"client_id":"client_8c41d2","status":"deactivated"}'
```

**Python**

```python
result = client.call("trainerize", "set_client_status", {"client_id":"client_8c41d2","status":"deactivated"})
```

**Node.js**

```js
const result = await cotlet.call('trainerize', 'set_client_status', {"client_id":"client_8c41d2","status":"deactivated"});
```

**CLI**

```bash
cotlet call trainerize set_client_status --data '{"client_id":"client_8c41d2","status":"deactivated"}'
```

### Example response

```json
{
  "client_id": "4821944",
  "status": "deactivated"
}
```
