curl --request PATCH \
--url https://api.1club.ai/v1/platform/instructors/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"clubId": 123,
"instructorTypeId": 123,
"sports": [
"<string>"
],
"displayName": "<string>",
"hourlyRate": 1,
"priceIncludesArea": true,
"maxConcurrentBookings": 2,
"operatingHours": {},
"isActive": true
}
'import requests
url = "https://api.1club.ai/v1/platform/instructors/{id}"
payload = {
"clubId": 123,
"instructorTypeId": 123,
"sports": ["<string>"],
"displayName": "<string>",
"hourlyRate": 1,
"priceIncludesArea": True,
"maxConcurrentBookings": 2,
"operatingHours": {},
"isActive": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
clubId: 123,
instructorTypeId: 123,
sports: ['<string>'],
displayName: '<string>',
hourlyRate: 1,
priceIncludesArea: true,
maxConcurrentBookings: 2,
operatingHours: {},
isActive: true
})
};
fetch('https://api.1club.ai/v1/platform/instructors/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.1club.ai/v1/platform/instructors/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'clubId' => 123,
'instructorTypeId' => 123,
'sports' => [
'<string>'
],
'displayName' => '<string>',
'hourlyRate' => 1,
'priceIncludesArea' => true,
'maxConcurrentBookings' => 2,
'operatingHours' => [
],
'isActive' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.1club.ai/v1/platform/instructors/{id}"
payload := strings.NewReader("{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.1club.ai/v1/platform/instructors/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/instructors/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"clubId": 123,
"instructorTypeId": 123,
"sports": [
"<string>"
],
"hourlyRate": 123,
"priceIncludesArea": true,
"bookability": "Admin_only",
"isBookable": true,
"maxConcurrentBookings": 123,
"operatingHours": {},
"visibility": "Private",
"isActive": true
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Update an instructor
Edits an instructor’s bookable profile - their sports, their member-facing rate, their availability, who may book them. Send only what changes; an omitted field is left alone.
Retire a coach with isActive: false and bring them back with isActive: true; there is no delete, because an instructor carries bookings, classes and pay history. Two invariants are applied on the way through, so read the response rather than assuming the payload landed verbatim: deactivating always retires bookability to Admin_only, and bookability never outruns visibility - making someone Private pulls a Public bookability down with it.
contactId is not editable: the profile is bound to one person, and re-pointing it would silently transfer their bookings and their pay. The staff-portal fields are refused here for the same reasons as on the create.
curl --request PATCH \
--url https://api.1club.ai/v1/platform/instructors/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"clubId": 123,
"instructorTypeId": 123,
"sports": [
"<string>"
],
"displayName": "<string>",
"hourlyRate": 1,
"priceIncludesArea": true,
"maxConcurrentBookings": 2,
"operatingHours": {},
"isActive": true
}
'import requests
url = "https://api.1club.ai/v1/platform/instructors/{id}"
payload = {
"clubId": 123,
"instructorTypeId": 123,
"sports": ["<string>"],
"displayName": "<string>",
"hourlyRate": 1,
"priceIncludesArea": True,
"maxConcurrentBookings": 2,
"operatingHours": {},
"isActive": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
clubId: 123,
instructorTypeId: 123,
sports: ['<string>'],
displayName: '<string>',
hourlyRate: 1,
priceIncludesArea: true,
maxConcurrentBookings: 2,
operatingHours: {},
isActive: true
})
};
fetch('https://api.1club.ai/v1/platform/instructors/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.1club.ai/v1/platform/instructors/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'clubId' => 123,
'instructorTypeId' => 123,
'sports' => [
'<string>'
],
'displayName' => '<string>',
'hourlyRate' => 1,
'priceIncludesArea' => true,
'maxConcurrentBookings' => 2,
'operatingHours' => [
],
'isActive' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.1club.ai/v1/platform/instructors/{id}"
payload := strings.NewReader("{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.1club.ai/v1/platform/instructors/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/instructors/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"clubId\": 123,\n \"instructorTypeId\": 123,\n \"sports\": [\n \"<string>\"\n ],\n \"displayName\": \"<string>\",\n \"hourlyRate\": 1,\n \"priceIncludesArea\": true,\n \"maxConcurrentBookings\": 2,\n \"operatingHours\": {},\n \"isActive\": true\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"clubId": 123,
"instructorTypeId": 123,
"sports": [
"<string>"
],
"hourlyRate": 123,
"priceIncludesArea": true,
"bookability": "Admin_only",
"isBookable": true,
"maxConcurrentBookings": 123,
"operatingHours": {},
"visibility": "Private",
"isActive": true
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Authorizations
Organization-scoped bearer credential: a customer API key (1club_sk_live_...) or an MCP OAuth access token.
Path Parameters
1club instructor id
Body
Fields accepted when updating an instructor. Send only what changes; an omitted field is left alone. At least one field is required, and unknown fields are rejected. contactId is absent on purpose: re-pointing a profile at another person would transfer their bookings and pay.
Club the instructor works at; null means every club in the organization.
The kind of coach, from GET /v1/platform/instructor-types. null leaves them unfiled, which is legal but loses the grouping every roster view reads from and the default revenue account their sessions would post to.
50Public-facing name. Defaults to " ." from the contact.
120What a member pays for an hour of one-to-one time with them. Not what the club pays the coach - that is a pay rate policy. Added to the area price unless priceIncludesArea is true.
x >= 0Who may book one-to-one sessions with them. Never outruns visibility: narrowing one pulls the other down with it, and deactivating the instructor retires this to Admin_only. The read-only isBookable is derived from this and cannot be written.
Admin_only, Member_only, Public When true, hourlyRate already covers the booked area, which is then not charged on top.
x >= 1Per-day-of-week availability schedule
Private, Member_only, Public False retires the instructor: they leave the listings and stop being bookable, and their history is kept. There is no delete.
Response
The updated instructor
An instructor (coach) in the organization, as returned by the instructors resource. Reference the id as instructorId when creating a booking. Leaner than the PlatformInstructor profile embedded in class payloads: this carries only what is needed to pick and price a coach.
Public display name when set, otherwise the linked contact name.
Club the instructor belongs to; null when org-wide.
The kind of coach, from GET /v1/platform/instructor-types; null for one nobody has filed.
Added to the area price when pricing a booking with this instructor, unless priceIncludesArea is true.
When true, hourlyRate is an all-in price that already covers the booked area - the area's price is not added on top of it.
Who may book one-to-one sessions with this instructor. Admin_only means the club reserves those bookings to its own staff, so a customer-initiated booking is rejected; an API key acts for the organization and may still create one.
Admin_only, Member_only, Public Derived from bookability: true unless it is Admin_only. Prefer bookability, which distinguishes members from the public.
Per-day-of-week availability schedule
Who may see the instructor on member-facing surfaces. bookability never outruns it.
Private, Member_only, Public False for a retired instructor: hidden from the list by default, not bookable, history kept.
Was this page helpful?