Source
This app’s code and revision history are public. Download a copy or explore the files below.
Public
The app’s code and revision history are public.
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 54b9c9d7fdc2b68029ce2e57
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
public/openapi.json
{
"openapi": "3.1.0",
"info": {
"title": "Feedback by OpenApps API",
"version": "1.0.0",
"summary": "Free feedback boards with voting, a public roadmap and a changelog.",
"description": "A free alternative to Canny. No account and no key: a board's id is its secret, like its link. POST /boards returns an ownerKey; send it in the x-owner-key header to change statuses, hide ideas, reply as the team and write the changelog. Votes come from people in the browser, one per person per idea; the API does not vote. Errors are JSON with an `error` sentence that says what to change. Guide for assistants: https://feedback-free.openapps.xyz/llms.txt",
"contact": {
"name": "OpenApps",
"url": "https://openapps.free/"
}
},
"externalDocs": {
"description": "llms.txt: the full guide for AI assistants",
"url": "https://feedback-free.openapps.xyz/llms.txt"
},
"servers": [
{
"url": "https://functions.openapps.xyz/apps/54b9c9d7fdc2b68029ce2e57/api"
}
],
"paths": {
"/boards": {
"post": {
"operationId": "createBoard",
"summary": "Create a feedback board",
"description": "Makes a board and returns its link, a private admin link and the owner key. Share url; keep adminUrl and ownerKey private.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 80
},
"intro": {
"type": "string",
"maxLength": 1000
},
"tags": {
"type": "array",
"maxItems": 20,
"items": {
"type": "string",
"maxLength": 24
},
"description": "Tag names. Defaults to [\"Idea\", \"Bug\"]."
}
}
},
"example": {
"name": "Acme feedback",
"intro": "Tell us what would make Acme better.",
"tags": [
"Idea",
"Bug"
]
}
}
}
},
"responses": {
"201": {
"description": "The new board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatedBoard"
},
"example": {
"boardId": "Hn4kWq8ZtR2mXc7pLs9a",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a",
"adminUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/admin#k=OWNER_KEY",
"ownerKey": "OWNER_KEY",
"board": {
"id": "Hn4kWq8ZtR2mXc7pLs9a",
"name": "Acme feedback",
"intro": null,
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a",
"roadmapUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/roadmap",
"changelogUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/changelog",
"tags": [
"Idea",
"Bug"
],
"posts": 0,
"byStatus": {
"new": 0,
"review": 0,
"planned": 0,
"progress": 0,
"done": 0,
"closed": 0
}
},
"note": "Share url with the people you want ideas from. Keep adminUrl and ownerKey private: they let anyone set statuses, hide posts and write the changelog."
}
}
}
},
"400": {
"description": "Missing or too long fields.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}": {
"get": {
"operationId": "getBoard",
"summary": "Read a board and its top requests",
"description": "The board, a count of ideas per status, and the ideas that match the filters. Pinned ideas come first.",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "sort",
"in": "query",
"description": "top (most votes), trending (votes and comments weighed by age) or new.",
"schema": {
"type": "string",
"enum": [
"top",
"trending",
"new"
],
"default": "top"
}
},
{
"name": "status",
"in": "query",
"description": "active (new, review, planned, progress), all, or one status.",
"schema": {
"type": "string",
"enum": [
"active",
"all",
"new",
"review",
"planned",
"progress",
"done",
"closed"
],
"default": "active"
}
},
{
"name": "tag",
"in": "query",
"description": "A tag name on the board, like Bug.",
"schema": {
"type": "string"
}
},
{
"name": "q",
"in": "query",
"description": "Words that must all appear in the title, details or tags.",
"schema": {
"type": "string"
}
},
{
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 500,
"default": 50
}
},
{
"name": "x-owner-key",
"in": "header",
"required": false,
"description": "Optional. With the board's owner key, hidden ideas are included.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The board and its matching ideas.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"board": {
"$ref": "#/components/schemas/Board"
},
"filter": {
"type": "object"
},
"matching": {
"type": "integer"
},
"posts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"example": {
"board": {
"id": "Hn4kWq8ZtR2mXc7pLs9a",
"name": "Acme feedback",
"intro": null,
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a",
"roadmapUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/roadmap",
"changelogUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/changelog",
"tags": [
"Idea",
"Bug"
],
"posts": 12,
"byStatus": {
"new": 7,
"review": 2,
"planned": 2,
"progress": 1,
"done": 0,
"closed": 0
}
},
"filter": {
"sort": "top",
"status": "active"
},
"matching": 12,
"posts": [
{
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "planned",
"statusLabel": "Planned",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
]
}
}
}
},
"400": {
"description": "A filter value is not one of the allowed ones.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No board with that id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}/roadmap": {
"get": {
"operationId": "getRoadmap",
"summary": "Read the public roadmap",
"description": "Ideas grouped by status: review, planned and progress (most voted first) and done (most recently finished first).",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": false,
"description": "Optional. With the board's owner key, hidden ideas are included.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The roadmap columns.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"board": {
"$ref": "#/components/schemas/Board"
},
"url": {
"type": "string",
"format": "uri"
},
"columns": {
"type": "object",
"properties": {
"review": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"posts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"planned": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"posts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"progress": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"posts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"done": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"posts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
}
}
}
}
},
"example": {
"board": {
"id": "Hn4kWq8ZtR2mXc7pLs9a",
"name": "Acme feedback",
"intro": null,
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a",
"roadmapUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/roadmap",
"changelogUrl": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/changelog",
"tags": [
"Idea",
"Bug"
],
"posts": 12,
"byStatus": {
"new": 7,
"review": 2,
"planned": 2,
"progress": 1,
"done": 0,
"closed": 0
}
},
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/roadmap",
"columns": {
"review": {
"label": "Under review",
"posts": []
},
"planned": {
"label": "Planned",
"posts": [
{
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "planned",
"statusLabel": "Planned",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
]
},
"progress": {
"label": "In progress",
"posts": []
},
"done": {
"label": "Done",
"posts": []
}
}
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No board with that id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}/posts": {
"post": {
"operationId": "createPost",
"summary": "Post an idea or bug report",
"description": "Adds an idea to the board. It starts with one vote, from the API. Also takes an HTML form post (urlencoded or multipart, fields title, details, tag, name) and then answers with a thank-you page; a filled _gotcha field is quietly dropped.",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/NewPost"
},
"example": {
"title": "Export reports to CSV",
"details": "Our finance team needs the monthly totals in a spreadsheet.",
"tags": [
"Idea"
],
"name": "Sam"
}
},
"application/x-www-form-urlencoded": {
"schema": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string"
},
"details": {
"type": "string"
},
"tag": {
"type": "string"
},
"name": {
"type": "string"
},
"_gotcha": {
"type": "string"
}
}
}
},
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string"
},
"details": {
"type": "string"
},
"tag": {
"type": "string"
},
"name": {
"type": "string"
},
"_gotcha": {
"type": "string"
}
}
}
}
}
},
"responses": {
"201": {
"description": "The new idea.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Post"
},
"example": {
"id": "Qm3TfVb8KpXa",
"title": "Export reports to CSV",
"details": "Easier on the eyes at night.",
"status": "new",
"statusLabel": "New",
"votes": 1,
"comments": 0,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa",
"note": "Posted. It starts with one vote, from the API. People vote on it at url."
}
},
"text/html": {
"schema": {
"type": "string",
"description": "For an HTML form post (unless the request accepts application/json): a short thank-you page linking to the idea and back to the referring site."
}
}
}
},
"400": {
"description": "Missing title, too long fields, or a tag the board does not have.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No board with that id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}/posts/{postId}": {
"get": {
"operationId": "getPost",
"summary": "Read one idea with its comments",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "postId",
"in": "path",
"required": true,
"description": "The idea's id: the characters after /p/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{6,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": false,
"description": "Optional. With the board's owner key, hidden ideas are included.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "The idea, its comments and the changelog entries that shipped it.",
"content": {
"application/json": {
"schema": {
"allOf": [
{
"$ref": "#/components/schemas/Post"
},
{
"type": "object",
"properties": {
"commentList": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Comment"
}
},
"shippedIn": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"publishedAt": {
"type": "string",
"format": "date-time"
},
"url": {
"type": "string",
"format": "uri"
}
}
}
}
}
}
]
},
"example": {
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "planned",
"statusLabel": "Planned",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa",
"commentList": [
{
"id": "Zt7RkPq2WmXa",
"body": "We need this for our audit too.",
"author": "Ana",
"team": false,
"at": "2026-10-19T13:00:00.000Z"
}
],
"shippedIn": []
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No idea with that id on this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"patch": {
"operationId": "updatePost",
"summary": "Change an idea's status, tags, pin or visibility (owner)",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "postId",
"in": "path",
"required": true,
"description": "The idea's id: the characters after /p/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{6,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": true,
"description": "The board's owner key, from POST /boards or the admin link.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"status": {
"type": "string",
"description": "new, review, planned, progress, done or closed. Also accepts \"under review\", \"in progress\", \"complete\" and \"shipped\"."
},
"title": {
"type": "string",
"maxLength": 140
},
"details": {
"type": "string",
"maxLength": 5000
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"pinned": {
"type": "boolean"
},
"hidden": {
"type": "boolean"
}
}
},
"example": {
"status": "in progress"
}
}
}
},
"responses": {
"200": {
"description": "The updated idea.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Post"
},
"example": {
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "progress",
"statusLabel": "In progress",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
}
}
},
"400": {
"description": "A value is not allowed.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "No owner key was sent.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No idea with that id on this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}/posts/{postId}/comments": {
"post": {
"operationId": "createComment",
"summary": "Comment on an idea",
"description": "With the owner key, the comment is marked as a reply from the team.",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "postId",
"in": "path",
"required": true,
"description": "The idea's id: the characters after /p/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{6,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": false,
"description": "Optional. With the board's owner key, hidden ideas are included.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"body"
],
"properties": {
"body": {
"type": "string",
"maxLength": 3000
},
"name": {
"type": "string",
"maxLength": 60
}
}
},
"example": {
"body": "We need this for our audit too.",
"name": "Ana"
}
}
}
},
"responses": {
"201": {
"description": "The new comment.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"body": {
"type": "string"
},
"author": {
"type": [
"string",
"null"
]
},
"team": {
"type": "boolean"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
"example": {
"id": "Zt7RkPq2WmXa",
"body": "We need this for our audit too.",
"author": "Ana",
"team": false,
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
}
}
},
"400": {
"description": "Missing or too long body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No idea with that id on this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/boards/{boardId}/changelog": {
"get": {
"operationId": "getChangelog",
"summary": "Read the changelog",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": false,
"description": "Optional. With the board's owner key, hidden ideas are included.",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "Entries, newest first.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"board": {
"type": "object"
},
"url": {
"type": "string",
"format": "uri"
},
"entries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Entry"
}
}
}
},
"example": {
"board": {
"id": "Hn4kWq8ZtR2mXc7pLs9a",
"name": "Acme feedback",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a"
},
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/changelog",
"entries": [
{
"id": "Lp4XqWn7TzRa",
"title": "Dark mode is here",
"body": "It follows your system setting.",
"publishedAt": "2026-10-19T15:00:00.000Z",
"shipped": [
{
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "done",
"statusLabel": "Done",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
]
}
]
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No board with that id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
},
"post": {
"operationId": "createChangelogEntry",
"summary": "Publish a changelog entry (owner)",
"description": "Links the ideas it shipped, so their voters see it, and by default marks them done.",
"parameters": [
{
"name": "boardId",
"in": "path",
"required": true,
"description": "The board's id: the 20 characters after /b/ in its link.",
"schema": {
"type": "string",
"pattern": "^[A-Za-z0-9]{8,32}$"
}
},
{
"name": "x-owner-key",
"in": "header",
"required": true,
"description": "The board's owner key, from POST /boards or the admin link.",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"maxLength": 140
},
"body": {
"type": "string",
"maxLength": 10000,
"description": "Markdown."
},
"posts": {
"type": "array",
"maxItems": 50,
"items": {
"type": "string"
},
"description": "Ids of the ideas it shipped."
},
"markDone": {
"type": "boolean",
"default": true
}
}
},
"example": {
"title": "Dark mode is here",
"body": "It follows your system setting. Thanks to everyone who voted.",
"posts": [
"Qm3TfVb8KpXa"
],
"markDone": true
}
}
}
},
"responses": {
"201": {
"description": "The new entry.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"shipped": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
},
"example": {
"id": "Lp4XqWn7TzRa",
"title": "Dark mode is here",
"body": "It follows your system setting. Thanks to everyone who voted.",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/changelog",
"shipped": [
{
"id": "Qm3TfVb8KpXa",
"title": "Dark mode",
"details": "Easier on the eyes at night.",
"status": "done",
"statusLabel": "Done",
"votes": 42,
"comments": 5,
"tags": [
"Idea"
],
"pinned": false,
"author": "Sam",
"createdAt": "2026-10-19T12:00:00.000Z",
"url": "https://feedback-free.openapps.xyz/b/Hn4kWq8ZtR2mXc7pLs9a/p/Qm3TfVb8KpXa"
}
]
}
}
}
},
"400": {
"description": "Missing title, or a post id that is not on this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "No owner key was sent.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"403": {
"description": "The owner key does not match this board.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "No board with that id.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Error": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string",
"description": "A sentence that says what to change."
}
}
},
"Board": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"intro": {
"type": [
"string",
"null"
]
},
"url": {
"type": "string",
"format": "uri"
},
"roadmapUrl": {
"type": "string",
"format": "uri"
},
"changelogUrl": {
"type": "string",
"format": "uri"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"posts": {
"type": "integer"
},
"byStatus": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
}
}
},
"CreatedBoard": {
"type": "object",
"properties": {
"boardId": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"adminUrl": {
"type": "string",
"format": "uri",
"description": "Private: opens the board as an owner on any device."
},
"ownerKey": {
"type": "string",
"description": "Private: send as x-owner-key for owner actions."
},
"board": {
"$ref": "#/components/schemas/Board"
},
"note": {
"type": "string"
}
}
},
"NewPost": {
"type": "object",
"required": [
"title"
],
"properties": {
"title": {
"type": "string",
"maxLength": 140
},
"details": {
"type": "string",
"maxLength": 5000,
"description": "Markdown."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"description": "Tag names from the board."
},
"name": {
"type": "string",
"maxLength": 60,
"description": "Author name shown with the idea."
}
}
},
"Post": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"details": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"new",
"review",
"planned",
"progress",
"done",
"closed"
]
},
"statusLabel": {
"type": "string"
},
"votes": {
"type": "integer"
},
"comments": {
"type": "integer"
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"pinned": {
"type": "boolean"
},
"hidden": {
"type": "boolean",
"description": "Present and true only for hidden ideas, which only owners see."
},
"mergedInto": {
"type": "string",
"description": "Present when the idea was merged into another one."
},
"author": {
"type": [
"string",
"null"
]
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"url": {
"type": "string",
"format": "uri"
}
}
},
"Comment": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"body": {
"type": "string"
},
"author": {
"type": [
"string",
"null"
]
},
"team": {
"type": "boolean"
},
"at": {
"type": "string",
"format": "date-time"
}
}
},
"Entry": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"body": {
"type": "string"
},
"publishedAt": {
"type": "string",
"format": "date-time"
},
"shipped": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Post"
}
}
}
}
}
}
}
Change history
Point store links to openapps.free
Release with preview
Retry release
Bind app agent address in policy
Use OpenApps service URLs and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync