Add a site
Adds a site owned by the member, as a draft. Without a handle one is proposed from the name, and a number is added when it is taken. A member can own at most 25 sites.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/sites \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"name": "Riley's Shop",
"visibility": "private",
"settings": {
"primary_color": "#112233"
}
}
EOFimport requests
url = "https://api.fluid.app/api/member/v2026-10/sites"
payload = {
"name": "Riley's Shop",
"visibility": "private",
"settings": { "primary_color": "#112233" }
}
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: 'Riley\'s Shop',
visibility: 'private',
settings: {primary_color: '#112233'}
})
};
fetch('https://api.fluid.app/api/member/v2026-10/sites', 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.fluid.app/api/member/v2026-10/sites",
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' => 'Riley\'s Shop',
'visibility' => 'private',
'settings' => [
'primary_color' => '#112233'
]
]),
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.fluid.app/api/member/v2026-10/sites"
payload := strings.NewReader("{\n \"name\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\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.fluid.app/api/member/v2026-10/sites")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/sites")
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\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\n}"
response = http.request(request)
puts response.read_body{
"status": 201,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"handle": "rileys-shop",
"name": "Riley's Shop",
"visibility": "private",
"status": "draft",
"owner_kind": "member",
"copied_from_id": null,
"access": {
"declared": false,
"uses": []
},
"layout_name": null,
"settings": {
"primary_color": "#112233"
},
"content_version": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d68",
"lock_version": 0,
"created_at": "2026-09-01T10:00:00.000000Z",
"updated_at": "2026-09-01T10:00:00.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
A member credential in the Authorization: Bearer header: a member
session JWT, a portal JWT whose login is linked to a membership in
that company, an opaque member token, or a verified One Auth identity
access token. The credential alone identifies the member and company.
Member session and portal JWTs are read-only and are refused with 403
on every write.
Body
A new site. Fields a member cannot set, such as required and position, are refused as unknown fields.
Display name.
1 - 255^[^\u0000]*[^\s\u0000][^\u0000]*$Lowercase letters and digits separated by single hyphens, not reserved and not used by another site in the company. Omit it to have one proposed from the name.
1 - 40^[a-z0-9]+(-[a-z0-9]+)*$Who may open the site once it is published. Defaults to private.
private, public The default layout for the site's pages. Null or omitted uses the site's own site layout.
255Design tokens such as colors and fonts.
curl --request POST \
--url https://api.fluid.app/api/member/v2026-10/sites \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"name": "Riley's Shop",
"visibility": "private",
"settings": {
"primary_color": "#112233"
}
}
EOFimport requests
url = "https://api.fluid.app/api/member/v2026-10/sites"
payload = {
"name": "Riley's Shop",
"visibility": "private",
"settings": { "primary_color": "#112233" }
}
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: 'Riley\'s Shop',
visibility: 'private',
settings: {primary_color: '#112233'}
})
};
fetch('https://api.fluid.app/api/member/v2026-10/sites', 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.fluid.app/api/member/v2026-10/sites",
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' => 'Riley\'s Shop',
'visibility' => 'private',
'settings' => [
'primary_color' => '#112233'
]
]),
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.fluid.app/api/member/v2026-10/sites"
payload := strings.NewReader("{\n \"name\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\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.fluid.app/api/member/v2026-10/sites")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/sites")
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\": \"Riley's Shop\",\n \"visibility\": \"private\",\n \"settings\": {\n \"primary_color\": \"#112233\"\n }\n}"
response = http.request(request)
puts response.read_body{
"status": 201,
"data": {
"id": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d67",
"handle": "rileys-shop",
"name": "Riley's Shop",
"visibility": "private",
"status": "draft",
"owner_kind": "member",
"copied_from_id": null,
"access": {
"declared": false,
"uses": []
},
"layout_name": null,
"settings": {
"primary_color": "#112233"
},
"content_version": "0192f4e5-6f7a-7b8c-9d0e-1f2a3b4c5d68",
"lock_version": 0,
"created_at": "2026-09-01T10:00:00.000000Z",
"updated_at": "2026-09-01T10:00:00.000000Z"
},
"meta": {
"request_uuid": "0192f4c8-5b6c-7d74-a3e8-0f1a2b3c4d5e",
"timestamp": "2026-09-30T15:08:21Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"timestamp": "2023-11-07T05:31:56Z"
}
}