Theme preview comments
List a theme's preview comments
Live comments with their replies nested, ordered by creation time and
then by client_id. Deleted comments are absent from preview_comments
and present in deleted_client_ids, which is what lets a client tell a
deletion apart from a comment it has simply not seen.
GET
/
api
/
v202604
/
themes
/
{theme_id}
/
preview_comments
List a theme's preview comments
curl --request GET \
--url https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments', 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/v202604/themes/{theme_id}/preview_comments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"preview_comments": [
{
"id": 31877,
"run_id": null,
"lock_version": 3,
"client_id": "c-3f9a2e71",
"n": 4,
"body": "The hero headline wraps onto three lines on mobile. Can we tighten it so it fits on two?",
"status": "open",
"status_at_ms": 1789398131000,
"page_url": "/",
"author_name": "Michael Scott",
"created_at_ms": 1789398131000,
"template_id": 902114,
"section": {
"id": "hero-banner-1",
"type": "hero-banner"
},
"block": null,
"target": {
"tag": "h1",
"selector": "section[data-section-id=\"hero-banner-1\"] h1.hero__title",
"text": "Limitless Paper in a Paperless World",
"html": "<h1 class=\"hero__title\">Limitless Paper in a Paperless World</h1>"
},
"pin": {
"x": 48.2,
"y": 22.7,
"ox": 0.41,
"oy": 0.63
},
"mentions": [
{
"id": "52018",
"name": "Pam Beesly"
}
],
"mentioned_project": null,
"proof_baseline": null,
"work_item": null,
"board_position": null,
"board_position_at_ms": null,
"assignee": null,
"assigner": null,
"assigned_at_ms": null,
"priority": null,
"priority_at_ms": null,
"replies": [
{
"client_id": "r-5c20e9b4",
"run_id": null,
"body": "Agreed. Let's drop the font size a step below 768px rather than rewording it.",
"author_name": "Pam Beesly",
"created_at_ms": 1789398277000,
"mentions": [],
"shot": null,
"proof": null
}
]
},
{
"id": 31902,
"run_id": null,
"lock_version": 1,
"client_id": "c-8e4b17d0",
"n": 5,
"body": "Swap this image for the new 20lb Copy Paper case shot from the product page.",
"status": "open",
"status_at_ms": 1789463922000,
"page_url": "/products/20lb-copy-paper",
"author_name": "Pam Beesly",
"created_at_ms": 1789463922000,
"template_id": 902131,
"section": {
"id": "product-gallery-1",
"type": "product-gallery"
},
"block": null,
"target": {
"tag": "img",
"selector": "section[data-section-id=\"product-gallery-1\"] img.gallery__main",
"text": null,
"html": "<img class=\"gallery__main\" alt=\"Dunder Mifflin 20lb Copy Paper\">"
},
"pin": {
"x": 31.5,
"y": 44,
"ox": 0.5,
"oy": 0.38
},
"mentions": [],
"mentioned_project": null,
"proof_baseline": null,
"work_item": null,
"board_position": "a0V",
"board_position_at_ms": 1789464000000,
"assignee": null,
"assigner": null,
"assigned_at_ms": null,
"priority": "high",
"priority_at_ms": 1789463922000,
"replies": []
}
],
"deleted_client_ids": [
"c-1a7d52f3"
],
"status": 200,
"meta": {
"request_uuid": "7c1e9a52-4b3d-4f0e-9d2a-81f6c3b5e240",
"timestamp": "2026-09-15T09:30:12Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Id of the theme whose comments to list.
Response
The theme's live comments, plus the ids of deleted ones.
Live comments, replies nested.
Show child attributes
Show child attributes
Client ids of comments that have been deleted.
HTTP status, repeated in the body.
Envelope metadata returned on every preview-comment response.
Show child attributes
Show child attributes
⌘I
List a theme's preview comments
curl --request GET \
--url https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments', 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/v202604/themes/{theme_id}/preview_comments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/themes/{theme_id}/preview_comments")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"preview_comments": [
{
"id": 31877,
"run_id": null,
"lock_version": 3,
"client_id": "c-3f9a2e71",
"n": 4,
"body": "The hero headline wraps onto three lines on mobile. Can we tighten it so it fits on two?",
"status": "open",
"status_at_ms": 1789398131000,
"page_url": "/",
"author_name": "Michael Scott",
"created_at_ms": 1789398131000,
"template_id": 902114,
"section": {
"id": "hero-banner-1",
"type": "hero-banner"
},
"block": null,
"target": {
"tag": "h1",
"selector": "section[data-section-id=\"hero-banner-1\"] h1.hero__title",
"text": "Limitless Paper in a Paperless World",
"html": "<h1 class=\"hero__title\">Limitless Paper in a Paperless World</h1>"
},
"pin": {
"x": 48.2,
"y": 22.7,
"ox": 0.41,
"oy": 0.63
},
"mentions": [
{
"id": "52018",
"name": "Pam Beesly"
}
],
"mentioned_project": null,
"proof_baseline": null,
"work_item": null,
"board_position": null,
"board_position_at_ms": null,
"assignee": null,
"assigner": null,
"assigned_at_ms": null,
"priority": null,
"priority_at_ms": null,
"replies": [
{
"client_id": "r-5c20e9b4",
"run_id": null,
"body": "Agreed. Let's drop the font size a step below 768px rather than rewording it.",
"author_name": "Pam Beesly",
"created_at_ms": 1789398277000,
"mentions": [],
"shot": null,
"proof": null
}
]
},
{
"id": 31902,
"run_id": null,
"lock_version": 1,
"client_id": "c-8e4b17d0",
"n": 5,
"body": "Swap this image for the new 20lb Copy Paper case shot from the product page.",
"status": "open",
"status_at_ms": 1789463922000,
"page_url": "/products/20lb-copy-paper",
"author_name": "Pam Beesly",
"created_at_ms": 1789463922000,
"template_id": 902131,
"section": {
"id": "product-gallery-1",
"type": "product-gallery"
},
"block": null,
"target": {
"tag": "img",
"selector": "section[data-section-id=\"product-gallery-1\"] img.gallery__main",
"text": null,
"html": "<img class=\"gallery__main\" alt=\"Dunder Mifflin 20lb Copy Paper\">"
},
"pin": {
"x": 31.5,
"y": 44,
"ox": 0.5,
"oy": 0.38
},
"mentions": [],
"mentioned_project": null,
"proof_baseline": null,
"work_item": null,
"board_position": "a0V",
"board_position_at_ms": 1789464000000,
"assignee": null,
"assigner": null,
"assigned_at_ms": null,
"priority": "high",
"priority_at_ms": 1789463922000,
"replies": []
}
],
"deleted_client_ids": [
"c-1a7d52f3"
],
"status": 200,
"meta": {
"request_uuid": "7c1e9a52-4b3d-4f0e-9d2a-81f6c3b5e240",
"timestamp": "2026-09-15T09:30:12Z"
}
}{
"error": {
"message": "<string>",
"details": {}
},
"status": 123,
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}