Review questions

GET /review-questions

List the extra questions reviewers are asked beside the star rating, in the order they appear on the form. Archived questions are included.

Requires the reviews:read permission.

Query parameters

limitnumber

The number of records to return.

cursorstring

A pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.

sortsortOrder | -sortOrder | label | -label | createdAt | -createdAt

The sort order. Prefix a field with - to sort descending. Defaults to sortOrder.

filterstring

A JSON-encoded filter document, for example {"createdAt":{"$gte":"2025-01-01T00:00:00Z"}}. Filterable fields: id, label, type, required, showOnWidget, archivedAt, createdAt. See Filtering for the syntax.

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: answersCount.

Request
curl \
  "https://your-store.meisei.app/api/review-questions" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "data": [
    {
      "id": "A4Ws1igz",
      "label": "string",
      "type": "scale",
      "config": {
        "steps": "...",
        "lowLabel": "...",
        "highLabel": "...",
        "middleLabel": "..."
      },
      "required": true,
      "showOnWidget": true,
      "sortOrder": 0,
      "productFilter": "...",
      "archivedAt": "2025-01-15T09:30:00Z",
      "metadata": "...",
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z",
      "answersCount": 0
    }
  ],
  "nextCursor": "string"
}

POST /review-questions

Add a question to the review form. A scale question asks for one of a run of steps between two labelled ends; a multi_choice question offers a list of options, one or several of which can be picked. Give it a productFilter to ask it only about part of the catalog. Triggers the reviewQuestion.created webhook.

Requires the reviews:write permission.

Body parameters

labelstringrequired

The question as reviewers read it.

typescale | multi_choicerequired

What the question asks for. scale is a run of steps between two labelled ends; multi_choice is a list of options.

configobject | objectrequired

The question's settings, whose shape follows its type: a scale question takes steps, lowLabel, highLabel and an optional middleLabel; a multi_choice question takes options and an optional multiple.

requiredboolean

Whether an answer is required. Defaults to false.

showOnWidgetboolean

Whether the storefront shows the answers. Defaults to true.

sortOrderinteger

Where the question sits on the form. Defaults to 0.

productFilterobject | null

A JSON filter document limiting the question to matching products, using the same fields as the products list endpoint. Null or empty asks it about every product.

metadataobject | null

Free-form string key/value pairs for your own data.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/review-questions" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "metadata": "..."
}'
Response
{
  "id": "A4Ws1igz",
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "archivedAt": "2025-01-15T09:30:00Z",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "answersCount": 0
}

GET /review-questions/{id}

Get a single review question by ID.

Requires the reviews:read permission.

Path parameters

idstringrequired

The ID of the review question.

Query parameters

includestring

A comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: answersCount.

Request
curl \
  "https://your-store.meisei.app/api/review-questions/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "archivedAt": "2025-01-15T09:30:00Z",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "answersCount": 0
}

PUT /review-questions/{id}

Edit a review question, or archive it so it stops being asked. Once reviewers have answered it, its type and its number of steps are fixed, and its options can be added to, relabeled or archived but never removed: the answers already recorded are read against them. Triggers the reviewQuestion.updated webhook.

Requires the reviews:write permission.

Path parameters

idstringrequired

The ID of the question to update.

Body parameters

labelstring

The question as reviewers read it.

typescale | multi_choice

The question's type. It can only be changed while nothing has answered the question.

configobject | object

Replaces the question's settings. Once the question has answers the number of steps is fixed and options can only be added, relabeled or archived.

requiredboolean

Whether an answer is required.

showOnWidgetboolean

Whether the storefront shows the answers.

sortOrderinteger

Where the question sits on the form.

productFilterobject | null

A JSON filter document limiting the question to matching products, using the same fields as the products list endpoint. Null or empty asks it about every product. Send null to ask it about everything again.

archivedboolean

Set true to stop asking the question, or false to ask it again. Answers already given keep showing either way.

metadataobject

Replaces the question's metadata wholesale. Omit to leave it alone.

Request
curl \
  -X PUT \
  "https://your-store.meisei.app/api/review-questions/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "archived": true,
  "metadata": "..."
}'
Response
{
  "id": "A4Ws1igz",
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "archivedAt": "2025-01-15T09:30:00Z",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "answersCount": 0
}

DELETE /review-questions/{id}

Delete a review question. This is refused once any review has answered it, because deleting it would take those answers with it. Archive it instead to stop asking it while its answers keep showing. Triggers the reviewQuestion.deleted webhook.

Requires the reviews:write permission.

Path parameters

idstringrequired

The ID of the question to delete.

Request
curl \
  -X DELETE \
  "https://your-store.meisei.app/api/review-questions/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "label": "string",
  "type": "scale",
  "config": {
    "steps": 0,
    "lowLabel": "string",
    "highLabel": "string",
    "middleLabel": "string"
  },
  "required": true,
  "showOnWidget": true,
  "sortOrder": 0,
  "productFilter": "...",
  "archivedAt": "2025-01-15T09:30:00Z",
  "metadata": "...",
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z",
  "answersCount": 0
}