Feedback
FeedbackBoards
Boards (post categories) organize feedback into distinct containers with their own settings.
List all boards
Get a board by ID
ModelsExpand Collapse
Board { id, access, createdAt, 7 more }
icon: EmojiIcon { type, value } | PredefinedIcon { type, value } | URLIcon { type, value } | nullThe board’s icon. Can be one of three types:
- emoji: A single emoji character (e.g., 💡, 🚀, ⭐)
- icon: A predefined icon from the built-in library (e.g., lightbulb, bug, star)
- url: A custom image URL (HTTPS required)
Can be null if no icon is set.
The board’s icon. Can be one of three types:
- emoji: A single emoji character (e.g., 💡, 🚀, ⭐)
- icon: A predefined icon from the built-in library (e.g., lightbulb, bug, star)
- url: A custom image URL (HTTPS required)
Can be null if no icon is set.
icon: EmojiIcon { type, value } | PredefinedIcon { type, value } | URLIcon { type, value } | nullThe board’s icon. Can be one of three types:
- emoji: A single emoji character (e.g., 💡, 🚀, ⭐)
- icon: A predefined icon from the built-in library (e.g., lightbulb, bug, star)
- url: A custom image URL (HTTPS required)
Can be null if no icon is set.
The board’s icon. Can be one of three types:
- emoji: A single emoji character (e.g., 💡, 🚀, ⭐)
- icon: A predefined icon from the built-in library (e.g., lightbulb, bug, star)
- url: A custom image URL (HTTPS required)
Can be null if no icon is set.
FeedbackPosts
User-submitted feedback and feature requests. Posts belong to boards and can be upvoted, commented on, and tracked through statuses.
List all posts
Create a new post
Get a post by ID
Update a post
Delete a post
Merge two posts
Unmerge a post
Search posts
ModelsExpand Collapse
Post { id, access, anchor, 30 more }
anchor: Anchor | nullWhen kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, the triage grouping key (source record id, conversation id, origin post id, or the insight’s own id for singletons). Legacy insights may be null and group as singletons.
insightSource: InsightSource | nullProvenance of an insight: which channel it came from and how it was captured.
Provenance of an insight: which channel it came from and how it was captured.
integrations: Integrations { clickup, devops, github, 4 more } Third-party integration links associated with this post
Third-party integration links associated with this post
kind: "issue" | "insight" | "record"Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Number of insights linked to this issue as supporting evidence. Only meaningful when kind is ‘issue’.
When kind is ‘insight’, the ID of the issue this insight supports. Null when the insight is unlinked or when kind is ‘issue’.
Total opportunity amount from linked HubSpot deals and Salesforce opportunities
True when the issue is hidden from portal/public surfaces. Missing stored values are returned as false.
Present and true only on POST /v2/posts, when the request carried a source.externalId that already had a post. The existing post is returned unchanged with HTTP 200; a newly created post returns HTTP 201 without this field.
intakeMode?: "request" | "feedback"Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
status: "queued" | "processing" | "complete" | 3 more‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
reason?: "request_mode" | "autopilot_off" | "insights_disabled" | 11 moreWhy processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
Why processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
results?: Array<Result>What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
outcome: "attached" | "request" | "question" | "held"‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
The request this ask became, or was attached to. Absent for a question, and absent when the request is not readable through this API (for example a ticket board).
reason?: "too_many_topics" | "uncertain" | "custom_fields" | "processing_failed"Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
PostList { data, nextCursor, object, pagination }
Array of posts
Array of posts
anchor: Anchor | nullWhen kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, the triage grouping key (source record id, conversation id, origin post id, or the insight’s own id for singletons). Legacy insights may be null and group as singletons.
insightSource: InsightSource | nullProvenance of an insight: which channel it came from and how it was captured.
Provenance of an insight: which channel it came from and how it was captured.
integrations: Integrations { clickup, devops, github, 4 more } Third-party integration links associated with this post
Third-party integration links associated with this post
kind: "issue" | "insight" | "record"Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Number of insights linked to this issue as supporting evidence. Only meaningful when kind is ‘issue’.
When kind is ‘insight’, the ID of the issue this insight supports. Null when the insight is unlinked or when kind is ‘issue’.
Total opportunity amount from linked HubSpot deals and Salesforce opportunities
True when the issue is hidden from portal/public surfaces. Missing stored values are returned as false.
Present and true only on POST /v2/posts, when the request carried a source.externalId that already had a post. The existing post is returned unchanged with HTTP 200; a newly created post returns HTTP 201 without this field.
intakeMode?: "request" | "feedback"Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
status: "queued" | "processing" | "complete" | 3 more‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
reason?: "request_mode" | "autopilot_off" | "insights_disabled" | 11 moreWhy processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
Why processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
results?: Array<Result>What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
outcome: "attached" | "request" | "question" | "held"‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
The request this ask became, or was attached to. Absent for a question, and absent when the request is not readable through this API (for example a ticket board).
reason?: "too_many_topics" | "uncertain" | "custom_fields" | "processing_failed"Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
PostProcessing { status, reason, results } On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
status: "queued" | "processing" | "complete" | 3 more‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
reason?: "request_mode" | "autopilot_off" | "insights_disabled" | 11 moreWhy processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
Why processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
results?: Array<Result>What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
outcome: "attached" | "request" | "question" | "held"‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
The request this ask became, or was attached to. Absent for a question, and absent when the request is not readable through this API (for example a ticket board).
reason?: "too_many_topics" | "uncertain" | "custom_fields" | "processing_failed"Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
PostSearchResponse { data, nextCursor, object, 2 more }
data: Array<Data>Array of search results
Array of search results
anchor: Anchor | nullWhen kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, where exactly the insight points back into its origin: an insight source record with character ranges into its fullText, or the native conversation/message/comment/post ids.
When kind is ‘insight’, the triage grouping key (source record id, conversation id, origin post id, or the insight’s own id for singletons). Legacy insights may be null and group as singletons.
insightSource: InsightSource | nullProvenance of an insight: which channel it came from and how it was captured.
Provenance of an insight: which channel it came from and how it was captured.
integrations: Integrations { clickup, devops, github, 4 more } Third-party integration links associated with this post
Third-party integration links associated with this post
kind: "issue" | "insight" | "record"Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Discriminates an actionable work item (‘issue’) from a customer submission whose claims were extracted into insights (‘record’ — not a work item). Defaults to ‘issue’ for all pre-existing posts. Default list responses return issues only; pass kind=‘record’ to opt in. Raw signal (‘insight’) is never returned by the posts resource — insights are served by /v2/insights.
Number of insights linked to this issue as supporting evidence. Only meaningful when kind is ‘issue’.
When kind is ‘insight’, the ID of the issue this insight supports. Null when the insight is unlinked or when kind is ‘issue’.
Total opportunity amount from linked HubSpot deals and Salesforce opportunities
True when the issue is hidden from portal/public surfaces. Missing stored values are returned as false.
Present and true only on POST /v2/posts, when the request carried a source.externalId that already had a post. The existing post is returned unchanged with HTTP 200; a newly created post returns HTTP 201 without this field.
intakeMode?: "request" | "feedback"Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
Present only on POST /v2/posts: the intakeMode the post was processed under (‘request’ when the request named none). On an idempotent replay (deduped: true) this is the mode the post was ORIGINALLY created with.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
On POST /v2/posts — queued: a processing run (claim extraction or the Organize rewrite) was enqueued and its result lands asynchronously on the post. skipped: nothing was enqueued; reason says which gate decided (‘request_mode’ for every intakeMode: ‘request’ create). existing: the create was an idempotent replay and the post was not processed again. On GET /v2/posts/{id} this field is present only for posts created with intakeMode: 'feedback' and reports how far that processing has got (‘queued’, ‘processing’, ‘complete’, ‘needs_review’, or ‘skipped’ with the same reason the create returned), with results listing what was made of the submission once the run has finished.
status: "queued" | "processing" | "complete" | 3 more‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
‘queued’ = an AI run was enqueued and has not landed yet; ‘processing’ = the run is working on the submission; ‘complete’ = it finished and results lists what it produced; ‘needs_review’ = it finished and a teammate still has to decide something; ‘skipped’ = nothing was enqueued (see reason); ‘existing’ = idempotent replay, not processed again.
reason?: "request_mode" | "autopilot_off" | "insights_disabled" | 11 moreWhy processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
Why processing was skipped. ‘request_mode’ = intakeMode was ‘request’ (the default); ‘autopilot_off’ = the workspace’s Autopilot dial is off or its plan does not include it; ‘pipeline_paused’ = the platform paused AI processing (it resumes automatically); ‘support_board’ / ‘spam_held’ / ‘staff_authored’ / ‘no_content’ = the post did not qualify; ‘source_too_long’ = the text was over the length limit when the run read it (a create that long is normally refused with a 400 first); ‘extraction_failed’ = the AI could not read the text after repeated attempts; nothing was written, and opening the post in Triage runs the analysis again.
results?: Array<Result>What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
What the workspace’s “Organize submissions” lane made of this submission, one entry per ask it found, in the order they appear in the text. Present on GET /v2/posts/{id} for posts created with intakeMode: 'feedback' once the run has finished. Absent while the run is still working, and absent for workspaces that do not organize submissions — there the post itself is the request.
outcome: "attached" | "request" | "question" | "held"‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
‘request’ = the ask became a request of its own; ‘attached’ = it was added as evidence to a request that already existed; ‘held’ = it became a request that is waiting for a teammate to publish it; ‘question’ = it asked something and no request was created, so a teammate answers it.
The request this ask became, or was attached to. Absent for a question, and absent when the request is not readable through this API (for example a ticket board).
reason?: "too_many_topics" | "uncertain" | "custom_fields" | "processing_failed"Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
Why a ‘held’ result is waiting for a teammate. Only on a ‘held’ result, and only one of these codes: ‘too_many_topics’ = the submission held more separate asks than one submission can become requests, so this one request lists the asks that did not fit, one line each in the customer’s words; ‘uncertain’ = the ask was too vague to file without a person; ‘custom_fields’ = the board requires custom fields this submission did not carry; ‘processing_failed’ = the AI could not rewrite the text (the request then holds the original words) or could not check this ask against existing requests, so a teammate confirms it is not a duplicate.
FeedbackPostsVoters
User-submitted feedback and feature requests. Posts belong to boards and can be upvoted, commented on, and tracked through statuses.
List voters on a post
Add a voter to a post
Remove a voter from a post
FeedbackPostsInsights
User-submitted feedback and feature requests. Posts belong to boards and can be upvoted, commented on, and tracked through statuses.
List the insights filed under a request
File a post as an insight under a request
Detach an insight from its request
Promote an insight into a request
FeedbackPost Statuses
Post statuses define the workflow stages for posts (e.g., In Review, Active, Completed).
List all post statuses
Get a post status by ID
FeedbackComments
Threaded discussions on posts and changelogs. Comments support voting, moderation, and privacy controls.
List comments
Create a new comment
Get a comment by ID
Update a comment
Delete a comment
Delete a comment
Search comments
ModelsExpand Collapse
CommentSearchResponse { data, nextCursor, object, 2 more }
FeedbackCustom Fields
Configurable input fields for posts in your Featurebase organization. Custom fields allow you to collect additional structured data when users create posts.