## Create a new comment **post** `/v2/comments` Creates a new comment or reply to an existing comment. You can create a comment for a post or changelog. Comments support: - HTML content (images are automatically uploaded to our storage) - Threading (replies via `parentCommentId`) - Privacy controls (private comments visible only to admins) - Author attribution (post on behalf of users) ### Required Fields - `content` - Comment content in HTML format - `postId` OR `changelogId` - One is required to specify the target ### Optional Fields - `parentCommentId` - Create a reply to an existing comment - `isPrivate` - Make comment visible only to admins (default: false) - `sendNotification` - Notify voters about the comment (default: true) - `author` - Post comment under a specific user (uses authenticated user if not provided) - `createdAt` - Backdate creation (useful for imports) ### Author Object The `author` field supports multiple identification methods: - `id` - Featurebase user ID (direct reference) - `userId` - External user ID from your system (via SSO) - `email` - Email address (finds existing or creates new user) - `name` - Display name (used with email for new users) - `profilePicture` - Profile picture URL If no author is provided, the comment is posted under the authenticated user. ### Content Format Content should be formatted as HTML. For images: - External URLs in `img src` attributes are automatically pulled into our storage - Base64 encoded data URIs (`data:image/...`) are also supported and processed ### Response Returns the created comment object with all fields populated, including: - `id` - Unique comment identifier - `author` - Author information - Voting stats and timestamps ### Errors - `400` - Invalid input (missing required fields, invalid IDs) - `403` - Commenting disabled or not authorized - `404` - Post/changelog not found or parent comment not found ### Header Parameters - `"Featurebase-Version": optional "2026-01-01.nova" or "2025-12-12.clover"` - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Body Parameters - `content: string` Comment content in HTML format - `author: optional AuthorInput` Author to attribute the post to. If not provided, uses the authenticated user. Supports multiple identification methods: id (Featurebase ID), userId (external SSO ID), or email. - `id: optional string` Featurebase user ID to attribute content to - `email: optional string` Author email (used to find or create user) - `name: optional string` Author display name - `profilePicture: optional string` Author profile picture URL - `userId: optional string` External user ID from your system (matched via SSO) - `changelogId: optional string` Changelog ID to comment on (accepts ObjectId or slug) - `createdAt: optional string` Set the date when the comment was created. Useful for importing comments from other platforms. - `downvotes: optional number` Initial downvotes count. Useful for importing comments from other platforms. Score will be calculated as upvotes - downvotes. - `isPrivate: optional boolean` Whether the comment is private (only visible to admins) - `parentCommentId: optional string` Parent comment ID if this is a reply - `postId: optional string` Post ID to comment on (accepts ObjectId or slug) - `sendNotification: optional boolean` Whether to notify voters of the submission about the comment - `upvotes: optional number` Initial upvotes count. Useful for importing comments from other platforms. Score will be calculated as upvotes - downvotes. ### Returns - `Comment object { id, author, changelogId, 14 more }` - `id: string` Unique identifier - `author: object { id, name, profilePicture, type }` - `id: string` Author unique identifier - `name: string` Author display name - `profilePicture: string` Author profile picture URL - `type: "admin" or "customer" or "guest" or 3 more` Type of user who authored the comment - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `changelogId: string` Changelog ID this comment belongs to - `content: string` Comment content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `downvotes: number` Number of downvotes - `inReview: boolean` Whether the comment is in review - `isDeleted: boolean` Whether the comment is deleted - `isPinned: boolean` Whether the comment is pinned - `isPrivate: boolean` Whether the comment is private - `isSpam: boolean` Whether the comment is spam - `object: "comment"` Object type identifier - `"comment"` - `parentCommentId: string` Parent comment ID for replies, null for root comments - `postId: string` Post ID this comment belongs to - `score: number` Net score (upvotes - downvotes) - `updatedAt: string` ISO 8601 timestamp when updated - `upvotes: number` Number of upvotes ### Example ```http curl https://do.featurebase.app/v2/comments \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $FEATUREBASE_API_KEY" \ -d '{ "content": "
This is a great idea!
", "changelogId": "507f1f77bcf86cd799439012", "createdAt": "2025-01-15T10:30:00.000Z", "parentCommentId": "507f1f77bcf86cd799439013", "postId": "507f1f77bcf86cd799439011", "sendNotification": true, "upvotes": 5 }' ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "author": { "id": "507f1f77bcf86cd799439011", "name": "John Doe", "profilePicture": "https://cdn.example.com/avatars/john.png", "type": "customer" }, "changelogId": "507f1f77bcf86cd799439013", "content": "This is a great idea!
", "createdAt": "2023-12-12T00:00:00.000Z", "downvotes": 0, "inReview": false, "isDeleted": false, "isPinned": false, "isPrivate": false, "isSpam": false, "object": "comment", "parentCommentId": "507f1f77bcf86cd799439014", "postId": "507f1f77bcf86cd799439012", "score": 5, "updatedAt": "2023-12-13T00:00:00.000Z", "upvotes": 5 } ```