Class-templates API
Auto-generated from the OpenAPI spec. Run
node docs-site/scripts/fetch-openapi.jsto regenerate.
GET /api/v1/class-templates
List Templates
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
include_inactive | query | No | boolean | |
status | query | No | "active" | "inactive" | "all". Takes precedence over include_inactive when provided — "inactive" is evaluated fully server-side, so the response's total/pagination reflect the filtered count rather than the broad set. Omit to keep today's include_inactive-only behavior. | |
removed | query | No | boolean | Default false excludes removed class types. true shows only removed class types (the "Removed" tab), regardless of include_inactive. |
page | query | No | integer | |
page_size | query | No | integer |
Responses
- 200 — Successful Response
- 422 — Validation Error
POST /api/v1/class-templates
Create Template
Request body
| Field | Required | Type | Description |
|---|---|---|---|
name | Yes | string | |
description | No | string | |
duration_minutes | No | integer | |
default_capacity | No | integer | |
default_instructor_id | No | integer | |
color | No | string | |
credits_cost | No | integer | |
cancellation_window_hours | No | integer | |
booking_open_hours_before | No | integer | |
booking_close_hours_before | No | integer | |
required_tag_id | No | integer | Restricts this template to clients carrying a specific tag (PRODUCT_SPEC.md §4.1a). Must reference a tags row or this returns 422. New scheduled classes created from this template inherit it by default. |
Responses
- 201 — Successful Response
- 422 — Validation Error, or
required_tag_iddoes not reference an existing tag.
The response also includes required_tag_id, required_tag_name, and required_tag_color
(denormalized from the tag, null when unset) — not shown above because they're response-only
fields fetch-openapi.js doesn't distinguish from request fields on this endpoint's schema.
GET /api/v1/class-templates/public
List Templates Public
Minimal class-template picker for ANY authenticated role (client or
instructor, not just staff) — e.g. the mobile app's classes/bookings/
appointments class-type filter. Deliberately separate from the
staff-only GET /api/v1/class-templates above (gated by
get_current_user, which rejects a client token with 403) rather than
widening that endpoint's auth: this route is intentionally narrow —
active, non-removed templates only, id+name only, no search/pagination/
include_inactive params.
Route-ordering: this MUST be registered before GET /{template_id}
below, for the same reason as GET /instructors/public in
app/routers/instructors.py — /{template_id}'s path parameter has no
explicit :int converter in the path string, so Starlette's generic
any-segment string converter would match the literal "public" segment
first (then fail int coercion with a 422, never reaching this route) if
that route were registered earlier in the file.
Responses
- 200 — Successful Response
GET /api/v1/class-templates/{template_id}
Get Template
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
template_id | path | Yes | integer |
Responses
- 200 — Successful Response
- 422 — Validation Error
PUT /api/v1/class-templates/{template_id}
Update Template
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
template_id | path | Yes | integer |
Request body
| Field | Required | Type | Description |
|---|---|---|---|
name | No | string | |
description | No | string | |
duration_minutes | No | integer | |
default_capacity | No | integer | |
default_instructor_id | No | integer | |
color | No | string | |
is_active | No | boolean | |
credits_cost | No | integer | |
cancellation_window_hours | No | integer | |
booking_open_hours_before | No | integer | |
booking_close_hours_before | No | integer | |
required_tag_id | No | integer | Set, change, or clear the template's tag restriction. Send explicit null to clear it; omit the field to leave it unchanged. Must reference a tags row or this returns 422. |
Responses
- 200 — Successful Response
- 422 — Validation Error, or
required_tag_iddoes not reference an existing tag.
DELETE /api/v1/class-templates/{template_id}
Deactivate Template
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
template_id | path | Yes | integer |
Responses
- 200 — Successful Response
- 422 — Validation Error
DELETE /api/v1/class-templates/{template_id}/remove
Remove Template
Soft-delete a class template. Never blocked by historical bookings.
Removed templates are hidden from the default/active list but remain in
the DB (visible via GET ?removed=true) and can be restored via
PATCH /restore. Existing ScheduledClass/Booking rows referencing this
template keep resolving correctly forever, since the row is never
deleted.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
template_id | path | Yes | integer |
Responses
- 204 — Successful Response
- 409
CLASS_TEMPLATE_ALREADY_REMOVED— This class type has already been removed. - 422 — Validation Error
PATCH /api/v1/class-templates/{template_id}/restore
Restore Template
Clears removed_at, moving the class type back out of the "Removed" tab
and into the normal active/inactive lists.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
template_id | path | Yes | integer |
Responses
- 200 — Successful Response
- 409
CLASS_TEMPLATE_NOT_REMOVED— This class type has not been removed. - 422 — Validation Error