curl --request POST \
--url https://api.1club.ai/v1/platform/revenue-accounts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": true,
"isDefault": false
}
'import requests
url = "https://api.1club.ai/v1/platform/revenue-accounts"
payload = {
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": True,
"isDefault": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
code: '<string>',
description: '<string>',
isActive: true,
isDefault: false
})
};
fetch('https://api.1club.ai/v1/platform/revenue-accounts', 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/revenue-accounts",
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([
'name' => '<string>',
'code' => '<string>',
'description' => '<string>',
'isActive' => true,
'isDefault' => false
]),
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/revenue-accounts"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.1club.ai/v1/platform/revenue-accounts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/revenue-accounts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": true,
"isDefault": true
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}Create a revenue account
Adds an account to the chart of accounts. code is what the club’s bookkeeper reconciles against and must be free within the organization - a clash is a 409, not a second account under the same code.
Sending isDefault: true moves the default off whichever account currently holds it, in the same transaction and behind a per-organization lock, so concurrent promotions cannot both win. The default is where a sale posts when the item names no account, resolved at the time of the sale rather than frozen onto the item, so moving it changes where future unattributed sales land and leaves the ones already taken alone.
Two things about the default are decided for you. An organization whose chart has no default yet gets one from this call whatever isDefault says, since creating an account is the only way to give it one - so the first account in an empty chart is always the default, and is therefore always created active. And a default can never be inactive, so isActive: false is refused for any request that would land one, whether isDefault was sent or inferred.
Requires revenue-accounts:write. Supports the Idempotency-Key header.
curl --request POST \
--url https://api.1club.ai/v1/platform/revenue-accounts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": true,
"isDefault": false
}
'import requests
url = "https://api.1club.ai/v1/platform/revenue-accounts"
payload = {
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": True,
"isDefault": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
code: '<string>',
description: '<string>',
isActive: true,
isDefault: false
})
};
fetch('https://api.1club.ai/v1/platform/revenue-accounts', 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/revenue-accounts",
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([
'name' => '<string>',
'code' => '<string>',
'description' => '<string>',
'isActive' => true,
'isDefault' => false
]),
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/revenue-accounts"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.1club.ai/v1/platform/revenue-accounts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.1club.ai/v1/platform/revenue-accounts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"code\": \"<string>\",\n \"description\": \"<string>\",\n \"isActive\": true,\n \"isDefault\": false\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"name": "<string>",
"code": "<string>",
"description": "<string>",
"isActive": true,
"isDefault": 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.
Headers
Retry-safe key; a repeat of the same request replays the first response
255Body
Fields accepted when creating a revenue account. name and code are required, and the code must be free within the organization. Unknown fields are rejected. The billing entity an account belongs to is not settable here - it is inherited, and re-pointing one rewrites who is selling.
255The bookkeeper's code for the account, e.g. "4000". Unique within the organization; a clash is a 409.
502000False retires the account. Everything already pointing at it keeps pointing at it; there is no delete. Refused for any request that would leave the default inactive - including the first account in an empty chart, which is always made the default.
Where a sale posts when the item names no account. Setting it true moves the default off whichever account currently holds it, in the same transaction and behind a per-organization lock. Ignored when the chart has no default yet - the first account always takes it, since creating one is the only way to give the organization a default. The default must be active, so anything landing an inactive one is refused.
Response
Revenue account created
One account in the organization's chart of accounts. Reference the id as revenueAccountId on a membership plan, a product, a class type, an area type or an instructor type to decide where its sales post.
The chart-of-accounts code, which is how the club's bookkeeper names the account. Unique within the organization.
False for an account retired from the chart. Still valid on existing rows; do not attach it to something new. Never false on the default.
Where a sale posts when nothing on the item names an account. Exactly one account holds it, and it is always active.
Was this page helpful?