curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/comments \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/comments"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/comments")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/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{
"items": [
{
"comment": {
"content": "Make this button match the header color.",
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c4d4f0a9001c3e5a1c",
"reactions": {},
"sender_id": "6820f41be7b91d003c45a20a",
"sender_name": "Dana Levi"
},
"reactor_names": {},
"replies": [],
"thread": {
"anchor": {
"element_tag": "button",
"source_location": "pages/Pricing.jsx:42:8"
},
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c1d4f0a9001c3e5a17",
"last_activity_at": "2026-10-05T09:14:22.512000Z",
"message_count": 0,
"page_path": "/pricing",
"unread": true
}
}
],
"has_more": false,
"next_cursor": "gAAAAABn7vJ0q2kX"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}List comments
Returns the app’s open comment threads with all their comments, newest first. Set include_resolved to true to include resolved threads too.
Each branch has its own comment threads. Set branch_id to work with a branch’s threads. Leave it out for main’s. Merging or deleting a branch deletes its threads, so treat a merged branch’s threads as gone.
Threads are ordered by when they were created, newest first. A page holds up to limit threads, 500 by default. While has_more is true, request the next page with cursor set to next_cursor and the same branch_id, and nothing else beside them. A cursor works for 24 hours, only on this app and branch. A thread created after you start paging shows up on a fresh first page, not in later pages.
Screenshot links in the response work for one hour. Call this again for fresh ones, or use Create comment screenshot link for a link that lasts a year.
This is limited to 600 requests per minute per app, shared by List comments and List mentionable users. A signed-in session has its own limit, and every personal access token for the workspace shares one. Some workspaces have a different limit. Every request that counts against the limit gets X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix time in seconds) headers, and a 429 also gets Retry-After in seconds. If the limiter itself is unavailable, requests go through without these headers.
curl --request GET \
--url https://app.base44.com/api/apps/{app_id}/comments \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.base44.com/api/apps/{app_id}/comments"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/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://app.base44.com/api/apps/{app_id}/comments")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.base44.com/api/apps/{app_id}/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{
"items": [
{
"comment": {
"content": "Make this button match the header color.",
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c4d4f0a9001c3e5a1c",
"reactions": {},
"sender_id": "6820f41be7b91d003c45a20a",
"sender_name": "Dana Levi"
},
"reactor_names": {},
"replies": [],
"thread": {
"anchor": {
"element_tag": "button",
"source_location": "pages/Pricing.jsx:42:8"
},
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c1d4f0a9001c3e5a17",
"last_activity_at": "2026-10-05T09:14:22.512000Z",
"message_count": 0,
"page_path": "/pricing",
"unread": true
}
}
],
"has_more": false,
"next_cursor": "gAAAAABn7vJ0q2kX"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Authorizations
Personal access token, sent as Authorization: Bearer <token>. Each operation lists the permission it needs: read_only or full_access. A full-access token can call every operation. A read-only token can call only the operations that list read_only; anything else returns 403 read_only_credential_route_not_allowed.
Path Parameters
ID of the app.
Query Parameters
Set to true to include resolved threads. Defaults to false.
Threads per page, 1 to 500. Defaults to 500.
1 <= x <= 500next_cursor from the previous page. Send it on its own: it carries include_resolved and limit, so sending either beside it returns a 400.
ID of the branch to work on, as returned by List branches. Omit it to work on the app's main branch.
Response
One page of the app's comment threads, newest first.
One page of an app's comment threads.
Threads on this page, newest first.
Show child attributes
Show child attributes
[
{
"comment": {
"content": "Make this button match the header color.",
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c4d4f0a9001c3e5a1c",
"reactions": {},
"sender_id": "6820f41be7b91d003c45a20a",
"sender_name": "Dana Levi"
},
"reactor_names": {},
"replies": [],
"thread": {
"anchor": {
"element_tag": "button",
"source_location": "pages/Pricing.jsx:42:8"
},
"created_date": "2026-10-05T09:14:22.512000Z",
"id": "68e2b7c1d4f0a9001c3e5a17",
"last_activity_at": "2026-10-05T09:14:22.512000Z",
"message_count": 0,
"page_path": "/pricing",
"unread": true
}
}
]
Whether more threads follow this page.
false
Pass as cursor to get the next page. null on the last page.
"gAAAAABn7vJ0q2kX"
Was this page helpful?