Skip to main content

Create Post

Create a new feedback post.
const res = await client.post.create.$post({
  title: "Add dark mode support",
  content: "It would be great to have a dark mode option for the app.",
  workspaceSlug: "acme",
  boardSlug: "features",
  tags: ["tag-id-1", "tag-id-2"],
  roadmapStatus: "pending",
  fingerprint: "browser-fingerprint" // For anonymous users
})
const { post } = await res.json()
Type: Public Procedure
title
string
required
Post title (1-256 characters)
content
string
required
Post content/description
workspaceSlug
string
required
Workspace slug
boardSlug
string
required
Board slug where post will be created
tags
string[]
Array of tag IDs to attach
image
string
Cover image URL
roadmapStatus
string
Initial status (default: “pending”)
fingerprint
string
Browser fingerprint for anonymous users
Authentication:
  • Authenticated users: Creates post with their user ID
  • Anonymous users: Requires fingerprint if board allows anonymous posting
  • Private boards: Requires workspace membership
Automatic Actions:
  • Post is automatically upvoted by creator
  • Generates URL-friendly slug
  • Triggers webhook notifications
  • Logs activity

Update Post

Update an existing post.
const res = await client.post.update.$post({
  postId: "post-123",
  title: "Updated title",
  content: "Updated content",
  tags: ["new-tag-id"],
  roadmapStatus: "planned"
})
const { post } = await res.json()
Type: Private Procedure
postId
string
required
Post ID to update
title
string
New title
content
string
New content
image
string | null
New cover image (null to remove)
boardSlug
string
Move to different board
roadmapStatus
string
Update status
tags
string[]
New tags (replaces existing)
Permissions:
  • Post author can edit their own post
  • Workspace owner can edit any post
  • Admins with moderation permission can edit

Delete Post

Permanently delete a post.
const res = await client.post.delete.$post({ 
  postId: "post-123" 
})
const { success } = await res.json()
Type: Private Procedure
postId
string
required
Post ID to delete
Permissions:
  • Post author can delete their own post
  • Workspace owner can delete any post
  • Admins with moderation permission can delete
Deleting a post also deletes all associated comments, votes, and activity logs.

Vote on Post

Upvote or remove upvote from a post.
// Authenticated user
const res = await client.post.vote.$post({ 
  postId: "post-123" 
})

// Anonymous user
const res = await client.post.vote.$post({ 
  postId: "post-123",
  fingerprint: "browser-fingerprint"
})

const { upvotes, hasVoted } = await res.json()
Type: Public Procedure
postId
string
required
Post ID to vote on
fingerprint
string
Required for anonymous users
upvotes
number
Updated vote count
hasVoted
boolean
Whether user has voted after this action
Behavior:
  • First call: Adds upvote
  • Second call: Removes upvote (toggle)
  • One vote per user/fingerprint

Get Vote Status

Check if user has voted on a post.
const res = await client.post.getVoteStatus.$get({ 
  postId: "post-123",
  fingerprint: "browser-fingerprint" // For anonymous
})
const { hasVoted } = await res.json()
Type: Public Procedure

Report Post

Report a post for moderation.
const res = await client.post.report.$post({
  postId: "post-123",
  reason: "spam",
  description: "This is a spam post advertising products"
})
Type: Private Procedure
postId
string
required
Post ID to report
reason
string
required
Reason for report (spam, offensive, duplicate, other)
description
string
Additional details
Actions:
  • Creates report record with “pending” status
  • Sends email notification to workspace owner
  • Logs activity with report count

Get Similar Posts

Find similar posts based on title matching.
const res = await client.post.getSimilar.$get({
  title: "Add dark mode",
  boardSlug: "features",
  workspaceSlug: "acme"
})
const { posts } = await res.json()
Type: Public Procedure
title
string
required
Post title to match against
boardSlug
string
required
Board to search in
workspaceSlug
string
required
Workspace slug
posts
array
Up to 3 similar posts sorted by relevance
Use Case: Show duplicate suggestions when users create new posts.

Merge Posts

Merge duplicate posts together.
const res = await client.post.merge.$post({
  postId: "post-123",
  targetPostId: "post-456",
  mergeType: "merge_into",
  reason: "Duplicate feature request"
})
const { success, merge } = await res.json()
Type: Private Procedure (requires moderation permission)
postId
string
required
Source post ID (will be archived)
targetPostId
string
required
Target post ID (receives merged data)
mergeType
string
required
Merge type (“merge_into” or “merge_here”)
reason
string
Reason for merge
Merge Actions:
  • Consolidates upvotes into target post
  • Transfers all comments to target
  • Transfers unique tags
  • Archives source post
  • Sets duplicateOfId reference
  • Logs merge activity

Merge Multiple Posts Here

Merge multiple posts into current post.
const res = await client.post.mergeHere.$post({
  postId: "post-123",
  sourcePostIds: ["post-456", "post-789"],
  reason: "Consolidating duplicate requests"
})
const { success } = await res.json()
Type: Private Procedure (requires moderation permission)
postId
string
required
Target post ID (receives all merged data)
sourcePostIds
string[]
required
Array of source post IDs to merge in
reason
string
Reason for merge

Search Merge Candidates

Search for potential posts to merge with.
const res = await client.post.searchMergeCandidates.$get({
  postId: "post-123",
  query: "dark mode",
  excludeSelf: true
})
const { candidates } = await res.json()
Type: Public Procedure
postId
string
required
Current post ID
query
string
Search query (searches in same workspace)
excludeSelf
boolean
Whether to exclude current post from results
candidates
array
Auto-Suggestions: If no query is provided, suggests posts with similar titles.

Example: Complete Post Creation Flow

// 1. Check for similar posts before creating
const similarRes = await client.post.getSimilar.$get({
  title: "Add dark mode support",
  boardSlug: "features",
  workspaceSlug: "acme"
})
const { posts: similar } = await similarRes.json()

if (similar.length > 0) {
  // Show duplicates to user
  console.log("Similar posts found:", similar)
}

// 2. Get available tags
const tagsRes = await client.board.tagsByWorkspaceSlug.$get({ 
  slug: "acme" 
})
const { tags } = await tagsRes.json()

// 3. Create the post
const createRes = await client.post.create.$post({
  title: "Add dark mode support",
  content: "Users want a dark mode for better readability at night.",
  workspaceSlug: "acme",
  boardSlug: "features",
  tags: [tags[0].id], // UI tag
  image: "https://example.com/mockup.png"
})
const { post } = await createRes.json()

// 4. Post is automatically upvoted by creator
console.log(post.upvotes) // 1

Build docs developers (and LLMs) love