# Posts ## List all posts `client.feedback.posts.list(PostListParamsparams?, RequestOptionsoptions?): CursorPage` **get** `/v2/posts` Returns all posts (feedback submissions) for the authenticated organization. Posts are user-submitted feedback items. Each post belongs to a board and can have: - Status (in progress, complete, etc.) - Tags for categorization - Upvotes from users - Comments (if enabled) - Custom field values ### Pagination This endpoint uses **cursor-based pagination**: - `limit` - Number of posts to return (1-100, default 10) - `cursor` - Opaque cursor from a previous response's `nextCursor` field **Example:** To paginate through results: 1. First request: `GET /v2/posts?limit=10` 1. If `nextCursor` is not null, use it for the next page 1. Next request: `GET /v2/posts?limit=10&cursor={nextCursor}` ### Response Format Returns a list object with: - `object` - Always "list" - `data` - Array of post objects - `nextCursor` - Cursor for the next page (null if no more results) ### Filtering Filter posts using query parameters: - `boardId` - Filter by board (category) ID - `statusId` - Filter by status ID - `tags` - Filter by tag names (can be comma-separated or repeated) - `q` - Search query for title/content - `inReview` - Include posts pending moderation ### Sorting Use `sortBy` to sort results: - `createdAt` - Sort by creation date (default) - `upvotes` - Sort by vote count - `trending` - Sort by trending score - `recent` - Sort by most recently updated ### Parameters - `params: PostListParams` - `boardId?: string | Array` Query param: Filter by board (category) ID(s) - `string` - `Array` - `cursor?: string` Query param: An opaque cursor for pagination. Use the nextCursor value from a previous response to fetch the next page of results. - `inReview?: boolean | null` Query param: Include posts that are in review - `limit?: number` Query param: A limit on the number of posts to be returned, between 1 and 100. - `q?: string` Query param: Search query to filter posts by title/content - `sortBy?: "createdAt" | "upvotes" | "trending" | "recent"` Query param: Sort order for posts - `"createdAt"` - `"upvotes"` - `"trending"` - `"recent"` - `sortOrder?: "asc" | "desc"` Query param: Sort direction - `"asc"` - `"desc"` - `statusId?: string | Array` Query param: Filter by status ID(s) - `string` - `Array` - `tags?: string | Array` Query param: Filter by tag names - `string` - `Array` - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `Post` - `id: string` Unique identifier - `access: Access` - `companyExternalIds: Array` External company IDs explicitly granted access to this post. Empty array means no company-level restrictions. Non-empty means only users belonging to these companies can see the post. - `userIds: Array` User IDs explicitly granted access to this post. Empty array means no user-level restrictions (post uses board/org visibility). Non-empty means only these users (plus admins) can see the post. - `assigneeId: string | null` ID of the admin assigned to this post, null if unassigned - `author: Author | null` - `id: string | null` Author unique identifier - `email: string | null` Author email (if available) - `name: string` Author display name - `profilePicture: string | null` Author profile picture URL - `type: "admin" | "customer" | "guest" | 3 more` Type of user who authored the post - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `boardId: string` Board (category) ID this post belongs to - `commentCount: number` Total number of comments - `content: string` Post content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `customFields: Record` Custom field values keyed by field ID - `eta: string | null` Estimated completion time as ISO 8601 timestamp, null if not set - `features: Features` - `commentsEnabled: boolean` Whether comments are allowed on this post - `inReview: boolean` Whether the post is pending moderation review - `integrations: Integrations` Third-party integration links associated with this post - `clickup: Array` - `id: string` ClickUp task ID - `title: string` ClickUp task title - `url: string` URL to the ClickUp task - `devops: Array` - `id: number` Azure DevOps work item ID - `projectId: string` Azure DevOps project ID - `projectName: string` Azure DevOps project name - `title: string` Work item title - `url: string` URL to the work item - `github: Array` - `id: string` GitHub issue ID - `number: string` GitHub issue number - `repositoryFullName: string` Full repository name (owner/repo) - `repositoryName: string` Repository name - `title: string` GitHub issue title - `url: string` URL to the GitHub issue - `hubspot: Array` - `dealAmount: number | null` Deal amount (for DEAL type) - `dealClosed: boolean | null` Whether the deal is closed (for DEAL type) - `objectId: number` HubSpot object ID - `type: "TICKET" | "DEAL" | "CONTACT"` HubSpot object type - `"TICKET"` - `"DEAL"` - `"CONTACT"` - `jira: Array` - `issueId: string` Jira issue ID - `issueUrl: string | null` URL to the Jira issue - `linear: Array` - `issueId: string` Linear issue ID - `issueUrl: string | null` URL to the Linear issue - `salesforce: Array` - `amount: number | null` Opportunity amount (for Opportunity type) - `isClosed: boolean | null` Whether the opportunity is closed (for Opportunity type) - `objectId: string` Salesforce record ID - `objectType: "Opportunity" | "Case"` Salesforce object type - `"Opportunity"` - `"Case"` - `isPinned: boolean` Whether the post is pinned to the top - `object: "post"` Object type identifier - `"post"` - `opportunityAmount: number | null` Total opportunity amount from linked HubSpot deals and Salesforce opportunities - `postUrl: string` Full URL to view the post - `slug: string` URL-friendly slug - `status: PostStatus` - `id: string` Unique identifier - `color: string` Color for UI display - `isDefault: boolean` Whether this is the default status for new posts - `name: string` Display name - `object: "post_status"` Object type identifier - `"post_status"` - `type: "reviewing" | "unstarted" | "active" | 2 more` The workflow stage this status represents - `"reviewing"` - `"unstarted"` - `"active"` - `"completed"` - `"canceled"` - `tags: Array` Tags attached to this post - `id: string` Tag unique identifier - `color: string | null` Tag color hex code - `name: string` Tag name - `title: string` Post title - `updatedAt: string` ISO 8601 timestamp when last modified - `upvotes: number` Total number of upvotes ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); // Automatically fetches more pages as needed. for await (const post of client.feedback.posts.list()) { console.log(post.id); } ``` #### Response ```json { "data": [ { "id": "507f1f77bcf86cd799439011", "access": { "companyExternalIds": [ "string" ], "userIds": [ "string" ] }, "assigneeId": "507f1f77bcf86cd799439013", "author": { "id": "507f1f77bcf86cd799439011", "email": "john@example.com", "name": "John Doe", "profilePicture": "https://cdn.example.com/avatars/john.png", "type": "customer" }, "boardId": "507f1f77bcf86cd799439011", "commentCount": 5, "content": "

It would be great to have a dark mode option for the dashboard.

", "createdAt": "2023-12-12T00:00:00.000Z", "customFields": { "cf_priority": "bar", "cf_effort": "bar" }, "eta": "2025-01-01T00:00:00.000Z", "features": { "commentsEnabled": true }, "inReview": false, "integrations": { "clickup": [ { "id": "86a1b2c3d", "title": "Add dark mode support", "url": "https://app.clickup.com/t/86a1b2c3d" } ], "devops": [ { "id": 1234, "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "projectName": "My Project", "title": "Add dark mode support", "url": "https://dev.azure.com/org/project/_workitems/edit/1234" } ], "github": [ { "id": "1234567890", "number": "42", "repositoryFullName": "acme/backend", "repositoryName": "backend", "title": "Add dark mode support", "url": "https://github.com/acme/backend/issues/42" } ], "hubspot": [ { "dealAmount": 5000, "dealClosed": false, "objectId": 123456789, "type": "TICKET" } ], "jira": [ { "issueId": "10042", "issueUrl": "https://myteam.atlassian.net/browse/PROJ-123" } ], "linear": [ { "issueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "issueUrl": "https://linear.app/team/issue/ENG-123" } ], "salesforce": [ { "amount": 25000, "isClosed": false, "objectId": "006Dn00000Abcdef", "objectType": "Opportunity" } ] }, "isPinned": false, "object": "post", "opportunityAmount": 30000, "postUrl": "https://feedback.example.com/p/add-dark-mode-support", "slug": "add-dark-mode-support", "status": { "id": "507f1f77bcf86cd799439011", "color": "Blue", "isDefault": false, "name": "In Progress", "object": "post_status", "type": "active" }, "tags": [ { "id": "507f1f77bcf86cd799439011", "color": "#FF5722", "name": "bug" } ], "title": "Add dark mode support", "updatedAt": "2023-12-13T00:00:00.000Z", "upvotes": 42 } ], "nextCursor": "eyJpZCI6IjUwN2YxZjc3YmNmODZjZDc5OTQzOTAxMSJ9", "object": "list", "pagination": { "limit": 10, "page": 1, "total": 42, "totalPages": 5 } } ``` ## Create a new post `client.feedback.posts.create(PostCreateParamsparams, RequestOptionsoptions?): Post` **post** `/v2/posts` Creates a new post (feedback submission) in the specified board. ### Required Fields - `title` - Post title (minimum 2 characters) - `boardId` - Board ID to create the post in ### Optional Fields - `content` - Post content in HTML format - `tags` - Array of tag names to attach - `statusId` - Status ID to set (defaults to board's default status) - `commentsEnabled` - Whether comments are allowed (default: true) - `inReview` - Whether post is pending moderation (default: false) - `customFields` - Custom field values as key-value pairs - `eta` - Estimated completion date (Unix timestamp or ISO date) - `assigneeId` - Admin ID to assign this post to - `visibility` - Post-level visibility restriction: 'public' (no additional restrictions), 'authorOnly' (only author and admins), or 'companyOnly' (only users in author's company). Note: even 'public' posts are still subject to board-level and organization-level access controls. ### Author Attribution For posts created on behalf of users, use the `author` object: - `id` - Featurebase user ID - `userId` - External SSO user ID - `email` - User's email address - `name` - Display name - `profilePicture` - Profile picture URL Resolution priority: `id` > `userId` > `email` > authenticated user ### Backdating (Imports) - `createdAt` - Override creation date for importing historical data ### Response Returns the created post object with all fields populated. ### Parameters - `params: PostCreateParams` - `boardId: string` Body param: Board ID to create post in - `title: string` Body param: Post title - `assigneeId?: string` Body param: Admin ID to assign this post to - `author?: AuthorInput` Body param: 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?: string` Featurebase user ID to attribute content to - `email?: string` Author email (used to find or create user) - `name?: string` Author display name - `profilePicture?: string` Author profile picture URL - `userId?: string` External user ID from your system (matched via SSO) - `commentsEnabled?: boolean | null` Body param: Whether comments are enabled on this post - `content?: string` Body param: Post content (HTML) - `createdAt?: string | null` Body param: Creation date (for backdating imports) - `customFields?: Record | boolean | number | 2 more>` Body param: Custom field values. Keys must be valid ObjectIds. Values can be: string, boolean, number, ISO date string, array of strings, ObjectId string, or null. - `Array` - `boolean` - `number` - `string` - `string | null` - `eta?: string | null` Body param: Estimated completion date - `inReview?: boolean | null` Body param: Whether post is pending moderation - `integrations?: Integrations` Body param: Push the created post to third-party integrations configured on your organization. Each integration must be explicitly set to true to trigger; omitted integrations will not be pushed to. - `clickup?: boolean` Push to ClickUp - `discord?: boolean` Push to Discord - `github?: boolean` Push to GitHub - `jira?: boolean` Push to Jira - `linear?: boolean` Push to Linear - `slack?: boolean` Push to Slack - `notifyAdmins?: boolean` Body param: Whether to send email notifications to admins when this post is created. When true, admins will receive the same email notifications as when a post is created from the dashboard. Defaults to false (no emails sent). - `statusId?: string` Body param: Status ID to set - `tags?: string | Array` Body param: Tag names to attach - `string` - `Array` - `upvotes?: number | null` Body param: Initial upvotes count. Defaults to 1 (post author is automatically added as voter). Use 0 to create a post without any votes. - `visibility?: "public" | "authorOnly" | "companyOnly"` Body param: Post visibility. 'public' = visible to all users, 'authorOnly' = only visible to the author and admins, 'companyOnly' = only visible to users in the same company as the author - `"public"` - `"authorOnly"` - `"companyOnly"` - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `Post` - `id: string` Unique identifier - `access: Access` - `companyExternalIds: Array` External company IDs explicitly granted access to this post. Empty array means no company-level restrictions. Non-empty means only users belonging to these companies can see the post. - `userIds: Array` User IDs explicitly granted access to this post. Empty array means no user-level restrictions (post uses board/org visibility). Non-empty means only these users (plus admins) can see the post. - `assigneeId: string | null` ID of the admin assigned to this post, null if unassigned - `author: Author | null` - `id: string | null` Author unique identifier - `email: string | null` Author email (if available) - `name: string` Author display name - `profilePicture: string | null` Author profile picture URL - `type: "admin" | "customer" | "guest" | 3 more` Type of user who authored the post - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `boardId: string` Board (category) ID this post belongs to - `commentCount: number` Total number of comments - `content: string` Post content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `customFields: Record` Custom field values keyed by field ID - `eta: string | null` Estimated completion time as ISO 8601 timestamp, null if not set - `features: Features` - `commentsEnabled: boolean` Whether comments are allowed on this post - `inReview: boolean` Whether the post is pending moderation review - `integrations: Integrations` Third-party integration links associated with this post - `clickup: Array` - `id: string` ClickUp task ID - `title: string` ClickUp task title - `url: string` URL to the ClickUp task - `devops: Array` - `id: number` Azure DevOps work item ID - `projectId: string` Azure DevOps project ID - `projectName: string` Azure DevOps project name - `title: string` Work item title - `url: string` URL to the work item - `github: Array` - `id: string` GitHub issue ID - `number: string` GitHub issue number - `repositoryFullName: string` Full repository name (owner/repo) - `repositoryName: string` Repository name - `title: string` GitHub issue title - `url: string` URL to the GitHub issue - `hubspot: Array` - `dealAmount: number | null` Deal amount (for DEAL type) - `dealClosed: boolean | null` Whether the deal is closed (for DEAL type) - `objectId: number` HubSpot object ID - `type: "TICKET" | "DEAL" | "CONTACT"` HubSpot object type - `"TICKET"` - `"DEAL"` - `"CONTACT"` - `jira: Array` - `issueId: string` Jira issue ID - `issueUrl: string | null` URL to the Jira issue - `linear: Array` - `issueId: string` Linear issue ID - `issueUrl: string | null` URL to the Linear issue - `salesforce: Array` - `amount: number | null` Opportunity amount (for Opportunity type) - `isClosed: boolean | null` Whether the opportunity is closed (for Opportunity type) - `objectId: string` Salesforce record ID - `objectType: "Opportunity" | "Case"` Salesforce object type - `"Opportunity"` - `"Case"` - `isPinned: boolean` Whether the post is pinned to the top - `object: "post"` Object type identifier - `"post"` - `opportunityAmount: number | null` Total opportunity amount from linked HubSpot deals and Salesforce opportunities - `postUrl: string` Full URL to view the post - `slug: string` URL-friendly slug - `status: PostStatus` - `id: string` Unique identifier - `color: string` Color for UI display - `isDefault: boolean` Whether this is the default status for new posts - `name: string` Display name - `object: "post_status"` Object type identifier - `"post_status"` - `type: "reviewing" | "unstarted" | "active" | 2 more` The workflow stage this status represents - `"reviewing"` - `"unstarted"` - `"active"` - `"completed"` - `"canceled"` - `tags: Array` Tags attached to this post - `id: string` Tag unique identifier - `color: string | null` Tag color hex code - `name: string` Tag name - `title: string` Post title - `updatedAt: string` ISO 8601 timestamp when last modified - `upvotes: number` Total number of upvotes ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const post = await client.feedback.posts.create({ boardId: '507f1f77bcf86cd799439011', title: 'Add dark mode support', }); console.log(post.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "access": { "companyExternalIds": [ "string" ], "userIds": [ "string" ] }, "assigneeId": "507f1f77bcf86cd799439013", "author": { "id": "507f1f77bcf86cd799439011", "email": "john@example.com", "name": "John Doe", "profilePicture": "https://cdn.example.com/avatars/john.png", "type": "customer" }, "boardId": "507f1f77bcf86cd799439011", "commentCount": 5, "content": "

It would be great to have a dark mode option for the dashboard.

", "createdAt": "2023-12-12T00:00:00.000Z", "customFields": { "cf_priority": "bar", "cf_effort": "bar" }, "eta": "2025-01-01T00:00:00.000Z", "features": { "commentsEnabled": true }, "inReview": false, "integrations": { "clickup": [ { "id": "86a1b2c3d", "title": "Add dark mode support", "url": "https://app.clickup.com/t/86a1b2c3d" } ], "devops": [ { "id": 1234, "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "projectName": "My Project", "title": "Add dark mode support", "url": "https://dev.azure.com/org/project/_workitems/edit/1234" } ], "github": [ { "id": "1234567890", "number": "42", "repositoryFullName": "acme/backend", "repositoryName": "backend", "title": "Add dark mode support", "url": "https://github.com/acme/backend/issues/42" } ], "hubspot": [ { "dealAmount": 5000, "dealClosed": false, "objectId": 123456789, "type": "TICKET" } ], "jira": [ { "issueId": "10042", "issueUrl": "https://myteam.atlassian.net/browse/PROJ-123" } ], "linear": [ { "issueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "issueUrl": "https://linear.app/team/issue/ENG-123" } ], "salesforce": [ { "amount": 25000, "isClosed": false, "objectId": "006Dn00000Abcdef", "objectType": "Opportunity" } ] }, "isPinned": false, "object": "post", "opportunityAmount": 30000, "postUrl": "https://feedback.example.com/p/add-dark-mode-support", "slug": "add-dark-mode-support", "status": { "id": "507f1f77bcf86cd799439011", "color": "Blue", "isDefault": false, "name": "In Progress", "object": "post_status", "type": "active" }, "tags": [ { "id": "507f1f77bcf86cd799439011", "color": "#FF5722", "name": "bug" } ], "title": "Add dark mode support", "updatedAt": "2023-12-13T00:00:00.000Z", "upvotes": 42 } ``` ## Get a post by ID `client.feedback.posts.retrieve(stringid, PostRetrieveParamsparams?, RequestOptionsoptions?): Post` **get** `/v2/posts/{id}` Retrieves a single post by its unique identifier. Returns the full post object including: - Author information - Current status - Tags - Voting stats - Engagement metrics - Custom field values ### Parameters - `id: string` Post unique identifier - `params: PostRetrieveParams` - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `Post` - `id: string` Unique identifier - `access: Access` - `companyExternalIds: Array` External company IDs explicitly granted access to this post. Empty array means no company-level restrictions. Non-empty means only users belonging to these companies can see the post. - `userIds: Array` User IDs explicitly granted access to this post. Empty array means no user-level restrictions (post uses board/org visibility). Non-empty means only these users (plus admins) can see the post. - `assigneeId: string | null` ID of the admin assigned to this post, null if unassigned - `author: Author | null` - `id: string | null` Author unique identifier - `email: string | null` Author email (if available) - `name: string` Author display name - `profilePicture: string | null` Author profile picture URL - `type: "admin" | "customer" | "guest" | 3 more` Type of user who authored the post - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `boardId: string` Board (category) ID this post belongs to - `commentCount: number` Total number of comments - `content: string` Post content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `customFields: Record` Custom field values keyed by field ID - `eta: string | null` Estimated completion time as ISO 8601 timestamp, null if not set - `features: Features` - `commentsEnabled: boolean` Whether comments are allowed on this post - `inReview: boolean` Whether the post is pending moderation review - `integrations: Integrations` Third-party integration links associated with this post - `clickup: Array` - `id: string` ClickUp task ID - `title: string` ClickUp task title - `url: string` URL to the ClickUp task - `devops: Array` - `id: number` Azure DevOps work item ID - `projectId: string` Azure DevOps project ID - `projectName: string` Azure DevOps project name - `title: string` Work item title - `url: string` URL to the work item - `github: Array` - `id: string` GitHub issue ID - `number: string` GitHub issue number - `repositoryFullName: string` Full repository name (owner/repo) - `repositoryName: string` Repository name - `title: string` GitHub issue title - `url: string` URL to the GitHub issue - `hubspot: Array` - `dealAmount: number | null` Deal amount (for DEAL type) - `dealClosed: boolean | null` Whether the deal is closed (for DEAL type) - `objectId: number` HubSpot object ID - `type: "TICKET" | "DEAL" | "CONTACT"` HubSpot object type - `"TICKET"` - `"DEAL"` - `"CONTACT"` - `jira: Array` - `issueId: string` Jira issue ID - `issueUrl: string | null` URL to the Jira issue - `linear: Array` - `issueId: string` Linear issue ID - `issueUrl: string | null` URL to the Linear issue - `salesforce: Array` - `amount: number | null` Opportunity amount (for Opportunity type) - `isClosed: boolean | null` Whether the opportunity is closed (for Opportunity type) - `objectId: string` Salesforce record ID - `objectType: "Opportunity" | "Case"` Salesforce object type - `"Opportunity"` - `"Case"` - `isPinned: boolean` Whether the post is pinned to the top - `object: "post"` Object type identifier - `"post"` - `opportunityAmount: number | null` Total opportunity amount from linked HubSpot deals and Salesforce opportunities - `postUrl: string` Full URL to view the post - `slug: string` URL-friendly slug - `status: PostStatus` - `id: string` Unique identifier - `color: string` Color for UI display - `isDefault: boolean` Whether this is the default status for new posts - `name: string` Display name - `object: "post_status"` Object type identifier - `"post_status"` - `type: "reviewing" | "unstarted" | "active" | 2 more` The workflow stage this status represents - `"reviewing"` - `"unstarted"` - `"active"` - `"completed"` - `"canceled"` - `tags: Array` Tags attached to this post - `id: string` Tag unique identifier - `color: string | null` Tag color hex code - `name: string` Tag name - `title: string` Post title - `updatedAt: string` ISO 8601 timestamp when last modified - `upvotes: number` Total number of upvotes ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const post = await client.feedback.posts.retrieve('507f1f77bcf86cd799439011'); console.log(post.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "access": { "companyExternalIds": [ "string" ], "userIds": [ "string" ] }, "assigneeId": "507f1f77bcf86cd799439013", "author": { "id": "507f1f77bcf86cd799439011", "email": "john@example.com", "name": "John Doe", "profilePicture": "https://cdn.example.com/avatars/john.png", "type": "customer" }, "boardId": "507f1f77bcf86cd799439011", "commentCount": 5, "content": "

It would be great to have a dark mode option for the dashboard.

", "createdAt": "2023-12-12T00:00:00.000Z", "customFields": { "cf_priority": "bar", "cf_effort": "bar" }, "eta": "2025-01-01T00:00:00.000Z", "features": { "commentsEnabled": true }, "inReview": false, "integrations": { "clickup": [ { "id": "86a1b2c3d", "title": "Add dark mode support", "url": "https://app.clickup.com/t/86a1b2c3d" } ], "devops": [ { "id": 1234, "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "projectName": "My Project", "title": "Add dark mode support", "url": "https://dev.azure.com/org/project/_workitems/edit/1234" } ], "github": [ { "id": "1234567890", "number": "42", "repositoryFullName": "acme/backend", "repositoryName": "backend", "title": "Add dark mode support", "url": "https://github.com/acme/backend/issues/42" } ], "hubspot": [ { "dealAmount": 5000, "dealClosed": false, "objectId": 123456789, "type": "TICKET" } ], "jira": [ { "issueId": "10042", "issueUrl": "https://myteam.atlassian.net/browse/PROJ-123" } ], "linear": [ { "issueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "issueUrl": "https://linear.app/team/issue/ENG-123" } ], "salesforce": [ { "amount": 25000, "isClosed": false, "objectId": "006Dn00000Abcdef", "objectType": "Opportunity" } ] }, "isPinned": false, "object": "post", "opportunityAmount": 30000, "postUrl": "https://feedback.example.com/p/add-dark-mode-support", "slug": "add-dark-mode-support", "status": { "id": "507f1f77bcf86cd799439011", "color": "Blue", "isDefault": false, "name": "In Progress", "object": "post_status", "type": "active" }, "tags": [ { "id": "507f1f77bcf86cd799439011", "color": "#FF5722", "name": "bug" } ], "title": "Add dark mode support", "updatedAt": "2023-12-13T00:00:00.000Z", "upvotes": 42 } ``` ## Update a post `client.feedback.posts.update(stringid, PostUpdateParamsparams, RequestOptionsoptions?): Post` **patch** `/v2/posts/{id}` Updates an existing post. Only provided fields will be modified. ### Updatable Fields - `title` - Post title (minimum 2 characters) - `content` - Post content in HTML format - `boardId` - Move post to a different board - `statusId` - Update post status - `tags` - Replace existing tags with new set - `commentsEnabled` - Enable/disable comments - `inReview` - Put post in/out of moderation queue - `customFields` - Update custom field values - `eta` - Set estimated completion date (null to clear) - `createdAt` - Update creation date (for backdating) - `assigneeId` - Admin ID to assign this post to (null to unassign) - `visibility` - Post-level visibility restriction: 'public' (no additional restrictions), 'authorOnly' (only author and admins), or 'companyOnly' (only users in author's company). Note: even 'public' posts are still subject to board-level and organization-level access controls. - `author` - Change post attribution (id, userId, email, name, profilePicture) ### Status Update Notifications - `sendStatusUpdateEmail` - When changing status, optionally send email notification to voters (default: false) ### Response Returns the updated post object with all fields populated. ### Parameters - `id: string` Post unique identifier - `params: PostUpdateParams` - `assigneeId?: string | null` Body param: Admin ID to assign this post to (null to unassign) - `author?: AuthorInput` Body param: 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?: string` Featurebase user ID to attribute content to - `email?: string` Author email (used to find or create user) - `name?: string` Author display name - `profilePicture?: string` Author profile picture URL - `userId?: string` External user ID from your system (matched via SSO) - `boardId?: string` Body param: Board ID to move post to - `commentsEnabled?: boolean | null` Body param: Whether comments are enabled on this post - `content?: string` Body param: Post content (HTML) - `createdAt?: string | null` Body param: Creation date (for backdating) - `customFields?: Record | boolean | number | 2 more>` Body param: Custom field values. Keys must be valid ObjectIds. Values can be: string, boolean, number, ISO date string, array of strings, ObjectId string, or null. - `Array` - `boolean` - `number` - `string` - `string | null` - `eta?: string | null` Body param: Estimated completion date (null to clear) - `inReview?: boolean | null` Body param: Whether post is pending moderation - `sendStatusUpdateEmail?: boolean | null` Body param: Whether to send status update email to voters - `statusId?: string` Body param: Status ID to set - `tags?: string | Array` Body param: Tag names to set (replaces existing) - `string` - `Array` - `title?: string` Body param: Post title - `upvotes?: number | null` Body param: Set the upvotes count directly. Use with caution as this overrides the actual vote count. - `visibility?: "public" | "authorOnly" | "companyOnly"` Body param: Post visibility. 'public' = visible to all users, 'authorOnly' = only visible to the author and admins, 'companyOnly' = only visible to users in the same company as the author - `"public"` - `"authorOnly"` - `"companyOnly"` - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `Post` - `id: string` Unique identifier - `access: Access` - `companyExternalIds: Array` External company IDs explicitly granted access to this post. Empty array means no company-level restrictions. Non-empty means only users belonging to these companies can see the post. - `userIds: Array` User IDs explicitly granted access to this post. Empty array means no user-level restrictions (post uses board/org visibility). Non-empty means only these users (plus admins) can see the post. - `assigneeId: string | null` ID of the admin assigned to this post, null if unassigned - `author: Author | null` - `id: string | null` Author unique identifier - `email: string | null` Author email (if available) - `name: string` Author display name - `profilePicture: string | null` Author profile picture URL - `type: "admin" | "customer" | "guest" | 3 more` Type of user who authored the post - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `boardId: string` Board (category) ID this post belongs to - `commentCount: number` Total number of comments - `content: string` Post content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `customFields: Record` Custom field values keyed by field ID - `eta: string | null` Estimated completion time as ISO 8601 timestamp, null if not set - `features: Features` - `commentsEnabled: boolean` Whether comments are allowed on this post - `inReview: boolean` Whether the post is pending moderation review - `integrations: Integrations` Third-party integration links associated with this post - `clickup: Array` - `id: string` ClickUp task ID - `title: string` ClickUp task title - `url: string` URL to the ClickUp task - `devops: Array` - `id: number` Azure DevOps work item ID - `projectId: string` Azure DevOps project ID - `projectName: string` Azure DevOps project name - `title: string` Work item title - `url: string` URL to the work item - `github: Array` - `id: string` GitHub issue ID - `number: string` GitHub issue number - `repositoryFullName: string` Full repository name (owner/repo) - `repositoryName: string` Repository name - `title: string` GitHub issue title - `url: string` URL to the GitHub issue - `hubspot: Array` - `dealAmount: number | null` Deal amount (for DEAL type) - `dealClosed: boolean | null` Whether the deal is closed (for DEAL type) - `objectId: number` HubSpot object ID - `type: "TICKET" | "DEAL" | "CONTACT"` HubSpot object type - `"TICKET"` - `"DEAL"` - `"CONTACT"` - `jira: Array` - `issueId: string` Jira issue ID - `issueUrl: string | null` URL to the Jira issue - `linear: Array` - `issueId: string` Linear issue ID - `issueUrl: string | null` URL to the Linear issue - `salesforce: Array` - `amount: number | null` Opportunity amount (for Opportunity type) - `isClosed: boolean | null` Whether the opportunity is closed (for Opportunity type) - `objectId: string` Salesforce record ID - `objectType: "Opportunity" | "Case"` Salesforce object type - `"Opportunity"` - `"Case"` - `isPinned: boolean` Whether the post is pinned to the top - `object: "post"` Object type identifier - `"post"` - `opportunityAmount: number | null` Total opportunity amount from linked HubSpot deals and Salesforce opportunities - `postUrl: string` Full URL to view the post - `slug: string` URL-friendly slug - `status: PostStatus` - `id: string` Unique identifier - `color: string` Color for UI display - `isDefault: boolean` Whether this is the default status for new posts - `name: string` Display name - `object: "post_status"` Object type identifier - `"post_status"` - `type: "reviewing" | "unstarted" | "active" | 2 more` The workflow stage this status represents - `"reviewing"` - `"unstarted"` - `"active"` - `"completed"` - `"canceled"` - `tags: Array` Tags attached to this post - `id: string` Tag unique identifier - `color: string | null` Tag color hex code - `name: string` Tag name - `title: string` Post title - `updatedAt: string` ISO 8601 timestamp when last modified - `upvotes: number` Total number of upvotes ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const post = await client.feedback.posts.update('507f1f77bcf86cd799439011'); console.log(post.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "access": { "companyExternalIds": [ "string" ], "userIds": [ "string" ] }, "assigneeId": "507f1f77bcf86cd799439013", "author": { "id": "507f1f77bcf86cd799439011", "email": "john@example.com", "name": "John Doe", "profilePicture": "https://cdn.example.com/avatars/john.png", "type": "customer" }, "boardId": "507f1f77bcf86cd799439011", "commentCount": 5, "content": "

It would be great to have a dark mode option for the dashboard.

", "createdAt": "2023-12-12T00:00:00.000Z", "customFields": { "cf_priority": "bar", "cf_effort": "bar" }, "eta": "2025-01-01T00:00:00.000Z", "features": { "commentsEnabled": true }, "inReview": false, "integrations": { "clickup": [ { "id": "86a1b2c3d", "title": "Add dark mode support", "url": "https://app.clickup.com/t/86a1b2c3d" } ], "devops": [ { "id": 1234, "projectId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "projectName": "My Project", "title": "Add dark mode support", "url": "https://dev.azure.com/org/project/_workitems/edit/1234" } ], "github": [ { "id": "1234567890", "number": "42", "repositoryFullName": "acme/backend", "repositoryName": "backend", "title": "Add dark mode support", "url": "https://github.com/acme/backend/issues/42" } ], "hubspot": [ { "dealAmount": 5000, "dealClosed": false, "objectId": 123456789, "type": "TICKET" } ], "jira": [ { "issueId": "10042", "issueUrl": "https://myteam.atlassian.net/browse/PROJ-123" } ], "linear": [ { "issueId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "issueUrl": "https://linear.app/team/issue/ENG-123" } ], "salesforce": [ { "amount": 25000, "isClosed": false, "objectId": "006Dn00000Abcdef", "objectType": "Opportunity" } ] }, "isPinned": false, "object": "post", "opportunityAmount": 30000, "postUrl": "https://feedback.example.com/p/add-dark-mode-support", "slug": "add-dark-mode-support", "status": { "id": "507f1f77bcf86cd799439011", "color": "Blue", "isDefault": false, "name": "In Progress", "object": "post_status", "type": "active" }, "tags": [ { "id": "507f1f77bcf86cd799439011", "color": "#FF5722", "name": "bug" } ], "title": "Add dark mode support", "updatedAt": "2023-12-13T00:00:00.000Z", "upvotes": 42 } ``` ## Delete a post `client.feedback.posts.delete(stringid, PostDeleteParamsparams?, RequestOptionsoptions?): PostDeleteResponse` **delete** `/v2/posts/{id}` Permanently deletes a post. This action cannot be undone. ### What Gets Deleted When you delete a post: - The post itself is permanently removed - All comments on the post are deleted - Vote records are removed - Any associated notifications are cleared ### Response Returns a deletion confirmation object with: - `id` - The ID of the deleted post - `object` - Always "post" - `deleted` - Always true ### Permissions Requires member-level access or higher to delete posts. ### Parameters - `id: string` Post unique identifier - `params: PostDeleteParams` - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `PostDeleteResponse` - `id: string` Unique identifier of the deleted post - `deleted: true` Indicates the resource was deleted - `true` - `object: "post"` Object type identifier - `"post"` ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const post = await client.feedback.posts.delete('507f1f77bcf86cd799439011'); console.log(post.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "deleted": true, "object": "post" } ``` ## Domain Types ### Post - `Post` - `id: string` Unique identifier - `access: Access` - `companyExternalIds: Array` External company IDs explicitly granted access to this post. Empty array means no company-level restrictions. Non-empty means only users belonging to these companies can see the post. - `userIds: Array` User IDs explicitly granted access to this post. Empty array means no user-level restrictions (post uses board/org visibility). Non-empty means only these users (plus admins) can see the post. - `assigneeId: string | null` ID of the admin assigned to this post, null if unassigned - `author: Author | null` - `id: string | null` Author unique identifier - `email: string | null` Author email (if available) - `name: string` Author display name - `profilePicture: string | null` Author profile picture URL - `type: "admin" | "customer" | "guest" | 3 more` Type of user who authored the post - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `boardId: string` Board (category) ID this post belongs to - `commentCount: number` Total number of comments - `content: string` Post content in HTML format - `createdAt: string` ISO 8601 timestamp when created - `customFields: Record` Custom field values keyed by field ID - `eta: string | null` Estimated completion time as ISO 8601 timestamp, null if not set - `features: Features` - `commentsEnabled: boolean` Whether comments are allowed on this post - `inReview: boolean` Whether the post is pending moderation review - `integrations: Integrations` Third-party integration links associated with this post - `clickup: Array` - `id: string` ClickUp task ID - `title: string` ClickUp task title - `url: string` URL to the ClickUp task - `devops: Array` - `id: number` Azure DevOps work item ID - `projectId: string` Azure DevOps project ID - `projectName: string` Azure DevOps project name - `title: string` Work item title - `url: string` URL to the work item - `github: Array` - `id: string` GitHub issue ID - `number: string` GitHub issue number - `repositoryFullName: string` Full repository name (owner/repo) - `repositoryName: string` Repository name - `title: string` GitHub issue title - `url: string` URL to the GitHub issue - `hubspot: Array` - `dealAmount: number | null` Deal amount (for DEAL type) - `dealClosed: boolean | null` Whether the deal is closed (for DEAL type) - `objectId: number` HubSpot object ID - `type: "TICKET" | "DEAL" | "CONTACT"` HubSpot object type - `"TICKET"` - `"DEAL"` - `"CONTACT"` - `jira: Array` - `issueId: string` Jira issue ID - `issueUrl: string | null` URL to the Jira issue - `linear: Array` - `issueId: string` Linear issue ID - `issueUrl: string | null` URL to the Linear issue - `salesforce: Array` - `amount: number | null` Opportunity amount (for Opportunity type) - `isClosed: boolean | null` Whether the opportunity is closed (for Opportunity type) - `objectId: string` Salesforce record ID - `objectType: "Opportunity" | "Case"` Salesforce object type - `"Opportunity"` - `"Case"` - `isPinned: boolean` Whether the post is pinned to the top - `object: "post"` Object type identifier - `"post"` - `opportunityAmount: number | null` Total opportunity amount from linked HubSpot deals and Salesforce opportunities - `postUrl: string` Full URL to view the post - `slug: string` URL-friendly slug - `status: PostStatus` - `id: string` Unique identifier - `color: string` Color for UI display - `isDefault: boolean` Whether this is the default status for new posts - `name: string` Display name - `object: "post_status"` Object type identifier - `"post_status"` - `type: "reviewing" | "unstarted" | "active" | 2 more` The workflow stage this status represents - `"reviewing"` - `"unstarted"` - `"active"` - `"completed"` - `"canceled"` - `tags: Array` Tags attached to this post - `id: string` Tag unique identifier - `color: string | null` Tag color hex code - `name: string` Tag name - `title: string` Post title - `updatedAt: string` ISO 8601 timestamp when last modified - `upvotes: number` Total number of upvotes ### Post Delete Response - `PostDeleteResponse` - `id: string` Unique identifier of the deleted post - `deleted: true` Indicates the resource was deleted - `true` - `object: "post"` Object type identifier - `"post"` # Voters ## List voters on a post `client.feedback.posts.voters.list(stringid, VoterListParamsparams?, RequestOptionsoptions?): CursorPage` **get** `/v2/posts/{id}/voters` Returns all voters (upvoters) for a specific post. Voters are users who have upvoted the post. Each voter is returned in the standard user format with: - Basic info: id, name, email, profilePicture - User type (admin, customer, guest, etc.) - Companies the user belongs to - Activity stats: commentsCreated, postsCreated, lastActivity - Preferences: subscribedToChangelog, locale, verified ### Pagination This endpoint uses **cursor-based pagination**: - `limit` - Number of voters to return (1-100, default 10) - `cursor` - Opaque cursor from a previous response's `nextCursor` field **Example:** To paginate through results: 1. First request: `GET /v2/posts/{id}/voters?limit=10` 1. If `nextCursor` is not null, use it for the next page 1. Next request: `GET /v2/posts/{id}/voters?limit=10&cursor={nextCursor}` ### Response Format Returns a list object with: - `object` - Always "list" - `data` - Array of user objects - `nextCursor` - Cursor for the next page (null if no more results) ### Permissions Requires member-level access or higher. ### Parameters - `id: string` Post unique identifier - `params: VoterListParams` - `cursor?: string` Query param: An opaque cursor for pagination. Use the nextCursor value from a previous response to fetch the next page of results. - `limit?: number` Query param: A limit on the number of voters to be returned, between 1 and 100. - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `VoterListResponse` - `id: string` Unique identifier - `name: string` User display name - `object: "contact"` Object type identifier - `"contact"` - `type: "admin" | "customer" | "guest" | 3 more` Type of user - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `commentsCreated?: number` Number of comments created - `companies?: Array` Companies the user belongs to - `id: string` Featurebase internal ID - `companyId: string` External company ID from your system - `companySize: number | null` Company employee headcount - `createdAt: string | null` ISO date when company was created - `industry: string | null` Industry - `lastActivity: string | null` ISO date of last activity - `linkedUsers: number | null` Number of users linked to this company - `monthlySpend: number | null` Monthly spend - `name: string` Company name - `object: "company"` Object type identifier - `"company"` - `plan: string | null` Plan or tier name - `updatedAt: string | null` ISO date when company was last updated - `website: string | null` Company website URL - `customFields?: Record` Custom field values - `customFields?: Record` Custom field values on the user - `description?: string` User description/bio - `email?: string | null` User email - `lastActivity?: string` Last activity ISO timestamp - `locale?: string` User locale - `manuallyOptedOutFromChangelog?: boolean` Whether manually opted out from changelog - `organizationId?: string` Organization ID the user belongs to - `postsCreated?: number` Number of posts created - `profilePicture?: string | null` Profile picture URL - `roles?: Array` User roles - `subscribedToChangelog?: boolean` Whether subscribed to changelog - `userId?: string` External user ID from SSO - `verified?: boolean` Whether email is verified ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); // Automatically fetches more pages as needed. for await (const voterListResponse of client.feedback.posts.voters.list( '507f1f77bcf86cd799439011', )) { console.log(voterListResponse.id); } ``` #### Response ```json { "data": [ { "id": "676f0f6765bdaa7d7d760f88", "name": "John Steezy", "object": "contact", "type": "customer", "commentsCreated": 0, "companies": [ { "id": "507f1f77bcf86cd799439011", "companyId": "comp_12345", "companySize": 250, "createdAt": "2025-01-01T12:00:00.000Z", "industry": "Technology", "lastActivity": "2025-01-15T00:00:00.000Z", "linkedUsers": 15, "monthlySpend": 5000, "name": "Acme Inc", "object": "company", "plan": "enterprise", "updatedAt": "2025-01-10T15:30:00.000Z", "website": "https://acme.com", "customFields": { "location": "bar", "priority": "bar" } } ], "customFields": { "foo": "bar" }, "description": "", "email": "john@example.com", "lastActivity": "2025-01-03T21:42:30.181Z", "locale": "en", "manuallyOptedOutFromChangelog": false, "organizationId": "5febde12dc56d60012d47db6", "postsCreated": 0, "profilePicture": "https://fb-usercontent.fra1.cdn.digitaloceanspaces.com/anon_23.png", "roles": [ "string" ], "subscribedToChangelog": true, "userId": "676f0f673dbb299c8a4f3057", "verified": true } ], "nextCursor": "eyJpZCI6IjUwN2YxZjc3YmNmODZjZDc5OTQzOTAxMSJ9", "object": "list", "pagination": { "limit": 10, "page": 1, "total": 42, "totalPages": 5 } } ``` ## Add a voter to a post `client.feedback.posts.voters.add(stringid, VoterAddParamsparams, RequestOptionsoptions?): VoterAddResponse` **post** `/v2/posts/{id}/voters` Adds a voter (upvote) to a post. ### Voter Identification To add a vote on behalf of a user, provide one or more identification fields: - `id` - Featurebase user ID - `userId` - External SSO user ID from your system - `email` - User's email address - `name` - Display name (used when creating a new user) - `profilePicture` - Profile picture URL (used when creating a new user) Resolution priority: `id` > `userId` > `email` > authenticated user If no fields are provided, the authenticated user's vote is added. If the user doesn't exist, a new customer will be created with the provided information. ### Idempotency If the user has already voted on this post, the request succeeds but no duplicate vote is added. ### Response Returns a confirmation object with: - `object` - Always "voter" - `added` - Always true - `id` - The voter's user ID - `postId` - The post ID the vote was added to ### Permissions Requires member-level access or higher. ### Parameters - `id: string` Post unique identifier - `params: VoterAddParams` - `id?: string` Body param: Featurebase user ID to add as voter - `email?: string` Body param: Voter email (used to find or create user) - `name?: string` Body param: Voter display name (used when creating new user) - `profilePicture?: string` Body param: Voter profile picture URL - `userId?: string` Body param: External user ID from your system (matched via SSO) - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `VoterAddResponse` - `id: string` Voter unique identifier - `added: true` Indicates the voter was added - `true` - `object: "voter"` Object type identifier - `"voter"` - `postId: string` Post ID the voter was added to ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const response = await client.feedback.posts.voters.add('507f1f77bcf86cd799439011'); console.log(response.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "added": true, "object": "voter", "postId": "507f1f77bcf86cd799439012" } ``` ## Remove a voter from a post `client.feedback.posts.voters.remove(stringid, VoterRemoveParamsparams, RequestOptionsoptions?): VoterRemoveResponse` **delete** `/v2/posts/{id}/voters` Removes a voter (upvote) from a post. ### Voter Identification To remove a vote on behalf of a user, provide one or more identification fields: - `id` - Featurebase user ID - `userId` - External SSO user ID from your system - `email` - User's email address Resolution priority: `id` > `userId` > `email` > authenticated user If no fields are provided, the authenticated user's vote will be removed. ### Response Returns a confirmation object with: - `object` - Always "voter" - `removed` - Always true - `id` - The voter's user ID - `postId` - The post ID the vote was removed from ### Permissions Requires member-level access or higher. ### Parameters - `id: string` Post unique identifier - `params: VoterRemoveParams` - `id?: string` Body param: Featurebase user ID to remove as voter - `email?: string` Body param: Voter email to identify user - `userId?: string` Body param: External user ID from your system (matched via SSO) - `featurebaseVersion?: "2026-01-01.nova" | "2025-12-12.clover"` Header param: API version for this request. Defaults to your organization's configured API version if not specified. - `"2026-01-01.nova"` - `"2025-12-12.clover"` ### Returns - `VoterRemoveResponse` - `id: string` Voter unique identifier - `object: "voter"` Object type identifier - `"voter"` - `postId: string` Post ID the voter was removed from - `removed: true` Indicates the voter was removed - `true` ### Example ```typescript import Featurebase from 'featurebase-node'; const client = new Featurebase({ apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted }); const voter = await client.feedback.posts.voters.remove('507f1f77bcf86cd799439011'); console.log(voter.id); ``` #### Response ```json { "id": "507f1f77bcf86cd799439011", "object": "voter", "postId": "507f1f77bcf86cd799439012", "removed": true } ``` ## Domain Types ### Voter List Response - `VoterListResponse` - `id: string` Unique identifier - `name: string` User display name - `object: "contact"` Object type identifier - `"contact"` - `type: "admin" | "customer" | "guest" | 3 more` Type of user - `"admin"` - `"customer"` - `"guest"` - `"integration"` - `"bot"` - `"lead"` - `commentsCreated?: number` Number of comments created - `companies?: Array` Companies the user belongs to - `id: string` Featurebase internal ID - `companyId: string` External company ID from your system - `companySize: number | null` Company employee headcount - `createdAt: string | null` ISO date when company was created - `industry: string | null` Industry - `lastActivity: string | null` ISO date of last activity - `linkedUsers: number | null` Number of users linked to this company - `monthlySpend: number | null` Monthly spend - `name: string` Company name - `object: "company"` Object type identifier - `"company"` - `plan: string | null` Plan or tier name - `updatedAt: string | null` ISO date when company was last updated - `website: string | null` Company website URL - `customFields?: Record` Custom field values - `customFields?: Record` Custom field values on the user - `description?: string` User description/bio - `email?: string | null` User email - `lastActivity?: string` Last activity ISO timestamp - `locale?: string` User locale - `manuallyOptedOutFromChangelog?: boolean` Whether manually opted out from changelog - `organizationId?: string` Organization ID the user belongs to - `postsCreated?: number` Number of posts created - `profilePicture?: string | null` Profile picture URL - `roles?: Array` User roles - `subscribedToChangelog?: boolean` Whether subscribed to changelog - `userId?: string` External user ID from SSO - `verified?: boolean` Whether email is verified ### Voter Add Response - `VoterAddResponse` - `id: string` Voter unique identifier - `added: true` Indicates the voter was added - `true` - `object: "voter"` Object type identifier - `"voter"` - `postId: string` Post ID the voter was added to ### Voter Remove Response - `VoterRemoveResponse` - `id: string` Voter unique identifier - `object: "voter"` Object type identifier - `"voter"` - `postId: string` Post ID the voter was removed from - `removed: true` Indicates the voter was removed - `true`