Root themes
Create a root theme
Submits a new theme to the Fluid theme library for review. The theme is created
under your company with an initial 1.0 version in draft status, built from the
zip archive at zip_file_url. The version stays in draft until a Fluid platform
administrator approves or rejects it.
Requires a company admin Bearer token with the application_themes update
permission. The response carries only a confirmation message; call
GET /api/root_themes/my to see the new theme and its versions. A failure while
creating the theme returns 422.
POST
/
api
/
root_themes
Create a root theme
curl --request POST \
--url https://api.fluid.app/api/root_themes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"zip_file_url": "https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip",
"name": "Scranton Classic",
"changelog": "Initial release with product, collection, and cart templates.",
"demo_url": "https://shop.dundermifflin.com",
"description": "A clean, paper-white storefront theme built for the Scranton branch."
}
'import requests
url = "https://api.fluid.app/api/root_themes"
payload = {
"zip_file_url": "https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip",
"name": "Scranton Classic",
"changelog": "Initial release with product, collection, and cart templates.",
"demo_url": "https://shop.dundermifflin.com",
"description": "A clean, paper-white storefront theme built for the Scranton branch."
}
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({
zip_file_url: 'https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip',
name: 'Scranton Classic',
changelog: 'Initial release with product, collection, and cart templates.',
demo_url: 'https://shop.dundermifflin.com',
description: 'A clean, paper-white storefront theme built for the Scranton branch.'
})
};
fetch('https://api.fluid.app/api/root_themes', 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/root_themes",
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([
'zip_file_url' => 'https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip',
'name' => 'Scranton Classic',
'changelog' => 'Initial release with product, collection, and cart templates.',
'demo_url' => 'https://shop.dundermifflin.com',
'description' => 'A clean, paper-white storefront theme built for the Scranton branch.'
]),
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/root_themes"
payload := strings.NewReader("{\n \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\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/root_themes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/root_themes")
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 \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\n}"
response = http.request(request)
puts response.read_body{
"message": "Theme has been uploaded for review",
"meta": {
"request_id": "5f0c9a2e-7b41-4d8e-9c36-1a2b8e4f7d90",
"timestamp": "2026-09-14T15:42:08Z"
}
}{
"message": "<string>",
"error": "<string>",
"error_message": "<string>",
"errors": "<string>",
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
Bearer token authentication
Body
application/json
⌘I
Create a root theme
curl --request POST \
--url https://api.fluid.app/api/root_themes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"zip_file_url": "https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip",
"name": "Scranton Classic",
"changelog": "Initial release with product, collection, and cart templates.",
"demo_url": "https://shop.dundermifflin.com",
"description": "A clean, paper-white storefront theme built for the Scranton branch."
}
'import requests
url = "https://api.fluid.app/api/root_themes"
payload = {
"zip_file_url": "https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip",
"name": "Scranton Classic",
"changelog": "Initial release with product, collection, and cart templates.",
"demo_url": "https://shop.dundermifflin.com",
"description": "A clean, paper-white storefront theme built for the Scranton branch."
}
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({
zip_file_url: 'https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip',
name: 'Scranton Classic',
changelog: 'Initial release with product, collection, and cart templates.',
demo_url: 'https://shop.dundermifflin.com',
description: 'A clean, paper-white storefront theme built for the Scranton branch.'
})
};
fetch('https://api.fluid.app/api/root_themes', 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/root_themes",
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([
'zip_file_url' => 'https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip',
'name' => 'Scranton Classic',
'changelog' => 'Initial release with product, collection, and cart templates.',
'demo_url' => 'https://shop.dundermifflin.com',
'description' => 'A clean, paper-white storefront theme built for the Scranton branch.'
]),
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/root_themes"
payload := strings.NewReader("{\n \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\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/root_themes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/root_themes")
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 \"zip_file_url\": \"https://cdn.fluid.app/uploads/dunder-mifflin/themes/scranton-classic-1.0.zip\",\n \"name\": \"Scranton Classic\",\n \"changelog\": \"Initial release with product, collection, and cart templates.\",\n \"demo_url\": \"https://shop.dundermifflin.com\",\n \"description\": \"A clean, paper-white storefront theme built for the Scranton branch.\"\n}"
response = http.request(request)
puts response.read_body{
"message": "Theme has been uploaded for review",
"meta": {
"request_id": "5f0c9a2e-7b41-4d8e-9c36-1a2b8e4f7d90",
"timestamp": "2026-09-14T15:42:08Z"
}
}{
"message": "<string>",
"error": "<string>",
"error_message": "<string>",
"errors": "<string>",
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}