# PushPress API

> Every PushPress 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/pushpress

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 PushPress. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/pushpress`
- Connects with: Your PushPress Core staff account (admin for plan changes and the No Show / Late Cancel report)
- Integration page: https://cotlet.dev/integrations/pushpress-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_members` | read | People in your gym with their plans and plan status. |
| `get_member` | read | Profile, plans with status and next bill date, and recent class activity. |
| `list_classes` | read | Classes on the calendar for a date range, with coach and reservation counts. |
| `get_class_roster` | read | Members of one class grouped by status. |
| `list_plan_templates` | read | Plans you sell, with price and whether they are recurring. |
| `list_no_shows_late_cancels` | read | Rows of the No Show / Late Cancel report for a date range. |
| `book_class_reservation` | write | Reserve a spot in a class for a member. |
| `check_in_member` | write | Check a member into a class, with or without a reservation. |
| `remove_reservation` | write | Remove a member's reservation or check-in from a class. |
| `switch_member_plan` | write | Move a member from one recurring plan to another, now or at the next bill date. |
| `pause_member_plan` | write | Pause a member's plan and its billing. |
| `cancel_member_plan` | write | Cancel a member's plan now or on a future date. |
| `message_class_registrants` | write | Email or text the members registered in a class. |
| `cancel_class` | write | Cancel one class, or this and future classes in its series. |

## List members

`POST https://cotlet.dev/api/v1/pushpress/list_members`

Access: read.

Lists people in Core with the status of each plan: Active, Alert, Pending Active, Pending Cancel, Cancelled, Paused or Completed. Alert means a billing issue; class reservations are restricted for that plan. Pages hold up to 100 people; pass next_cursor back as cursor for the next page.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `search` | string | no | Name or email. |
| `plan_status` | enum | no | active, alert, pending_active, pending_cancel, cancelled, paused or completed. |
| `limit` | integer | no | 1 to 100. Default: 50. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

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

**Python**

```python
result = client.call("pushpress", "list_members")
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'list_members');
```

**CLI**

```bash
cotlet call pushpress list_members
```

### Example response

```json
{
  "members": [
    {
      "member_id": "usr_8f2k41",
      "name": "Jordan Reyes",
      "plans": [
        {
          "plan_id": "pln_30917",
          "name": "3x Week",
          "status": "active",
          "next_bill_date": "2026-11-01"
        }
      ]
    },
    {
      "member_id": "usr_2c77d9",
      "name": "Alex Kim",
      "plans": [
        {
          "plan_id": "pln_30455",
          "name": "Unlimited",
          "status": "alert",
          "next_bill_date": "2026-10-15"
        }
      ]
    }
  ],
  "next_cursor": null
}
```

## Get member

`POST https://cotlet.dev/api/v1/pushpress/get_member`

Access: read.

Returns one profile with contact details, every plan with its status, next bill date and the Plan ID other tools need, and recent reservations and check-ins. Call it before switching, pausing or cancelling a plan.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `member_id` | string | yes | Member ID from list_members. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/get_member \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"member_id":"member_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "get_member", {"member_id":"member_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'get_member', {"member_id":"member_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress get_member --data '{"member_id":"member_8c41d2"}'
```

### Example response

```json
{
  "member_id": "usr_8f2k41",
  "name": "Jordan Reyes",
  "email": "jordan@example.com",
  "plans": [
    {
      "plan_id": "pln_30917",
      "name": "3x Week",
      "status": "active",
      "recurring": true,
      "next_bill_date": "2026-11-01"
    }
  ],
  "recent_activity": [
    {
      "class_id": "cls_5101",
      "class_name": "CrossFit 7:00",
      "status": "checked_in",
      "date": "2026-10-09"
    }
  ]
}
```

## List classes

`POST https://cotlet.dev/api/v1/pushpress/list_classes`

Access: read.

Lists classes on the calendar between two dates, in start order. Each item has the Class ID other tools need, the coach and how many members are reserved or waitlisted. Cancelled classes are not returned.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `from` | date | yes | First day. |
| `to` | date | no | Last day. Default: same as from. |

### Request

**cURL**

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

**Python**

```python
result = client.call("pushpress", "list_classes", {"from":"2026-10-01"})
```

**Node.js**

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

**CLI**

```bash
cotlet call pushpress list_classes --data '{"from":"2026-10-01"}'
```

### Example response

```json
{
  "classes": [
    {
      "class_id": "cls_5101",
      "name": "CrossFit 7:00",
      "starts_at": "2026-10-12T07:00:00-04:00",
      "coach": "Dana",
      "reserved": 11,
      "waitlist": 0
    },
    {
      "class_id": "cls_5120",
      "name": "CrossFit 9:00",
      "starts_at": "2026-10-17T09:00:00-04:00",
      "coach": "Dana",
      "reserved": 3,
      "waitlist": 1
    }
  ]
}
```

## Get class roster

`POST https://cotlet.dev/api/v1/pushpress/get_class_roster`

Access: read.

Returns everyone on one class card with the same statuses Core shows: Checked In, Reserved, Waitlist, Late Cancel and No Show. A Waitlist member moves to Reserved if a spot opens.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/get_class_roster \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"class_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "get_class_roster", {"class_id":"class_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'get_class_roster', {"class_id":"class_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress get_class_roster --data '{"class_id":"class_8c41d2"}'
```

### Example response

```json
{
  "class_id": "cls_5120",
  "name": "CrossFit 9:00",
  "members": [
    {
      "member_id": "usr_8f2k41",
      "name": "Jordan Reyes",
      "status": "reserved"
    },
    {
      "member_id": "usr_2c77d9",
      "name": "Alex Kim",
      "status": "reserved"
    },
    {
      "member_id": "usr_91ab03",
      "name": "Sam Ortiz",
      "status": "reserved"
    },
    {
      "member_id": "usr_44de18",
      "name": "Priya Nair",
      "status": "waitlist"
    }
  ]
}
```

## List plan templates

`POST https://cotlet.dev/api/v1/pushpress/list_plan_templates`

Access: read.

Lists the plans you can put a member on, with price and whether each is recurring. Use the template ID as new_plan_template_id in switch_member_plan, which works only with recurring plans.

### Parameters

No parameters.

### Request

**cURL**

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

**Python**

```python
result = client.call("pushpress", "list_plan_templates")
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'list_plan_templates');
```

**CLI**

```bash
cotlet call pushpress list_plan_templates
```

### Example response

```json
{
  "plan_templates": [
    {
      "template_id": "tpl_3x",
      "name": "3x Week",
      "recurring": true,
      "price": "149.00 USD / month"
    },
    {
      "template_id": "tpl_unlimited",
      "name": "Unlimited",
      "recurring": true,
      "price": "189.00 USD / month"
    }
  ]
}
```

## List no-shows and late cancels

`POST https://cotlet.dev/api/v1/pushpress/list_no_shows_late_cancels`

Access: read.

Returns the members who missed a class (No Show) or cancelled inside the late cancel window (Late Cancel). PushPress updates the report within 24 to 48 hours after check-ins or deletions, so recent classes may be incomplete. Fees are not charged automatically.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `from` | date | yes | First day. |
| `to` | date | yes | Last day. |
| `type` | enum | no | no_show, late_cancel or all. Default: all. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/list_no_shows_late_cancels \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"from":"2026-10-05","to":"2026-10-11","type":"all"}'
```

**Python**

```python
result = client.call("pushpress", "list_no_shows_late_cancels", {"from":"2026-10-05","to":"2026-10-11","type":"all"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'list_no_shows_late_cancels', {"from":"2026-10-05","to":"2026-10-11","type":"all"});
```

**CLI**

```bash
cotlet call pushpress list_no_shows_late_cancels --data '{"from":"2026-10-05","to":"2026-10-11","type":"all"}'
```

### Example response

```json
{
  "rows": [
    {
      "member_id": "usr_91ab03",
      "name": "Sam Ortiz",
      "class_name": "CrossFit 7:00",
      "date": "2026-10-07",
      "type": "no_show"
    },
    {
      "member_id": "usr_2c77d9",
      "name": "Alex Kim",
      "class_name": "CrossFit 9:00",
      "date": "2026-10-08",
      "type": "late_cancel"
    }
  ]
}
```

## Book class reservation

`POST https://cotlet.dev/api/v1/pushpress/book_class_reservation`

Access: write.

Adds a member to a class from the class view in Core. Access rules apply: a plan that does not allow the class blocks the booking. It reaches no one else and remove_reservation undoes it, so it runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |
| `member_id` | string | yes | Member ID from list_members. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/book_class_reservation \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "book_class_reservation", {"class_id":"class_8c41d2","member_id":"member_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'book_class_reservation', {"class_id":"class_8c41d2","member_id":"member_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress book_class_reservation --data '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

### Example response

```json
{
  "class_id": "cls_5120",
  "member_id": "usr_8f2k41",
  "status": "reserved"
}
```

## Check in member

`POST https://cotlet.dev/api/v1/pushpress/check_in_member`

Access: write.

Checks a Reserved member in, or adds a walk-in who has no reservation. It enforces the same access rules as a direct check-in. With override set to true it checks the member in anyway, as staff can in the Control Panel; an override does not charge the member. It reaches no one else and remove_reservation can undo the entry, so it runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |
| `member_id` | string | yes | Member ID from list_members. |
| `override` | boolean | no | Check in even when the member's plan does not allow the class. Default: false. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/check_in_member \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "check_in_member", {"class_id":"class_8c41d2","member_id":"member_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'check_in_member', {"class_id":"class_8c41d2","member_id":"member_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress check_in_member --data '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

### Example response

```json
{
  "class_id": "cls_5101",
  "member_id": "usr_8f2k41",
  "status": "checked_in"
}
```

## Remove reservation

`POST https://cotlet.dev/api/v1/pushpress/remove_reservation`

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

Removes the entry, the same as Remove Reservation or Remove Check-In in Core. PushPress states that removing a reservation does not affect the member's plan or billing. The member loses the spot. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |
| `member_id` | string | yes | Member ID from list_members. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/remove_reservation \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "remove_reservation", {"class_id":"class_8c41d2","member_id":"member_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'remove_reservation', {"class_id":"class_8c41d2","member_id":"member_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress remove_reservation --data '{"class_id":"class_8c41d2","member_id":"member_8c41d2"}'
```

### Example response

```json
{
  "class_id": "cls_5120",
  "member_id": "usr_91ab03",
  "status": "removed"
}
```

## Switch member plan

`POST https://cotlet.dev/api/v1/pushpress/switch_member_plan`

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

Runs Switch Plan from the member profile. With now, the current plan ends at once and prorated fees go on the first bill of the new plan. With next_bill_date, the current plan shows as pending cancel and the new one as pending active. Works only for recurring plans. PushPress emails the admin and the member. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `member_id` | string | yes | Member ID from list_members. |
| `current_plan_id` | string | yes | Plan ID from get_member. |
| `new_plan_template_id` | string | yes | Template ID from list_plan_templates. |
| `when` | enum | yes | now or next_bill_date. |
| `waive_setup_fee` | boolean | no | Set the setup fee to 0. Default: false. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/switch_member_plan \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"member_id":"usr_8f2k41","current_plan_id":"pln_30917","new_plan_template_id":"tpl_unlimited","when":"next_bill_date","waive_setup_fee":true}'
```

**Python**

```python
result = client.call("pushpress", "switch_member_plan", {"member_id":"usr_8f2k41","current_plan_id":"pln_30917","new_plan_template_id":"tpl_unlimited","when":"next_bill_date","waive_setup_fee":True})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'switch_member_plan', {"member_id":"usr_8f2k41","current_plan_id":"pln_30917","new_plan_template_id":"tpl_unlimited","when":"next_bill_date","waive_setup_fee":true});
```

**CLI**

```bash
cotlet call pushpress switch_member_plan --data '{"member_id":"usr_8f2k41","current_plan_id":"pln_30917","new_plan_template_id":"tpl_unlimited","when":"next_bill_date","waive_setup_fee":true}'
```

### Example response

```json
{
  "member_id": "usr_8f2k41",
  "current_plan": {
    "plan_id": "pln_30917",
    "name": "3x Week",
    "status": "pending_cancel",
    "ends_on": "2026-11-01"
  },
  "new_plan": {
    "name": "Unlimited",
    "status": "pending_active",
    "starts_on": "2026-11-01",
    "setup_fee": "0.00 USD"
  },
  "confirmation_email": "sent to member and admin"
}
```

## Pause member plan

`POST https://cotlet.dev/api/v1/pushpress/pause_member_plan`

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

Runs Pause Plan from the member profile. Billing stops while the status is Paused. Leave resume_on empty for an indefinite pause. On resume, unused days from the pause date to the Paid Until Date are credited and the next bill date moves out by that many days. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `member_id` | string | yes | Member ID from list_members. |
| `plan_id` | string | yes | Plan ID from get_member (the member's current plan). |
| `pause_from` | date | yes | First day of the pause. |
| `resume_on` | date | no | Day the plan resumes. Empty means indefinite. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/pause_member_plan \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"member_id":"usr_2c77d9","plan_id":"pln_30455","pause_from":"2026-10-19","resume_on":"2026-11-19"}'
```

**Python**

```python
result = client.call("pushpress", "pause_member_plan", {"member_id":"usr_2c77d9","plan_id":"pln_30455","pause_from":"2026-10-19","resume_on":"2026-11-19"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'pause_member_plan', {"member_id":"usr_2c77d9","plan_id":"pln_30455","pause_from":"2026-10-19","resume_on":"2026-11-19"});
```

**CLI**

```bash
cotlet call pushpress pause_member_plan --data '{"member_id":"usr_2c77d9","plan_id":"pln_30455","pause_from":"2026-10-19","resume_on":"2026-11-19"}'
```

### Example response

```json
{
  "member_id": "usr_2c77d9",
  "plan_id": "pln_30455",
  "status": "paused",
  "paused_from": "2026-10-12",
  "resumes_on": "2026-11-12"
}
```

## Cancel member plan

`POST https://cotlet.dev/api/v1/pushpress/cancel_member_plan`

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

Runs Cancel Plan from the member profile. A date of today sets the status to Cancelled and the member loses access at once. A future date sets Pending Cancel, and the member keeps full access until that date has passed. Setting the date one day before the next bill date helps avoid an extra charge. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `member_id` | string | yes | Member ID from list_members. |
| `plan_id` | string | yes | Plan ID from get_member (the member's current plan). |
| `cancel_on` | date | no | Cancel date. Default: today. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/cancel_member_plan \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"member_id":"member_8c41d2","plan_id":"plan_8c41d2"}'
```

**Python**

```python
result = client.call("pushpress", "cancel_member_plan", {"member_id":"member_8c41d2","plan_id":"plan_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'cancel_member_plan', {"member_id":"member_8c41d2","plan_id":"plan_8c41d2"});
```

**CLI**

```bash
cotlet call pushpress cancel_member_plan --data '{"member_id":"member_8c41d2","plan_id":"plan_8c41d2"}'
```

### Example response

```json
{
  "member_id": "usr_8f2k41",
  "plan_id": "pln_30917",
  "status": "pending_cancel",
  "cancel_on": "2026-10-31"
}
```

## Message class registrants

`POST https://cotlet.dev/api/v1/pushpress/message_class_registrants`

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

Runs Mass Email Registrants from the class menu. It reaches the members currently registered in the class, by email, text or both. Core sends these one class at a time. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |
| `channel` | enum | yes | email, sms or both. |
| `subject` | string | no | Email subject. Used for email and both. |
| `body` | string | yes | Message text. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/message_class_registrants \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"class_8c41d2","channel":"email","body":"body"}'
```

**Python**

```python
result = client.call("pushpress", "message_class_registrants", {"class_id":"class_8c41d2","channel":"email","body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'message_class_registrants', {"class_id":"class_8c41d2","channel":"email","body":"body"});
```

**CLI**

```bash
cotlet call pushpress message_class_registrants --data '{"class_id":"class_8c41d2","channel":"email","body":"body"}'
```

### Example response

```json
{
  "class_id": "cls_5120",
  "channel": "sms",
  "recipients": 4,
  "status": "sent"
}
```

## Cancel class

`POST https://cotlet.dev/api/v1/pushpress/cancel_class`

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

Removes the class from the calendar. PushPress sends no notification, so call message_class_registrants first. Scope is this class only, this class and all future classes on that weekday, or this class and all future classes in the series. Members who were not checked in get their class credits back. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `class_id` | string | yes | Class ID from list_classes. |
| `scope` | enum | yes | this_class, this_and_future_weekday or this_and_future_series. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/pushpress/cancel_class \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"class_id":"cls_5120","scope":"this_class"}'
```

**Python**

```python
result = client.call("pushpress", "cancel_class", {"class_id":"cls_5120","scope":"this_class"})
```

**Node.js**

```js
const result = await cotlet.call('pushpress', 'cancel_class', {"class_id":"cls_5120","scope":"this_class"});
```

**CLI**

```bash
cotlet call pushpress cancel_class --data '{"class_id":"cls_5120","scope":"this_class"}'
```

### Example response

```json
{
  "class_id": "cls_5120",
  "scope": "this_class",
  "status": "cancelled",
  "reservations_released": 3,
  "members_notified": false
}
```
