Skip to content

Feedback API ​

Use these endpoints to read and interact with feedback boards, items, comments, and subscriptions.


List Boards ​

GET v1/feedback/boards

Returns all feedback boards for the project.

Authentication ​

No authentication required.

Response ​

json
{
  "boards": [
    {
      "slug": "feature-requests",
      "name": "Feature Requests",
      "color": "#6366f1",
      "items_count": 42,
      "description": "Submit and vote on feature requests."
    }
  ]
}

List Statuses ​

GET v1/feedback/statuses

Returns the feedback statuses configured for the project.

Authentication ​

No authentication required.

Response ​

json
{
  "statuses": [
    { "value": "open", "label": "Open", "color": "#22c55e" },
    { "value": "in_progress", "label": "In progress", "color": "#eab308" }
  ]
}

List Tags ​

GET v1/feedback/tags

Returns all feedback tags for the project.

Authentication ​

No authentication required.

Response ​

json
{
  "tags": [
    { "ulid": "01HXY...", "name": "Bug" },
    { "ulid": "01HXZ...", "name": "Enhancement" }
  ]
}

Search Similar Items ​

GET v1/feedback/search-similar

Returns up to 5 matching items. Queries shorter than 3 characters return an empty array.

Authentication ​

No authentication required.

Query Parameters ​

ParamTypeDescription
querystringSearch string

Response ​

json
{
  "items": [
    {
      "ulid": "01HXY...",
      "name": "Dark mode support",
      "description": "Please add a dark mode.",
      "votes": 42,
      "status": "open",
      "created_at": "2024-01-15T10:00:00.000000Z",
      "author": { "name": "Jane", "avatar": null, "is_user": false },
      "tags": [],
      "feedback_board_slug": "feature-requests",
      "board": {
        "slug": "feature-requests",
        "name": "Feature Requests",
        "color": "#6366f1"
      }
    }
  ]
}

List All Items ​

GET v1/feedback/items

Returns paginated feedback items across all boards.

Authentication ​

No authentication required.

Query Parameters ​

ParamTypeDescription
sortstringtop (default), trending, or new
statusstringFilter by status
boardsstringComma-separated board slugs
searchstringSearch query
tagstringTag ULID
pageintegerPage number, default 1

Response ​

json
{
  "data": [
    {
      "ulid": "01HXY...",
      "name": "Dark mode support",
      "description": "Please add a dark mode.",
      "votes": 42,
      "status": "open",
      "author": { "name": "Jane", "avatar": null, "is_user": false },
      "created_at": "2024-01-15T10:00:00.000000Z",
      "image": null,
      "comments_count": 3,
      "pinned": false,
      "comments_enabled": true,
      "updated_at": "2024-01-16T12:00:00.000000Z",
      "tags": [],
      "feedback_board_slug": "feature-requests",
      "board": {
        "slug": "feature-requests",
        "name": "Feature Requests",
        "color": "#6366f1"
      }
    }
  ],
  "current_page": 1,
  "per_page": 20,
  "total": 42,
  "total_pages": 3,
  "has_more": true
}

List Items by Board ​

GET v1/feedback/boards/{boardSlug}/items

Returns paginated feedback items for a single board.

Authentication ​

No authentication required.

Query Parameters ​

ParamTypeDescription
sortstringtop (default), trending, or new
statusstringFilter by status
pageintegerPage number, default 1

Response ​

Same shape as GET v1/feedback/items.


Get Item ​

GET v1/feedback/items/{itemUlid}

Returns one feedback item with full public detail.

Authentication ​

No authentication required.

Response ​

json
{
  "item": {
    "ulid": "01HXY...",
    "name": "Dark mode support",
    "description": "Please add a dark mode.",
    "description_html": "<p>Please add a dark mode.</p>",
    "votes": 42,
    "status": "open",
    "author": { "name": "Jane", "avatar": null, "is_user": false },
    "created_at": "2024-01-15T10:00:00.000000Z",
    "updated_at": "2024-01-16T12:00:00.000000Z",
    "image": null,
    "comments_count": 3,
    "pinned": false,
    "comments_enabled": true,
    "can_delete": false,
    "can_update": false,
    "tags": [],
    "feedback_board_slug": "feature-requests",
    "board": {
      "slug": "feature-requests",
      "name": "Feature Requests",
      "color": "#6366f1",
      "description": "Submit and vote on feature requests."
    },
    "mergedItems": [],
    "logs": [],
    "changelogs": []
  },
  "previous_item_ulid": "01HXA...",
  "next_item_ulid": "01HXB..."
}

Create Item ​

POST v1/feedback/items

Creates a feedback item.

Authentication ​

  • customer token via X-Customer-Token, or
  • no token when allow_anonymous_posting is enabled

Request Body ​

FieldTypeRequiredDescription
feedback_board_slugstringyesTarget board slug
namestringyesItem title, max 255
descriptionstringyesItem description
imagestringnoBase64-encoded image
authorstringnoOptional display name
tagsstring[]noArray of tag ULIDs

Response ​

Returns 201 Created.

json
{
  "success": true,
  "message": "Feedback submitted successfully!",
  "item": {
    "ulid": "01HXY...",
    "name": "Dark mode support"
  }
}

Notes ​

  • authenticated submissions are auto-attributed to the customer
  • anonymous submissions use the anonymous identity cookie / header
  • invalid images or uploads without the uploads feature return an error

Update Item ​

PATCH v1/feedback/items/{itemUlid}

Updates the authenticated customer's own feedback item.

Authentication ​

Requires X-Customer-Token.

Request Body ​

FieldTypeRequiredDescription
namestringnoUpdated title
descriptionstring|nullnoUpdated description
imagestring|nullnoBase64 image, or empty / null to remove
authorstringnoOptional author override
tagsstring[]noReplacement tag ULIDs

Response ​

200 OK with the updated item.

Notes ​

  • returns 401 if the caller is not authenticated
  • returns 403 if the item belongs to a different customer

Delete Item ​

DELETE v1/feedback/items/{itemUlid}

Deletes the authenticated customer's own feedback item.

Authentication ​

Requires X-Customer-Token.

Response ​

json
{
  "success": true,
  "message": "Feedback item deleted successfully."
}

Notes ​

  • returns 401 if the caller is not authenticated
  • returns 403 if the item belongs to a different customer

Vote on Item ​

POST v1/feedback/items/{itemUlid}/vote

Toggles a vote on a feedback item.

Authentication ​

  • customer token via X-Customer-Token, or
  • anonymous vote with anonymous: true when allow_anonymous_upvoting is enabled

Request Body ​

FieldTypeRequiredDescription
anonymousbooleannoSet true for anonymous voting

Response ​

json
{
  "success": true,
  "voted": true,
  "votes": 43
}

Notes ​

  • anonymous voting requires the anonymous cookie or X-Klero-Anon-Id
  • returns 400 if anonymous voting is attempted without an anonymous identity

List Comments ​

GET v1/feedback/items/{itemUlid}/comments

Returns publicly visible comments for a feedback item.

Authentication ​

No authentication required.

Response ​

json
{
  "comments": [
    {
      "ulid": "01HXY...",
      "content": "Great idea!",
      "image": null,
      "author": "Jane",
      "created_at": "2024-01-15T10:00:00.000000Z",
      "updated_at": "2024-01-15T10:00:00.000000Z",
      "is_reply": false,
      "likes_count": 2,
      "replies": []
    }
  ]
}

Notes ​

  • deleted comments are represented as [deleted]
  • viewer-specific like or ownership state is not included here

Create Comment ​

POST v1/feedback/items/{itemUlid}/comments

Creates a comment or reply.

Authentication ​

  • customer token via X-Customer-Token, or
  • no token when allow_anonymous_commenting is enabled

Request Body ​

FieldTypeRequiredDescription
contentstringno*Comment text, max 2000
imagestringnoBase64-encoded image
parent_comment_ulidstringnoReply target
authorstringnoOptional display name

content is required when the request is anonymous. For authenticated requests, either content or image must be present.

Response ​

json
{
  "success": true,
  "message": "Comment added successfully!",
  "comment": {
    "ulid": "01HXY...",
    "content": "Great idea!",
    "image": null,
    "author": "Jane",
    "created_at": "2024-01-15T10:00:00.000000Z",
    "is_reply": false
  }
}

Notes ​

  • returns 403 if comments are disabled on the item
  • image uploads require the project uploads feature

Update Comment ​

PATCH v1/feedback/items/{itemUlid}/comments/{commentUlid}

Updates the authenticated customer's own comment.

Authentication ​

Requires X-Customer-Token.

Request Body ​

FieldTypeRequiredDescription
contentstring|nullnoUpdated text
imagestring|nullnoBase64 image, or empty / null to remove

Response ​

200 OK with the updated comment payload.

Notes ​

  • returns 401 if the caller is not authenticated
  • returns 403 if the comment belongs to a different customer

Delete Comment ​

DELETE v1/feedback/items/{itemUlid}/comments/{commentUlid}

Deletes the authenticated customer's own comment.

Authentication ​

Requires X-Customer-Token.

Response ​

json
{
  "success": true,
  "message": "Comment deleted successfully!"
}

Notes ​

  • returns 401 if the caller is not authenticated
  • returns 403 if the comment belongs to a different customer

Item Personalization ​

GET v1/feedback/items/{itemUlid}/personalization

Returns viewer-specific state for a single feedback item.

Authentication ​

Optional.

  • authenticated requests use X-Customer-Token
  • anonymous requests use the anonymous cookie or X-Klero-Anon-Id

Response ​

json
{
  "is_voted": true,
  "liked_comment_ulids": ["01HXY...", "01HXZ..."],
  "owned_comment_ulids": ["01HAB..."]
}

If no viewer identity is present, the arrays are empty and is_voted is false.


Like / Unlike Comment ​

POST v1/feedback/items/{itemUlid}/comments/{commentUlid}/like

Toggles a like on a comment.

Authentication ​

  • customer token via X-Customer-Token, or
  • anonymous like with anonymous: true when allow_anonymous_commenting is enabled

Request Body ​

FieldTypeRequiredDescription
anonymousbooleannoSet true for anonymous liking

Response ​

json
{
  "success": true,
  "liked": true,
  "likes_count": 3
}

Notes ​

  • anonymous liking requires the anonymous cookie or X-Klero-Anon-Id
  • returns 400 if anonymous liking is attempted without an anonymous identity

Subscriptions ​

Subscription endpoints always require X-Customer-Token.

Get Subscription Status ​

GET v1/subscribe

Returns:

json
{
  "subscribed": true
}

Unauthenticated requests return:

json
{
  "subscribed": false
}

Subscribe ​

POST v1/subscribe

Returns:

json
{
  "success": true,
  "subscribed": true
}

Unsubscribe ​

DELETE v1/subscribe

Returns:

json
{
  "success": true,
  "subscribed": false
}

Customer Feedback Management