#Review answers
GET /review-answers
List the questions shoppers have asked about your products, most recently asked first, each with the answer that was generated from the product's reviews. One row per product per question; asking again bumps the ask count rather than adding a row. No shopper identity is stored with a question.
Requires the reviews:read permission.
Query Parameters
limitnumberThe number of records to return.
cursorstringA pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.
curl \
"https://api.cascade.dev/review-answers" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY"import { client } from "@cascade-commerce/api/admin/client"
import { getReviewAnswers } from "@cascade-commerce/api/admin"
client.setConfig({
baseUrl: "https://api.cascade.dev",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await getReviewAnswers()require "net/http"
uri = URI("https://api.cascade.dev/review-answers")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer sk_YOUR_SECRET_KEY"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyimport json
from urllib.request import Request, urlopen
req = Request(
"https://api.cascade.dev/review-answers",
headers={"Authorization": "Bearer sk_YOUR_SECRET_KEY"},
)
with urlopen(req) as res:
print(json.load(res)){
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"productId": "550e8400-e29b-41d4-a716-446655440000",
"productTitle": "string",
"productSlug": "string",
"question": "string",
"answered": true,
"answer": "string",
"citedReviewIds": ["..."],
"reviewCount": 0,
"modelId": "string",
"generatedAt": "2025-01-15T09:30:00Z",
"hidden": true,
"askCount": 0,
"lastAskedAt": "2025-01-15T09:30:00Z"
}
],
"nextCursor": "string"
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Unique identifier for the question and its cached answer."
},
"productId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The product the question was asked about."
},
"productTitle": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The product's title, joined for the list."
},
"productSlug": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The product's slug, joined for the list."
},
"question": {
"type": "string",
"description": "The question in its normalized form: lowercased, whitespace collapsed, terminal punctuation stripped. Rephrasings that normalize the same way are one row."
},
"answered": {
"type": "boolean",
"description": "Whether the reviews addressed the question. False means shoppers were told the reviews do not say."
},
"answer": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The generated answer shoppers privately see, or null when `answered` is false."
},
"citedReviewIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "The reviews the answer draws on."
},
"reviewCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "How many published reviews the product had when the answer was generated."
},
"modelId": {
"type": "string",
"description": "The model that produced the answer."
},
"generatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the answer was last generated."
},
"hidden": {
"type": "boolean",
"description": "Whether you have hidden this answer. A hidden answer tells shoppers the reviews do not say, without another model call."
},
"askCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "How many times the question has been asked."
},
"lastAskedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the question was last asked."
}
},
"required": [
"id",
"productId",
"productTitle",
"productSlug",
"question",
"answered",
"answer",
"citedReviewIds",
"reviewCount",
"modelId",
"generatedAt",
"hidden",
"askCount",
"lastAskedAt"
],
"additionalProperties": false
},
"description": "The page of records, in the requested sort order."
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Pass this back as `cursor` to fetch the next page. Null once the last page has been returned."
}
},
"required": ["data", "nextCursor"],
"additionalProperties": false
}PATCH /review-answers/{id}
Hide a question's answer from shoppers, or show it again. A hidden answer keeps serving from cache as "the reviews do not say", so hiding one never costs a model call.
Requires the reviews:write permission.
Path Parameters
idstring (uuid)requiredThe ID of the question.
Body Parameters
hiddenbooleanrequiredTrue hides this answer: shoppers asking the question are told the reviews do not say, and no new answer is generated for it. False shows the cached answer again.
curl \
-X PATCH \
"https://api.cascade.dev/review-answers/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"hidden": true
}'import { client } from "@cascade-commerce/api/admin/client"
import { patchReviewAnswersById } from "@cascade-commerce/api/admin"
client.setConfig({
baseUrl: "https://api.cascade.dev",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await patchReviewAnswersById({
path: { id: "550e8400-e29b-41d4-a716-446655440000" },
body: {
hidden: true,
},
})require "net/http"
uri = URI("https://api.cascade.dev/review-answers/550e8400-e29b-41d4-a716-446655440000")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer sk_YOUR_SECRET_KEY"
req["Content-Type"] = "application/json"
req.body = <<~JSON
{
"hidden": true
}
JSON
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.bodyimport json
from urllib.request import Request, urlopen
body = """{
"hidden": true
}"""
req = Request(
"https://api.cascade.dev/review-answers/550e8400-e29b-41d4-a716-446655440000",
data=body.encode(),
method="PATCH",
headers={
"Authorization": "Bearer sk_YOUR_SECRET_KEY",
"Content-Type": "application/json",
},
)
with urlopen(req) as res:
print(json.load(res)){
"id": "550e8400-e29b-41d4-a716-446655440000",
"productId": "550e8400-e29b-41d4-a716-446655440000",
"productTitle": "string",
"productSlug": "string",
"question": "string",
"answered": true,
"answer": "string",
"citedReviewIds": ["string"],
"reviewCount": 0,
"modelId": "string",
"generatedAt": "2025-01-15T09:30:00Z",
"hidden": true,
"askCount": 0,
"lastAskedAt": "2025-01-15T09:30:00Z"
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "Unique identifier for the question and its cached answer."
},
"productId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The product the question was asked about."
},
"productTitle": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The product's title, joined for the list."
},
"productSlug": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The product's slug, joined for the list."
},
"question": {
"type": "string",
"description": "The question in its normalized form: lowercased, whitespace collapsed, terminal punctuation stripped. Rephrasings that normalize the same way are one row."
},
"answered": {
"type": "boolean",
"description": "Whether the reviews addressed the question. False means shoppers were told the reviews do not say."
},
"answer": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The generated answer shoppers privately see, or null when `answered` is false."
},
"citedReviewIds": {
"type": "array",
"items": {
"type": "string"
},
"description": "The reviews the answer draws on."
},
"reviewCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "How many published reviews the product had when the answer was generated."
},
"modelId": {
"type": "string",
"description": "The model that produced the answer."
},
"generatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the answer was last generated."
},
"hidden": {
"type": "boolean",
"description": "Whether you have hidden this answer. A hidden answer tells shoppers the reviews do not say, without another model call."
},
"askCount": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991,
"description": "How many times the question has been asked."
},
"lastAskedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the question was last asked."
}
},
"required": [
"id",
"productId",
"productTitle",
"productSlug",
"question",
"answered",
"answer",
"citedReviewIds",
"reviewCount",
"modelId",
"generatedAt",
"hidden",
"askCount",
"lastAskedAt"
],
"additionalProperties": false,
"description": "The updated question."
}