Create a draft event form revision
Requires forms:write, a live credential, and Idempotency-Key. Test keys may read this surface but cannot create, update, or publish. Convex validates studio/event/definition tenancy and stale base-revision semantics.
curl --request POST \
--url https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"form_definition_id": "<string>",
"base_revision_id": "<string>",
"fields": [
{
"key": "<string>",
"label": "<string>",
"required": true,
"sort_order": 1,
"allow_multiple": true,
"options": [
"<string>"
],
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
]
}
'import requests
url = "https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions"
payload = {
"form_definition_id": "<string>",
"base_revision_id": "<string>",
"fields": [
{
"key": "<string>",
"label": "<string>",
"required": True,
"sort_order": 1,
"allow_multiple": True,
"options": ["<string>"],
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
]
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
form_definition_id: '<string>',
base_revision_id: '<string>',
fields: [
{
key: '<string>',
label: '<string>',
required: true,
sort_order: 1,
allow_multiple: true,
options: ['<string>'],
placeholder: '<string>',
semantic_key: '<string>',
semantic_label: '<string>'
}
]
})
};
fetch('https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions', 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.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'form_definition_id' => '<string>',
'base_revision_id' => '<string>',
'fields' => [
[
'key' => '<string>',
'label' => '<string>',
'required' => true,
'sort_order' => 1,
'allow_multiple' => true,
'options' => [
'<string>'
],
'placeholder' => '<string>',
'semantic_key' => '<string>',
'semantic_label' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$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.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions"
payload := strings.NewReader("{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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.post("https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"edit_version": 2,
"event_id": "<string>",
"fields": [
{
"input_type": "text",
"key": "<string>",
"label": "<string>",
"required": true,
"sort_order": 1,
"allow_multiple": true,
"boolean_display": "toggle",
"options": [
"<string>"
],
"options_display": "dropdown",
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
],
"id": "<string>",
"status": "<string>",
"studio_id": "<string>",
"base_revision_id": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"form_definition_id": "<string>",
"form_presentation": {
"pages": [
{
"id": "<string>",
"rows": [
{
"fields": [
{
"field_key": "<string>",
"width": "full"
}
],
"id": "<string>"
}
],
"title": "<string>",
"description": "<string>"
}
],
"public_title": "<string>",
"description": "<string>"
},
"published_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}Authorizations
Batch Relay scoped API key or an anonymous Test Mode session. Scope names document required capabilities. Anonymous sessions are sandbox-only and do not authorize studio, event, billing, or Live Mode operations.
Headers
1 - 200Untrusted optional analytics hint naming the calling client surface. It never affects authorization, routing, pricing, or behavior.
1 - 100Untrusted optional analytics hint naming the calling client version. It never affects authorization, routing, pricing, or behavior.
1 - 100Untrusted optional analytics hint naming the invocation mode. It never affects authorization, routing, pricing, or behavior.
1 - 100Path Parameters
Stable public studio ID beginning with stu_. The API never selects a studio implicitly; a local CLI profile name is not a studio ID.
5 - 256^stu_[A-Za-z0-9_-]+$1 - 256Body
- Option 1
- Option 2
Supply form_definition_id, at least one explicit field, or both. A definition may be cloned then overridden by explicit fields.
11200Show child attributes
Show child attributes
Typed public form layout. It intentionally excludes heroStorageId, Convex IDs, athlete data, guardian data, and submitted answers.
Show child attributes
Show child attributes
Response
Draft revision
x >= 11200Show child attributes
Show child attributes
Stable public form-revision ID.
111Present when this event revision derives from a reusable definition.
1Typed public form layout. It intentionally excludes heroStorageId, Convex IDs, athlete data, guardian data, and submitted answers.
Show child attributes
Show child attributes
curl --request POST \
--url https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: <idempotency-key>' \
--data '
{
"form_definition_id": "<string>",
"base_revision_id": "<string>",
"fields": [
{
"key": "<string>",
"label": "<string>",
"required": true,
"sort_order": 1,
"allow_multiple": true,
"options": [
"<string>"
],
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
]
}
'import requests
url = "https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions"
payload = {
"form_definition_id": "<string>",
"base_revision_id": "<string>",
"fields": [
{
"key": "<string>",
"label": "<string>",
"required": True,
"sort_order": 1,
"allow_multiple": True,
"options": ["<string>"],
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
]
}
headers = {
"Idempotency-Key": "<idempotency-key>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'Idempotency-Key': '<idempotency-key>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
form_definition_id: '<string>',
base_revision_id: '<string>',
fields: [
{
key: '<string>',
label: '<string>',
required: true,
sort_order: 1,
allow_multiple: true,
options: ['<string>'],
placeholder: '<string>',
semantic_key: '<string>',
semantic_label: '<string>'
}
]
})
};
fetch('https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions', 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.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'form_definition_id' => '<string>',
'base_revision_id' => '<string>',
'fields' => [
[
'key' => '<string>',
'label' => '<string>',
'required' => true,
'sort_order' => 1,
'allow_multiple' => true,
'options' => [
'<string>'
],
'placeholder' => '<string>',
'semantic_key' => '<string>',
'semantic_label' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Idempotency-Key: <idempotency-key>"
],
]);
$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.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions"
payload := strings.NewReader("{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Idempotency-Key", "<idempotency-key>")
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.post("https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions")
.header("Idempotency-Key", "<idempotency-key>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.batchrelay.com/v1/studios/{studio_id}/events/{event_id}/form-revisions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '<idempotency-key>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"form_definition_id\": \"<string>\",\n \"base_revision_id\": \"<string>\",\n \"fields\": [\n {\n \"key\": \"<string>\",\n \"label\": \"<string>\",\n \"required\": true,\n \"sort_order\": 1,\n \"allow_multiple\": true,\n \"options\": [\n \"<string>\"\n ],\n \"placeholder\": \"<string>\",\n \"semantic_key\": \"<string>\",\n \"semantic_label\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"edit_version": 2,
"event_id": "<string>",
"fields": [
{
"input_type": "text",
"key": "<string>",
"label": "<string>",
"required": true,
"sort_order": 1,
"allow_multiple": true,
"boolean_display": "toggle",
"options": [
"<string>"
],
"options_display": "dropdown",
"placeholder": "<string>",
"semantic_key": "<string>",
"semantic_label": "<string>"
}
],
"id": "<string>",
"status": "<string>",
"studio_id": "<string>",
"base_revision_id": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"form_definition_id": "<string>",
"form_presentation": {
"pages": [
{
"id": "<string>",
"rows": [
{
"fields": [
{
"field_key": "<string>",
"width": "full"
}
],
"id": "<string>"
}
],
"title": "<string>",
"description": "<string>"
}
],
"public_title": "<string>",
"description": "<string>"
},
"published_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}{
"code": "<string>",
"docs_url": "<string>",
"error": "<string>",
"message": "<string>",
"request_id": "<string>"
}