Feedback API
Use these endpoints to read and interact with feedback boards, items, comments, and subscriptions.
List Boards
GET v1/feedback/boardsReturns all feedback boards for the project.
Authentication
No authentication required.
Response
{
"boards": [
{
"slug": "feature-requests",
"name": "Feature Requests",
"color": "#6366f1",
"items_count": 42,
"description": "Submit and vote on feature requests."
}
]
}List Statuses
GET v1/feedback/statusesReturns the feedback statuses configured for the project.
Authentication
No authentication required.
Response
{
"statuses": [
{ "value": "open", "label": "Open", "color": "#22c55e" },
{ "value": "in_progress", "label": "In progress", "color": "#eab308" }
]
}List Tags
GET v1/feedback/tagsReturns all feedback tags for the project.
Authentication
No authentication required.
Response
{
"tags": [
{ "ulid": "01HXY...", "name": "Bug" },
{ "ulid": "01HXZ...", "name": "Enhancement" }
]
}Search Similar Items
GET v1/feedback/search-similarReturns up to 5 matching items. Queries shorter than 3 characters return an empty array.
Authentication
No authentication required.
Query Parameters
| Param | Type | Description |
|---|---|---|
query | string | Search string |
Response
{
"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/itemsReturns paginated feedback items across all boards.
Authentication
No authentication required.
Query Parameters
| Param | Type | Description |
|---|---|---|
sort | string | top (default), trending, or new |
status | string | Filter by status |
boards | string | Comma-separated board slugs |
search | string | Search query |
tag | string | Tag ULID |
page | integer | Page number, default 1 |
Response
{
"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}/itemsReturns paginated feedback items for a single board.
Authentication
No authentication required.
Query Parameters
| Param | Type | Description |
|---|---|---|
sort | string | top (default), trending, or new |
status | string | Filter by status |
page | integer | Page 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
{
"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/itemsCreates a feedback item.
Authentication
- customer token via
X-Customer-Token, or - no token when
allow_anonymous_postingis enabled
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
feedback_board_slug | string | yes | Target board slug |
name | string | yes | Item title, max 255 |
description | string | yes | Item description |
image | string | no | Base64-encoded image |
author | string | no | Optional display name |
tags | string[] | no | Array of tag ULIDs |
Response
Returns 201 Created.
{
"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
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | Updated title |
description | string|null | no | Updated description |
image | string|null | no | Base64 image, or empty / null to remove |
author | string | no | Optional author override |
tags | string[] | no | Replacement tag ULIDs |
Response
200 OK with the updated item.
Notes
- returns
401if the caller is not authenticated - returns
403if 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
{
"success": true,
"message": "Feedback item deleted successfully."
}Notes
- returns
401if the caller is not authenticated - returns
403if the item belongs to a different customer
Vote on Item
POST v1/feedback/items/{itemUlid}/voteToggles a vote on a feedback item.
Authentication
- customer token via
X-Customer-Token, or - anonymous vote with
anonymous: truewhenallow_anonymous_upvotingis enabled
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
anonymous | boolean | no | Set true for anonymous voting |
Response
{
"success": true,
"voted": true,
"votes": 43
}Notes
- anonymous voting requires the anonymous cookie or
X-Klero-Anon-Id - returns
400if anonymous voting is attempted without an anonymous identity
List Comments
GET v1/feedback/items/{itemUlid}/commentsReturns publicly visible comments for a feedback item.
Authentication
No authentication required.
Response
{
"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}/commentsCreates a comment or reply.
Authentication
- customer token via
X-Customer-Token, or - no token when
allow_anonymous_commentingis enabled
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
content | string | no* | Comment text, max 2000 |
image | string | no | Base64-encoded image |
parent_comment_ulid | string | no | Reply target |
author | string | no | Optional display name |
content is required when the request is anonymous. For authenticated requests, either content or image must be present.
Response
{
"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
403if 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
| Field | Type | Required | Description |
|---|---|---|---|
content | string|null | no | Updated text |
image | string|null | no | Base64 image, or empty / null to remove |
Response
200 OK with the updated comment payload.
Notes
- returns
401if the caller is not authenticated - returns
403if 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
{
"success": true,
"message": "Comment deleted successfully!"
}Notes
- returns
401if the caller is not authenticated - returns
403if the comment belongs to a different customer
Item Personalization
GET v1/feedback/items/{itemUlid}/personalizationReturns 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
{
"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}/likeToggles a like on a comment.
Authentication
- customer token via
X-Customer-Token, or - anonymous like with
anonymous: truewhenallow_anonymous_commentingis enabled
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
anonymous | boolean | no | Set true for anonymous liking |
Response
{
"success": true,
"liked": true,
"likes_count": 3
}Notes
- anonymous liking requires the anonymous cookie or
X-Klero-Anon-Id - returns
400if anonymous liking is attempted without an anonymous identity
Subscriptions
Subscription endpoints always require X-Customer-Token.
Get Subscription Status
GET v1/subscribeReturns:
{
"subscribed": true
}Unauthenticated requests return:
{
"subscribed": false
}Subscribe
POST v1/subscribeReturns:
{
"success": true,
"subscribed": true
}Unsubscribe
DELETE v1/subscribeReturns:
{
"success": true,
"subscribed": false
}