curl --request PUT \
--url https://api.1club.ai/v1/platform/forms/{id}/questions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"questions": [
{
"label": "<string>",
"required": true,
"id": 123,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": [
"<string>"
],
"contactCustomFieldId": 123,
"translations": {}
}
],
"removeQuestionIds": [
123
]
}
'import requests
url = "https://api.1club.ai/v1/platform/forms/{id}/questions"
payload = {
"questions": [
{
"label": "<string>",
"required": True,
"id": 123,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": ["<string>"],
"contactCustomFieldId": 123,
"translations": {}
}
],
"removeQuestionIds": [123]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
questions: [
{
label: '<string>',
required: true,
id: 123,
placeholder: '<string>',
helpText: '<string>',
sectionHeading: '<string>',
options: ['<string>'],
contactCustomFieldId: 123,
translations: {}
}
],
removeQuestionIds: [123]
})
};
fetch('https://api.1club.ai/v1/platform/forms/{id}/questions', 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/forms/{id}/questions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'questions' => [
[
'label' => '<string>',
'required' => true,
'id' => 123,
'placeholder' => '<string>',
'helpText' => '<string>',
'sectionHeading' => '<string>',
'options' => [
'<string>'
],
'contactCustomFieldId' => 123,
'translations' => [
]
]
],
'removeQuestionIds' => [
123
]
]),
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/forms/{id}/questions"
payload := strings.NewReader("{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.1club.ai/v1/platform/forms/{id}/questions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/forms/{id}/questions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"slug": "<string>",
"createsAccount": true,
"publicUrl": "<string>",
"name": "<string>",
"title": "<string>",
"subtitle": "<string>",
"planStepTitle": "<string>",
"classTypeStepTitle": "<string>",
"planIds": [
123
],
"classTypeIds": [
123
],
"productIds": [
123
],
"registrationFor": "individual",
"signatureMethod": "draw",
"collectsDocuments": true,
"requiresAuthentication": true,
"combineSelectionAndDetails": true,
"displayMode": "page",
"videoUrl": "<string>",
"videoRequired": true,
"videoTitle": "<string>",
"fieldOverrides": {
"firstName": "required",
"lastName": "required",
"email": "required",
"phone": "required",
"dateOfBirth": "required",
"gender": "required",
"address": "required"
},
"translations": {},
"packageIds": [
123
],
"submissionCount": 123,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"questions": [
{
"id": 123,
"label": "<string>",
"type": "text",
"required": true,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": [
"<string>"
],
"contactCustomFieldId": 123,
"translations": {}
}
]
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}Set a fill-in form's questions
Sets the questions of a fill-in form (createsAccount: false), in the order given. The change is live immediately.
Resend every question you are keeping with its id, and list the ones to delete in removeQuestionIds. A question is never deleted by being left out: a list that is missing an existing question is a 400 (FORM_QUESTION_OMITTED) naming it. The ids matter because answers are stored against them, so a question resent without its id is a new question and the answers already given stop being linked to it. Deleting a question keeps past submissions readable with the wording they were asked under.
A sign-up form has no questions of its own (FORM_QUESTIONS_FILL_IN_ONLY).
curl --request PUT \
--url https://api.1club.ai/v1/platform/forms/{id}/questions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"questions": [
{
"label": "<string>",
"required": true,
"id": 123,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": [
"<string>"
],
"contactCustomFieldId": 123,
"translations": {}
}
],
"removeQuestionIds": [
123
]
}
'import requests
url = "https://api.1club.ai/v1/platform/forms/{id}/questions"
payload = {
"questions": [
{
"label": "<string>",
"required": True,
"id": 123,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": ["<string>"],
"contactCustomFieldId": 123,
"translations": {}
}
],
"removeQuestionIds": [123]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
questions: [
{
label: '<string>',
required: true,
id: 123,
placeholder: '<string>',
helpText: '<string>',
sectionHeading: '<string>',
options: ['<string>'],
contactCustomFieldId: 123,
translations: {}
}
],
removeQuestionIds: [123]
})
};
fetch('https://api.1club.ai/v1/platform/forms/{id}/questions', 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/forms/{id}/questions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'questions' => [
[
'label' => '<string>',
'required' => true,
'id' => 123,
'placeholder' => '<string>',
'helpText' => '<string>',
'sectionHeading' => '<string>',
'options' => [
'<string>'
],
'contactCustomFieldId' => 123,
'translations' => [
]
]
],
'removeQuestionIds' => [
123
]
]),
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/forms/{id}/questions"
payload := strings.NewReader("{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.1club.ai/v1/platform/forms/{id}/questions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/forms/{id}/questions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"questions\": [\n {\n \"label\": \"<string>\",\n \"required\": true,\n \"id\": 123,\n \"placeholder\": \"<string>\",\n \"helpText\": \"<string>\",\n \"sectionHeading\": \"<string>\",\n \"options\": [\n \"<string>\"\n ],\n \"contactCustomFieldId\": 123,\n \"translations\": {}\n }\n ],\n \"removeQuestionIds\": [\n 123\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"slug": "<string>",
"createsAccount": true,
"publicUrl": "<string>",
"name": "<string>",
"title": "<string>",
"subtitle": "<string>",
"planStepTitle": "<string>",
"classTypeStepTitle": "<string>",
"planIds": [
123
],
"classTypeIds": [
123
],
"productIds": [
123
],
"registrationFor": "individual",
"signatureMethod": "draw",
"collectsDocuments": true,
"requiresAuthentication": true,
"combineSelectionAndDetails": true,
"displayMode": "page",
"videoUrl": "<string>",
"videoRequired": true,
"videoTitle": "<string>",
"fieldOverrides": {
"firstName": "required",
"lastName": "required",
"email": "required",
"phone": "required",
"dateOfBirth": "required",
"gender": "required",
"address": "required"
},
"translations": {},
"packageIds": [
123
],
"submissionCount": 123,
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z",
"questions": [
{
"id": 123,
"label": "<string>",
"type": "text",
"required": true,
"placeholder": "<string>",
"helpText": "<string>",
"sectionHeading": "<string>",
"options": [
"<string>"
],
"contactCustomFieldId": 123,
"translations": {}
}
]
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}{
"error": "<string>",
"code": "<string>",
"details": {}
}Authorizations
Organization-scoped bearer credential: a customer API key (1club_sk_live_...) or an MCP OAuth access token.
Headers
Retry-safe key; a repeat of the same request replays the first response
255Path Parameters
1club form id
Body
Response
The form, with its new questions
A form: a page people fill in, live at publicUrl.
The last part of publicUrl. Fixed once the form exists.
true for a sign-up form (registers the person, can sell); false for a fill-in form (collects answers). Fixed once the form exists.
Where the form is filled in, on the organization's own website or member portal. It is live: anyone with the link can use it. null when the organization has neither switched on, so nothing can open the form until one is.
Internal name, shown to staff in the admin portal.
200Heading at the top of the form. Blank or null falls back to the wizard's own wording.
200Sub-heading under the title. Blank or null falls back to the wizard's own wording.
200Heading above the plan picker (sign-up forms). Blank or null falls back to the wizard's own wording.
200Heading above the class-type picker (sign-up forms). Blank or null falls back to the wizard's own wording.
200Sign-up forms only. Plans the form sells, from GET /v1/platform/plans. Each must be active, publicly visible and not a season plan (FORM_PLAN_NOT_SELLABLE names each refused id and why). When any are set, the person must choose one to finish.
100Sign-up forms only. Class types offered as an interest, from GET /v1/platform/class-types. Nothing is booked.
100Sign-up forms only. Products the form sells, from GET /v1/platform/products. Each must be active, publicly visible and sold as a product (FORM_PRODUCT_NOT_SELLABLE).
100Who the form registers: the person filling it in, only their children, or both.
individual, child, both How documents are signed: drawn, typed name, or a checkbox.
draw, type, check Whether the form asks for the organization's documents and a signature. Which documents is set by the organization's document rules.
Fill-in forms only: the person must be signed in to fill it in. Refused on a sign-up form (FORM_AUTHENTICATION_FILL_IN_ONLY).
Put the "choose what to buy" step and the details step on one page. Needs a form that sells something (FORM_NOTHING_TO_COMBINE).
How a link to the form opens: as its own page, or as a dialog over the page it was opened from.
page, dialog A Cloudinary video URL from the media library, shown as a step before review. null removes the video step.
500The person cannot continue until the video has played to the end. Needs a video (FORM_VIDEO_REQUIRED_WITHOUT_VIDEO).
Heading above the video. Blank or null falls back to the wizard's own wording.
200Fill-in forms only (FORM_FIELD_OVERRIDES_FILL_IN_ONLY; an empty object is accepted and ignored on a sign-up form, which asks the organization's own sign-up fields instead). Which built-in contact fields the form asks: required asks it, hidden does not. A fill-in form cannot ask one optionally. address asks the whole postal address. On update the map is merged: the fields you send change and the rest stay as they are, so send hidden to stop asking one. null clears every override.
Show child attributes
Show child attributes
Per-locale wording, as { "es": { "title": "..." } }. Replaces the whole map. Translatable fields: title, subtitle, planStepTitle, classTypeStepTitle, videoTitle; any other key is refused (INVALID_TRANSLATIONS).
Show child attributes
Show child attributes
Read-only here: packages are added in the admin portal.
How many people have completed it. The answers are not served by this API.
In order. On a single-form read and on every write; not in the list.
Show child attributes
Show child attributes
Was this page helpful?