The public API behind the feedback board. CORS is open to any origin, so you can call it from your own frontend. For a walkthrough, see Build your own UI.
Objects#
Post
json
{
"id": "fb_k2j3h4g5f6d7",
"title": "Dark mode for the dashboard",
"description": "Working late nights and the bright dashboard is rough on the eyes.",
"status": "planned",
"authorName": "Priya",
"votes": 42,
"comments": 2,
"voted": true,
"createdAt": "2026-09-09T08:53:52.962Z",
"updatedAt": "2026-09-12T10:01:00.000Z"
}idstringrequiredUnique id.
titlestringrequiredUp to 120 characters.
descriptionstringrequiredUp to 4000 characters. May be empty.
statusstringrequiredOne of
open, planned, in_progress, done, closed.authorNamestringoptionalOmitted when the author didn’t give a name.
votesnumberrequiredUpvote count.
commentsnumberrequiredComment count.
votedbooleanrequiredWhether the visitor in
x-visitor-id has upvoted. false when no header is sent.createdAt / updatedAtstringrequiredISO 8601 timestamps.
Comment
json
{
"id": "fbc_a1b2c3d4e5f6",
"postId": "fb_k2j3h4g5f6d7",
"author": "agent",
"name": "Alex from Acme",
"body": "This is on the roadmap for next quarter.",
"createdAt": "2026-09-12T10:01:00.000Z"
}author is "customer" for your users and "agent" for your team’s official replies. name is omitted when not given. Visitor ids are never returned.
Endpoints#
List posts#
GET
/api/feedbacksortqueryoptionaltop (most votes, then newest) or new. Default top.statusqueryoptionalOnly posts with this status.
qqueryoptionalSearch text, matched against title and description.
x-visitor-idheaderoptionalFills in
voted.200 OK
{
"posts": [ /* Post, up to 200 */ ],
"counts": { "open": 4, "planned": 1, "in_progress": 1, "done": 1, "closed": 1, "all": 8 }
}Create a post#
POST
/api/feedbackx-visitor-idheaderrequiredThe author.
titlestringrequiredTrimmed; up to 120 characters.
descriptionstringoptionalUp to 4000 characters.
namestringoptionalAuthor’s display name; up to 80 characters.
Returns 201 with { "post": Post }. The author’s upvote is added automatically, so the post starts with votes: 1, voted: true.
Get a post with its comments#
GET
/api/feedback/:id200 OK
{ "post": { /* Post */ }, "comments": [ /* Comment, oldest first */ ] }Upvote or remove an upvote#
POST
/api/feedback/:id/votex-visitor-idheaderrequiredThe voter.
votedbooleanoptionaltrue to upvote (default), false to remove.Idempotent: upvoting twice still counts once. Returns { "post": Post } with the updated votes and voted.
Add a comment#
POST
/api/feedback/:id/commentsx-visitor-idheaderrequiredThe commenter.
bodystringrequiredUp to 2000 characters.
namestringoptionalDisplay name; up to 80 characters.
Returns 201 with { "comment": Comment }.
Errors#
CORS#
http
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: content-type, x-visitor-id
Access-Control-Max-Age: 86400Note
Changing a post’s status, editing it or deleting it is done by you in the inbox (see the Owner API), never through the public API.