featurebase-node 0.15.1 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/client.d.mts +18 -6
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +18 -6
  5. package/client.d.ts.map +1 -1
  6. package/client.js +12 -0
  7. package/client.js.map +1 -1
  8. package/client.mjs +12 -0
  9. package/client.mjs.map +1 -1
  10. package/package.json +1 -1
  11. package/resources/away-reasons.d.mts +37 -0
  12. package/resources/away-reasons.d.mts.map +1 -0
  13. package/resources/away-reasons.d.ts +37 -0
  14. package/resources/away-reasons.d.ts.map +1 -0
  15. package/resources/away-reasons.js +31 -0
  16. package/resources/away-reasons.js.map +1 -0
  17. package/resources/away-reasons.mjs +27 -0
  18. package/resources/away-reasons.mjs.map +1 -0
  19. package/resources/changelogs/changelogs.d.mts +1166 -6
  20. package/resources/changelogs/changelogs.d.mts.map +1 -1
  21. package/resources/changelogs/changelogs.d.ts +1166 -6
  22. package/resources/changelogs/changelogs.d.ts.map +1 -1
  23. package/resources/changelogs/changelogs.js +53 -3
  24. package/resources/changelogs/changelogs.js.map +1 -1
  25. package/resources/changelogs/changelogs.mjs +53 -3
  26. package/resources/changelogs/changelogs.mjs.map +1 -1
  27. package/resources/changelogs/index.d.mts +1 -1
  28. package/resources/changelogs/index.d.mts.map +1 -1
  29. package/resources/changelogs/index.d.ts +1 -1
  30. package/resources/changelogs/index.d.ts.map +1 -1
  31. package/resources/changelogs/index.js.map +1 -1
  32. package/resources/changelogs/index.mjs.map +1 -1
  33. package/resources/feedback/comments.d.mts +4 -2
  34. package/resources/feedback/comments.d.mts.map +1 -1
  35. package/resources/feedback/comments.d.ts +4 -2
  36. package/resources/feedback/comments.d.ts.map +1 -1
  37. package/resources/feedback/custom-fields.d.mts +12 -0
  38. package/resources/feedback/custom-fields.d.mts.map +1 -1
  39. package/resources/feedback/custom-fields.d.ts +12 -0
  40. package/resources/feedback/custom-fields.d.ts.map +1 -1
  41. package/resources/feedback/feedback.d.mts +2 -2
  42. package/resources/feedback/feedback.d.mts.map +1 -1
  43. package/resources/feedback/feedback.d.ts +2 -2
  44. package/resources/feedback/feedback.d.ts.map +1 -1
  45. package/resources/feedback/feedback.js.map +1 -1
  46. package/resources/feedback/feedback.mjs.map +1 -1
  47. package/resources/feedback/index.d.mts +1 -1
  48. package/resources/feedback/index.d.mts.map +1 -1
  49. package/resources/feedback/index.d.ts +1 -1
  50. package/resources/feedback/index.d.ts.map +1 -1
  51. package/resources/feedback/index.js.map +1 -1
  52. package/resources/feedback/index.mjs.map +1 -1
  53. package/resources/feedback/posts/index.d.mts +2 -1
  54. package/resources/feedback/posts/index.d.mts.map +1 -1
  55. package/resources/feedback/posts/index.d.ts +2 -1
  56. package/resources/feedback/posts/index.d.ts.map +1 -1
  57. package/resources/feedback/posts/index.js +3 -1
  58. package/resources/feedback/posts/index.js.map +1 -1
  59. package/resources/feedback/posts/index.mjs +1 -0
  60. package/resources/feedback/posts/index.mjs.map +1 -1
  61. package/resources/feedback/posts/insights.d.mts +254 -0
  62. package/resources/feedback/posts/insights.d.mts.map +1 -0
  63. package/resources/feedback/posts/insights.d.ts +254 -0
  64. package/resources/feedback/posts/insights.d.ts.map +1 -0
  65. package/resources/feedback/posts/insights.js +269 -0
  66. package/resources/feedback/posts/insights.js.map +1 -0
  67. package/resources/feedback/posts/insights.mjs +265 -0
  68. package/resources/feedback/posts/insights.mjs.map +1 -0
  69. package/resources/feedback/posts/posts.d.mts +610 -21
  70. package/resources/feedback/posts/posts.d.mts.map +1 -1
  71. package/resources/feedback/posts/posts.d.ts +610 -21
  72. package/resources/feedback/posts/posts.d.ts.map +1 -1
  73. package/resources/feedback/posts/posts.js +199 -7
  74. package/resources/feedback/posts/posts.js.map +1 -1
  75. package/resources/feedback/posts/posts.mjs +199 -7
  76. package/resources/feedback/posts/posts.mjs.map +1 -1
  77. package/resources/index.d.mts +5 -3
  78. package/resources/index.d.mts.map +1 -1
  79. package/resources/index.d.ts +5 -3
  80. package/resources/index.d.ts.map +1 -1
  81. package/resources/index.js +5 -1
  82. package/resources/index.js.map +1 -1
  83. package/resources/index.mjs +2 -0
  84. package/resources/index.mjs.map +1 -1
  85. package/resources/organization/admins.d.mts +151 -4
  86. package/resources/organization/admins.d.mts.map +1 -1
  87. package/resources/organization/admins.d.ts +151 -4
  88. package/resources/organization/admins.d.ts.map +1 -1
  89. package/resources/organization/admins.js +58 -3
  90. package/resources/organization/admins.js.map +1 -1
  91. package/resources/organization/admins.mjs +58 -3
  92. package/resources/organization/admins.mjs.map +1 -1
  93. package/resources/organization/index.d.mts +2 -2
  94. package/resources/organization/index.d.mts.map +1 -1
  95. package/resources/organization/index.d.ts +2 -2
  96. package/resources/organization/index.d.ts.map +1 -1
  97. package/resources/organization/index.js.map +1 -1
  98. package/resources/organization/index.mjs.map +1 -1
  99. package/resources/organization/organization.d.mts +4 -4
  100. package/resources/organization/organization.d.mts.map +1 -1
  101. package/resources/organization/organization.d.ts +4 -4
  102. package/resources/organization/organization.d.ts.map +1 -1
  103. package/resources/organization/organization.js.map +1 -1
  104. package/resources/organization/organization.mjs +1 -1
  105. package/resources/organization/organization.mjs.map +1 -1
  106. package/resources/organization/teams.d.mts +34 -4
  107. package/resources/organization/teams.d.mts.map +1 -1
  108. package/resources/organization/teams.d.ts +34 -4
  109. package/resources/organization/teams.d.ts.map +1 -1
  110. package/resources/organization/teams.js +18 -3
  111. package/resources/organization/teams.js.map +1 -1
  112. package/resources/organization/teams.mjs +18 -3
  113. package/resources/organization/teams.mjs.map +1 -1
  114. package/resources/reports.d.mts +45 -1
  115. package/resources/reports.d.mts.map +1 -1
  116. package/resources/reports.d.ts +45 -1
  117. package/resources/reports.d.ts.map +1 -1
  118. package/resources/reports.js +35 -0
  119. package/resources/reports.js.map +1 -1
  120. package/resources/reports.mjs +35 -0
  121. package/resources/reports.mjs.map +1 -1
  122. package/resources/support/tickets/tickets.d.mts +9 -5
  123. package/resources/support/tickets/tickets.d.mts.map +1 -1
  124. package/resources/support/tickets/tickets.d.ts +9 -5
  125. package/resources/support/tickets/tickets.d.ts.map +1 -1
  126. package/resources/support/tickets/tickets.js.map +1 -1
  127. package/resources/support/tickets/tickets.mjs.map +1 -1
  128. package/resources/training-data/index.d.mts +1 -1
  129. package/resources/training-data/index.d.mts.map +1 -1
  130. package/resources/training-data/index.d.ts +1 -1
  131. package/resources/training-data/index.d.ts.map +1 -1
  132. package/resources/training-data/index.js.map +1 -1
  133. package/resources/training-data/index.mjs.map +1 -1
  134. package/resources/training-data/training-data.d.mts +66 -161
  135. package/resources/training-data/training-data.d.mts.map +1 -1
  136. package/resources/training-data/training-data.d.ts +66 -161
  137. package/resources/training-data/training-data.d.ts.map +1 -1
  138. package/resources/training-data/training-data.js.map +1 -1
  139. package/resources/training-data/training-data.mjs.map +1 -1
  140. package/resources/workload.d.mts +103 -0
  141. package/resources/workload.d.mts.map +1 -0
  142. package/resources/workload.d.ts +103 -0
  143. package/resources/workload.d.ts.map +1 -0
  144. package/resources/workload.js +32 -0
  145. package/resources/workload.js.map +1 -0
  146. package/resources/workload.mjs +28 -0
  147. package/resources/workload.mjs.map +1 -0
  148. package/src/client.ts +36 -0
  149. package/src/resources/away-reasons.ts +68 -0
  150. package/src/resources/changelogs/changelogs.ts +2003 -51
  151. package/src/resources/changelogs/index.ts +1 -0
  152. package/src/resources/feedback/comments.ts +4 -2
  153. package/src/resources/feedback/custom-fields.ts +15 -0
  154. package/src/resources/feedback/feedback.ts +4 -0
  155. package/src/resources/feedback/index.ts +2 -0
  156. package/src/resources/feedback/posts/index.ts +9 -0
  157. package/src/resources/feedback/posts/insights.ts +340 -0
  158. package/src/resources/feedback/posts/posts.ts +714 -20
  159. package/src/resources/index.ts +10 -0
  160. package/src/resources/organization/admins.ts +254 -3
  161. package/src/resources/organization/index.ts +8 -0
  162. package/src/resources/organization/organization.ts +23 -1
  163. package/src/resources/organization/teams.ts +69 -3
  164. package/src/resources/reports.ts +70 -0
  165. package/src/resources/support/tickets/tickets.ts +9 -5
  166. package/src/resources/training-data/index.ts +1 -0
  167. package/src/resources/training-data/training-data.ts +77 -193
  168. package/src/resources/workload.ts +179 -0
  169. package/src/version.ts +1 -1
  170. package/version.d.mts +1 -1
  171. package/version.d.ts +1 -1
  172. package/version.js +1 -1
  173. package/version.mjs +1 -1
@@ -1,6 +1,8 @@
1
1
  import { APIResource } from "../../../core/resource.mjs";
2
2
  import * as PostsAPI from "./posts.mjs";
3
3
  import * as PostStatusesAPI from "../post-statuses.mjs";
4
+ import * as InsightsAPI from "./insights.mjs";
5
+ import { InsightConvertToPostParams, InsightLinkParams, InsightListParams, InsightUnlinkParams, Insights } from "./insights.mjs";
4
6
  import * as VotersAPI from "./voters.mjs";
5
7
  import { VoterAddParams, VoterAddResponse, VoterListParams, VoterListResponse, VoterListResponsesCursorPage, VoterRemoveParams, VoterRemoveResponse, Voters } from "./voters.mjs";
6
8
  import * as TicketsAPI from "../../support/tickets/tickets.mjs";
@@ -12,16 +14,28 @@ import { RequestOptions } from "../../../internal/request-options.mjs";
12
14
  */
13
15
  export declare class Posts extends APIResource {
14
16
  voters: VotersAPI.Voters;
17
+ insights: InsightsAPI.Insights;
15
18
  /**
16
19
  * Creates a new post (feedback submission) in the specified board.
17
20
  *
18
21
  * ### Required Fields
19
22
  *
20
- * - `title` - Post title (minimum 2 characters)
21
- * - `boardId` - Board ID to create the post in
23
+ * - `title` - Post title (minimum 2 characters). Required unless `intakeMode` is
24
+ * `feedback`; see "Intake mode" below.
22
25
  *
23
26
  * ### Optional Fields
24
27
  *
28
+ * - `boardId` - Board ID to create the post in. Omit to use the organization's
29
+ * default board.
30
+ * - `intakeMode` - What the text is: `request` (default) or `feedback`. See
31
+ * "Intake mode" below.
32
+ * - `source` - Where the request came from:
33
+ * `{ channel, externalId, url?, conversationId?, label? }`. See "Provenance and
34
+ * idempotency" below.
35
+ * - `attachTo` - Id of an existing open request this post belongs with. The new
36
+ * post stays a post. See "attachTo, or link-insight?" below.
37
+ * - `internal` - Store this request on the hidden internal board (never
38
+ * portal-visible). Cannot be combined with `boardId`.
25
39
  * - `content` - Post content in HTML format
26
40
  * - `tags` - Array of tag names to attach
27
41
  * - `statusId` - Status ID to set (defaults to board's default status)
@@ -47,20 +61,155 @@ export declare class Posts extends APIResource {
47
61
  *
48
62
  * Resolution priority: `id` > `userId` > `email` > authenticated user
49
63
  *
64
+ * ### Intake mode
65
+ *
66
+ * `intakeMode` is the caller's declared intent, and the ONE field that selects how
67
+ * the post is processed. `author` and `source` only describe where the text came
68
+ * from; they never select the path.
69
+ *
70
+ * - `request` (default, and the behaviour of every call that does not send the
71
+ * field): a finished request. Stored exactly as supplied — no AI claim
72
+ * extraction, no rewrite — whoever the author is. Featurebase may still link
73
+ * existing customer evidence TO the new request in the background; that never
74
+ * modifies it.
75
+ * - `feedback`: raw customer feedback (a Slack message, a call note, a survey
76
+ * answer). Processed exactly like a post written on the portal: organized into a
77
+ * request when the workspace's "Organize submissions" lane is on, otherwise its
78
+ * claims are extracted and matched against existing requests. The workspace's
79
+ * Autopilot dial, plan, AI budget, moderation and spam settings all apply, and
80
+ * the post is processed even when it is filed under the API key's own user.
81
+ * `statusId` and `eta` are rejected in this mode (400): raw feedback carries no
82
+ * decision yet. Feedback creates are rate-limited per workspace more strictly
83
+ * than requests (429 with `Retry-After`).
84
+ *
85
+ * At most 5 requests organized from one submission notify the team (admin
86
+ * notifications, mentions, Slack, Discord and tracker pushes); the rest are
87
+ * created silently — still revealed, published and returned in
88
+ * `processing.results` — and still fire the `post.created` webhook.
89
+ *
90
+ * In `feedback` mode `title` is optional: raw text rarely has one. Omit it (or
91
+ * send it blank) and the first line of `content` becomes the title, cut to 120
92
+ * characters. `content` is then required — an empty title and an empty content
93
+ * together are rejected with a 400 on `content`. In `request` mode `title` stays
94
+ * required, minimum 2 characters.
95
+ *
96
+ * #### How much text a feedback create may carry
97
+ *
98
+ * Feedback text is read whole or not at all: up to the limit of its
99
+ * `source.channel` it is read in full, from the first line to the last; anything
100
+ * longer is rejected (400 on `content`) instead of being trimmed, and the error
101
+ * message states the limit and the length that was sent.
102
+ *
103
+ * | `source.channel` | Limit (characters) | Sized for |
104
+ * | ------------------ | ------------------ | -------------------------- |
105
+ * | `call` | 120,000 | a two-hour call transcript |
106
+ * | `email` | 60,000 | a long email thread |
107
+ * | `api` | 60,000 | a document or an export |
108
+ * | `slack`, `discord` | 30,000 | a thread or channel export |
109
+ *
110
+ * Text sent without a `source.channel` gets the `api` limit. The limits are the
111
+ * same for every workspace.
112
+ *
113
+ * The count is of plain text: the title and the content with its HTML markup
114
+ * removed. Workspaces that do not process feedback at all (the AI is switched off)
115
+ * have no limit — the text is stored exactly as sent. To send more, split it and
116
+ * give each part its own `source.externalId`.
117
+ *
118
+ * Long text takes longer. A short message is processed in seconds; a long one is
119
+ * read in parts, one after the other, and every ask it produces is then matched
120
+ * and filed in turn — allow tens of minutes for a two-hour transcript. An ask that
121
+ * comes up more than once in the same text is reported once. One submission yields
122
+ * at most 30 requests: when the text holds more separate asks than that, the 29
123
+ * strongest become requests as usual and the rest are listed — one line each, the
124
+ * ask and the customer's own words — in a single request held for a teammate.
125
+ * Where the workspace does not organize submissions, at most 50 asks are captured
126
+ * from one submission; the rest of a longer text is not read.
127
+ *
128
+ * Long feedback is rate-limited on its own: at most 20 submissions per workspace
129
+ * per hour may be longer than a single reading pass (about 16,000 characters where
130
+ * the workspace organizes submissions, otherwise 6,000 — 24,000 for a `call`).
131
+ * Past that the create answers 429 with `Retry-After`; shorter feedback is not
132
+ * affected.
133
+ *
134
+ * The response reports what happened in `intakeMode` and `processing`:
135
+ * `processing.status` is `queued` when an AI run was enqueued (its result lands on
136
+ * the post asynchronously), `skipped` with a `reason` when nothing was enqueued
137
+ * (`request_mode`, `autopilot_off`, `pipeline_paused`, `support_board`,
138
+ * `spam_held`, `staff_authored`, …), or `existing` on an idempotent replay. To
139
+ * read where the feedback ended up afterwards, fetch the post with
140
+ * `GET /v2/posts/{id}`.
141
+ *
142
+ * ### Provenance and idempotency
143
+ *
144
+ * `source` records where a request came from and makes the create idempotent:
145
+ *
146
+ * - `source.externalId` is the stable id of the message or record in your system.
147
+ * Sending the same `(channel, externalId)` twice returns the post created the
148
+ * first time, unchanged, with `deduped: true` — the first delivery always wins.
149
+ * - Ids are stored namespaced as `api:<externalId>`, so they can never collide
150
+ * with ids Featurebase writes itself.
151
+ * - `feedback`, `widget` and `support` are reserved for posts authored on the
152
+ * portal, the widget and the inbox, and are rejected with a 400.
153
+ * - With `source` and no `author`, the post is attributed to a guest named after
154
+ * `source.label` (or the channel), because a relayed request belongs to the
155
+ * customer who said it — not to the API key that carried it.
156
+ *
157
+ * ### attachTo, or link-insight?
158
+ *
159
+ * Both attach something to a request that already exists, and they do different
160
+ * things.
161
+ *
162
+ * `attachTo` records that the NEW post belongs with an existing request. **The
163
+ * post stays a post**: it keeps `kind: 'issue'`, it is still returned by
164
+ * `GET /v2/posts` and `GET /v2/posts/{id}`, it keeps its own votes, and its author
165
+ * does **not** become a supporter of the target — nothing about the target changes
166
+ * except that it now counts this post among the posts linked to it. The link is
167
+ * silent: no notification, no ack to the author. The post does **not** appear in
168
+ * `GET /v2/posts/{targetId}/insights` — that endpoint lists insights, and this is
169
+ * a post.
170
+ *
171
+ * `POST /v2/posts/{id}/link-insight` does the opposite: it files the post as a
172
+ * **quote** under the request. The post becomes an insight, leaves the posts
173
+ * resource (`GET /v2/posts/{id}` answers 404 afterwards), appears in
174
+ * `GET /v2/posts/{targetId}/insights`, and its author is rolled up as a supporter
175
+ * of the request.
176
+ *
177
+ * So: two customers asking for the same thing, and you want both to keep their own
178
+ * request row → `attachTo`. A sentence a customer said that is evidence for a
179
+ * request you already track → create the post, then call `link-insight` on it.
180
+ * Both take the same kind of target: an open request in this workspace.
181
+ *
182
+ * `attachTo` cannot be combined with `intakeMode: 'feedback'` (400
183
+ * `invalid_parameter` on `attachTo`): `attachTo` says where the text belongs, and
184
+ * `feedback` mode asks Featurebase to decide that for every ask the text contains.
185
+ * Pick one.
186
+ *
187
+ * The link is made AFTER the post is written, so an unusable target is a **422
188
+ * that says the post was created** — it is not rolled back. The target is refused
189
+ * when it does not exist in this workspace, is not a request (an insight or a
190
+ * record), was merged into another request, is a processed submission, is still
191
+ * awaiting moderation, is held as spam, or is the new post itself.
192
+ *
50
193
  * ### Backdating (Imports)
51
194
  *
52
195
  * - `createdAt` - Override creation date for importing historical data
53
196
  *
54
197
  * ### Response
55
198
  *
56
- * Returns the created post object with all fields populated.
199
+ * - **201** - the post was created. Returns the post object with all fields
200
+ * populated, plus `intakeMode` and `processing`.
201
+ * - **200** - a post already existed for this
202
+ * `(source.channel, source.externalId)`. Returns that post unchanged, with
203
+ * `deduped: true` and `processing.status: 'existing'`. A replay is answered from
204
+ * the existing post and never links anything a second time, whatever `attachTo`
205
+ * says.
206
+ * - **422** - `attachTo` named a request that cannot carry evidence (missing,
207
+ * merged, atomized, held for moderation or spam, not a request, or the post
208
+ * itself). **The post was still created**; the error message says so.
57
209
  *
58
210
  * @example
59
211
  * ```ts
60
- * const post = await client.feedback.posts.create({
61
- * boardId: '507f1f77bcf86cd799439011',
62
- * title: 'Add dark mode support',
63
- * });
212
+ * const post = await client.feedback.posts.create();
64
213
  * ```
65
214
  */
66
215
  create(params: PostCreateParams, options?: RequestOptions): APIPromise<Post>;
@@ -76,6 +225,46 @@ export declare class Posts extends APIResource {
76
225
  * - Engagement metrics
77
226
  * - Custom field values
78
227
  *
228
+ * ### Feedback processing
229
+ *
230
+ * For a post created with `intakeMode: 'feedback'`, the response also carries
231
+ * `processing`, which says how far Featurebase has got with the text and what it
232
+ * made of it. It is absent on every other post, and on the list endpoint.
233
+ *
234
+ * `processing.status`:
235
+ *
236
+ * - `queued` - the text was accepted and no result has landed yet
237
+ * - `processing` - Featurebase is organizing the submission right now
238
+ * - `complete` - it is done; `results` lists what came out of it
239
+ * - `needs_review` - it is done, and a teammate still has to decide something
240
+ * - `skipped` - nothing ran, and nothing will; `reason` says why (the same reason
241
+ * the create returned, for example `autopilot_off`). The post is stored exactly
242
+ * as it was sent.
243
+ *
244
+ * `processing.results` is present in workspaces that organize submissions, once
245
+ * the run has finished: one entry per ask found in the text, in the order they
246
+ * appear. Each entry has the ask's `title` and its `outcome`:
247
+ *
248
+ * - `request` - the ask became a request of its own
249
+ * - `attached` - it was added as evidence to a request that already existed
250
+ * - `held` - it became a request waiting for a teammate to publish it
251
+ * - `question` - it asked something; no request was created and a teammate answers
252
+ * it
253
+ *
254
+ * `postId` and `postTitle` name the request the ask became or was attached to.
255
+ * They are absent for a `question`, and absent when that request is not readable
256
+ * through this API.
257
+ *
258
+ * `held` results carry a `reason` code saying what the teammate still has to
259
+ * decide: `too_many_topics` (the submission held more separate asks than one
260
+ * submission can become requests, so this request lists the ones that did not
261
+ * fit), `uncertain`, `custom_fields` or `processing_failed` (the AI could not
262
+ * rewrite the text, or could not check the ask against existing requests, so a
263
+ * teammate confirms it). No other outcome carries it.
264
+ *
265
+ * Workspaces that do not organize submissions report `status` only: there the post
266
+ * you sent IS the request, so there is no separate result to list.
267
+ *
79
268
  * @example
80
269
  * ```ts
81
270
  * const post = await client.feedback.posts.retrieve(
@@ -165,6 +354,8 @@ export declare class Posts extends APIResource {
165
354
  * - `tags` - Filter by tag names (can be comma-separated or repeated)
166
355
  * - `q` - Search query for title/content
167
356
  * - `inReview` - Include posts pending moderation
357
+ * - `kind` - `issue` (default: work items) or `record`; insights are never served
358
+ * by this resource — use `/v2/insights`
168
359
  *
169
360
  * ### Sorting
170
361
  *
@@ -432,6 +623,12 @@ export interface Post {
432
623
  */
433
624
  id: string;
434
625
  access: PostAccess;
626
+ /**
627
+ * When kind is 'insight', where exactly the insight points back into its origin:
628
+ * an insight source record with character ranges into its fullText, or the native
629
+ * conversation/message/comment/post ids.
630
+ */
631
+ anchor: Post.Anchor | null;
435
632
  /**
436
633
  * ID of the admin assigned to this post, null if unassigned
437
634
  */
@@ -464,10 +661,20 @@ export interface Post {
464
661
  */
465
662
  eta: string | null;
466
663
  features: PostFeatures;
664
+ /**
665
+ * When kind is 'insight', the triage grouping key (source record id, conversation
666
+ * id, origin post id, or the insight's own id for singletons). Legacy insights may
667
+ * be null and group as singletons.
668
+ */
669
+ groupKey: string | null;
467
670
  /**
468
671
  * Whether the post is pending moderation review
469
672
  */
470
673
  inReview: boolean;
674
+ /**
675
+ * Provenance of an insight: which channel it came from and how it was captured.
676
+ */
677
+ insightSource: Post.InsightSource | null;
471
678
  /**
472
679
  * Third-party integration links associated with this post
473
680
  */
@@ -476,6 +683,24 @@ export interface Post {
476
683
  * Whether the post is pinned to the top
477
684
  */
478
685
  isPinned: boolean;
686
+ /**
687
+ * Discriminates an actionable work item ('issue') from a customer submission whose
688
+ * claims were extracted into insights ('record' — not a work item). Defaults to
689
+ * 'issue' for all pre-existing posts. Default list responses return issues only;
690
+ * pass kind='record' to opt in. Raw signal ('insight') is never returned by the
691
+ * posts resource — insights are served by /v2/insights.
692
+ */
693
+ kind: 'issue' | 'insight' | 'record';
694
+ /**
695
+ * Number of insights linked to this issue as supporting evidence. Only meaningful
696
+ * when kind is 'issue'.
697
+ */
698
+ linkedInsightCount: number;
699
+ /**
700
+ * When kind is 'insight', the ID of the issue this insight supports. Null when the
701
+ * insight is unlinked or when kind is 'issue'.
702
+ */
703
+ linkedIssueId: string | null;
479
704
  /**
480
705
  * Object type identifier
481
706
  */
@@ -484,6 +709,11 @@ export interface Post {
484
709
  * Total opportunity amount from linked HubSpot deals and Salesforce opportunities
485
710
  */
486
711
  opportunityAmount: number | null;
712
+ /**
713
+ * True when the issue is hidden from portal/public surfaces. Missing stored values
714
+ * are returned as false.
715
+ */
716
+ portalHidden: boolean;
487
717
  /**
488
718
  * Full URL to view the post
489
719
  */
@@ -509,8 +739,64 @@ export interface Post {
509
739
  * Total number of upvotes
510
740
  */
511
741
  upvotes: number;
742
+ /**
743
+ * Present and true only on POST /v2/posts, when the request carried a
744
+ * `source.externalId` that already had a post. The existing post is returned
745
+ * unchanged with HTTP 200; a newly created post returns HTTP 201 without this
746
+ * field.
747
+ */
748
+ deduped?: true;
749
+ /**
750
+ * Present only on POST /v2/posts: the `intakeMode` the post was processed under
751
+ * ('request' when the request named none). On an idempotent replay
752
+ * (`deduped: true`) this is the mode the post was ORIGINALLY created with.
753
+ */
754
+ intakeMode?: 'request' | 'feedback';
755
+ /**
756
+ * On POST /v2/posts — `queued`: a processing run (claim extraction or the Organize
757
+ * rewrite) was enqueued and its result lands asynchronously on the post.
758
+ * `skipped`: nothing was enqueued; `reason` says which gate decided
759
+ * ('request_mode' for every intakeMode: 'request' create). `existing`: the create
760
+ * was an idempotent replay and the post was not processed again. On GET
761
+ * /v2/posts/{id} this field is present only for posts created with
762
+ * `intakeMode: 'feedback'` and reports how far that processing has got ('queued',
763
+ * 'processing', 'complete', 'needs_review', or 'skipped' with the same `reason`
764
+ * the create returned), with `results` listing what was made of the submission
765
+ * once the run has finished.
766
+ */
767
+ processing?: PostProcessing;
512
768
  }
513
769
  export declare namespace Post {
770
+ /**
771
+ * When kind is 'insight', where exactly the insight points back into its origin:
772
+ * an insight source record with character ranges into its fullText, or the native
773
+ * conversation/message/comment/post ids.
774
+ */
775
+ interface Anchor {
776
+ commentId?: string | null;
777
+ conversationId?: string | null;
778
+ messageId?: string | null;
779
+ ranges?: Array<Anchor.Range> | null;
780
+ sourceRecordId?: string | null;
781
+ submissionId?: string | null;
782
+ }
783
+ namespace Anchor {
784
+ interface Range {
785
+ end: number;
786
+ start: number;
787
+ }
788
+ }
789
+ /**
790
+ * Provenance of an insight: which channel it came from and how it was captured.
791
+ */
792
+ interface InsightSource {
793
+ channel: 'slack' | 'discord' | 'email' | 'support' | 'widget' | 'call' | 'api' | 'feedback';
794
+ capturedBy?: 'manual' | 'auto' | 'ai' | 'api' | null;
795
+ conversationId?: string | null;
796
+ externalId?: string | null;
797
+ sourceLabel?: string | null;
798
+ url?: string | null;
799
+ }
514
800
  /**
515
801
  * Third-party integration links associated with this post
516
802
  */
@@ -686,6 +972,126 @@ export interface PostFeatures {
686
972
  */
687
973
  commentsEnabled: boolean;
688
974
  }
975
+ export interface PostList {
976
+ /**
977
+ * Array of posts
978
+ */
979
+ data: Array<Post>;
980
+ /**
981
+ * Cursor for fetching the next page (cursor-based pagination)
982
+ */
983
+ nextCursor: string | null;
984
+ /**
985
+ * Object type identifier
986
+ */
987
+ object: 'list';
988
+ /**
989
+ * Pagination metadata for page-based requests
990
+ */
991
+ pagination?: PostList.Pagination;
992
+ }
993
+ export declare namespace PostList {
994
+ /**
995
+ * Pagination metadata for page-based requests
996
+ */
997
+ interface Pagination {
998
+ /**
999
+ * Items per page
1000
+ */
1001
+ limit: number;
1002
+ /**
1003
+ * Current page number
1004
+ */
1005
+ page: number;
1006
+ /**
1007
+ * Total number of items
1008
+ */
1009
+ total: number;
1010
+ /**
1011
+ * Total number of pages
1012
+ */
1013
+ totalPages: number;
1014
+ }
1015
+ }
1016
+ /**
1017
+ * On POST /v2/posts — `queued`: a processing run (claim extraction or the Organize
1018
+ * rewrite) was enqueued and its result lands asynchronously on the post.
1019
+ * `skipped`: nothing was enqueued; `reason` says which gate decided
1020
+ * ('request_mode' for every intakeMode: 'request' create). `existing`: the create
1021
+ * was an idempotent replay and the post was not processed again. On GET
1022
+ * /v2/posts/{id} this field is present only for posts created with
1023
+ * `intakeMode: 'feedback'` and reports how far that processing has got ('queued',
1024
+ * 'processing', 'complete', 'needs_review', or 'skipped' with the same `reason`
1025
+ * the create returned), with `results` listing what was made of the submission
1026
+ * once the run has finished.
1027
+ */
1028
+ export interface PostProcessing {
1029
+ /**
1030
+ * 'queued' = an AI run was enqueued and has not landed yet; 'processing' = the run
1031
+ * is working on the submission; 'complete' = it finished and `results` lists what
1032
+ * it produced; 'needs_review' = it finished and a teammate still has to decide
1033
+ * something; 'skipped' = nothing was enqueued (see `reason`); 'existing' =
1034
+ * idempotent replay, not processed again.
1035
+ */
1036
+ status: 'queued' | 'processing' | 'complete' | 'needs_review' | 'skipped' | 'existing';
1037
+ /**
1038
+ * Why processing was skipped. 'request_mode' = intakeMode was 'request' (the
1039
+ * default); 'autopilot_off' = the workspace's Autopilot dial is off or its plan
1040
+ * does not include it; 'pipeline_paused' = the platform paused AI processing (it
1041
+ * resumes automatically); 'support_board' / 'spam_held' / 'staff_authored' /
1042
+ * 'no_content' = the post did not qualify; 'source_too_long' = the text was over
1043
+ * the length limit when the run read it (a create that long is normally refused
1044
+ * with a 400 first); 'extraction_failed' = the AI could not read the text after
1045
+ * repeated attempts; nothing was written, and opening the post in Triage runs the
1046
+ * analysis again.
1047
+ */
1048
+ reason?: 'request_mode' | 'autopilot_off' | 'insights_disabled' | 'pipeline_paused' | 'support_board' | 'spam_held' | 'staff_authored' | 'not_a_post' | 'no_board' | 'no_id' | 'no_content' | 'source_too_long' | 'extraction_failed' | 'hook_error';
1049
+ /**
1050
+ * What the workspace's "Organize submissions" lane made of this submission, one
1051
+ * entry per ask it found, in the order they appear in the text. Present on GET
1052
+ * /v2/posts/{id} for posts created with `intakeMode: 'feedback'` once the run has
1053
+ * finished. Absent while the run is still working, and absent for workspaces that
1054
+ * do not organize submissions — there the post itself is the request.
1055
+ */
1056
+ results?: Array<PostProcessing.Result>;
1057
+ }
1058
+ export declare namespace PostProcessing {
1059
+ interface Result {
1060
+ /**
1061
+ * 'request' = the ask became a request of its own; 'attached' = it was added as
1062
+ * evidence to a request that already existed; 'held' = it became a request that is
1063
+ * waiting for a teammate to publish it; 'question' = it asked something and no
1064
+ * request was created, so a teammate answers it.
1065
+ */
1066
+ outcome: 'attached' | 'request' | 'question' | 'held';
1067
+ /**
1068
+ * The ask, as it was written up.
1069
+ */
1070
+ title: string;
1071
+ /**
1072
+ * The request this ask became, or was attached to. Absent for a question, and
1073
+ * absent when the request is not readable through this API (for example a ticket
1074
+ * board).
1075
+ */
1076
+ postId?: string;
1077
+ /**
1078
+ * Title of `postId`.
1079
+ */
1080
+ postTitle?: string;
1081
+ /**
1082
+ * Why a 'held' result is waiting for a teammate. Only on a 'held' result, and only
1083
+ * one of these codes: 'too_many_topics' = the submission held more separate asks
1084
+ * than one submission can become requests, so this one request lists the asks that
1085
+ * did not fit, one line each in the customer's words; 'uncertain' = the ask was
1086
+ * too vague to file without a person; 'custom_fields' = the board requires custom
1087
+ * fields this submission did not carry; 'processing_failed' = the AI could not
1088
+ * rewrite the text (the request then holds the original words) or could not check
1089
+ * this ask against existing requests, so a teammate confirms it is not a
1090
+ * duplicate.
1091
+ */
1092
+ reason?: 'too_many_topics' | 'uncertain' | 'custom_fields' | 'processing_failed';
1093
+ }
1094
+ }
689
1095
  export interface PostTag {
690
1096
  /**
691
1097
  * Tag unique identifier
@@ -770,6 +1176,12 @@ export declare namespace PostSearchResponse {
770
1176
  */
771
1177
  id: string;
772
1178
  access: PostsAPI.PostAccess;
1179
+ /**
1180
+ * When kind is 'insight', where exactly the insight points back into its origin:
1181
+ * an insight source record with character ranges into its fullText, or the native
1182
+ * conversation/message/comment/post ids.
1183
+ */
1184
+ anchor: Data.Anchor | null;
773
1185
  /**
774
1186
  * ID of the admin assigned to this post, null if unassigned
775
1187
  */
@@ -802,10 +1214,20 @@ export declare namespace PostSearchResponse {
802
1214
  */
803
1215
  eta: string | null;
804
1216
  features: PostsAPI.PostFeatures;
1217
+ /**
1218
+ * When kind is 'insight', the triage grouping key (source record id, conversation
1219
+ * id, origin post id, or the insight's own id for singletons). Legacy insights may
1220
+ * be null and group as singletons.
1221
+ */
1222
+ groupKey: string | null;
805
1223
  /**
806
1224
  * Whether the post is pending moderation review
807
1225
  */
808
1226
  inReview: boolean;
1227
+ /**
1228
+ * Provenance of an insight: which channel it came from and how it was captured.
1229
+ */
1230
+ insightSource: Data.InsightSource | null;
809
1231
  /**
810
1232
  * Third-party integration links associated with this post
811
1233
  */
@@ -814,6 +1236,24 @@ export declare namespace PostSearchResponse {
814
1236
  * Whether the post is pinned to the top
815
1237
  */
816
1238
  isPinned: boolean;
1239
+ /**
1240
+ * Discriminates an actionable work item ('issue') from a customer submission whose
1241
+ * claims were extracted into insights ('record' — not a work item). Defaults to
1242
+ * 'issue' for all pre-existing posts. Default list responses return issues only;
1243
+ * pass kind='record' to opt in. Raw signal ('insight') is never returned by the
1244
+ * posts resource — insights are served by /v2/insights.
1245
+ */
1246
+ kind: 'issue' | 'insight' | 'record';
1247
+ /**
1248
+ * Number of insights linked to this issue as supporting evidence. Only meaningful
1249
+ * when kind is 'issue'.
1250
+ */
1251
+ linkedInsightCount: number;
1252
+ /**
1253
+ * When kind is 'insight', the ID of the issue this insight supports. Null when the
1254
+ * insight is unlinked or when kind is 'issue'.
1255
+ */
1256
+ linkedIssueId: string | null;
817
1257
  /**
818
1258
  * Object type identifier
819
1259
  */
@@ -822,6 +1262,11 @@ export declare namespace PostSearchResponse {
822
1262
  * Total opportunity amount from linked HubSpot deals and Salesforce opportunities
823
1263
  */
824
1264
  opportunityAmount: number | null;
1265
+ /**
1266
+ * True when the issue is hidden from portal/public surfaces. Missing stored values
1267
+ * are returned as false.
1268
+ */
1269
+ portalHidden: boolean;
825
1270
  /**
826
1271
  * Full URL to view the post
827
1272
  */
@@ -847,8 +1292,64 @@ export declare namespace PostSearchResponse {
847
1292
  * Total number of upvotes
848
1293
  */
849
1294
  upvotes: number;
1295
+ /**
1296
+ * Present and true only on POST /v2/posts, when the request carried a
1297
+ * `source.externalId` that already had a post. The existing post is returned
1298
+ * unchanged with HTTP 200; a newly created post returns HTTP 201 without this
1299
+ * field.
1300
+ */
1301
+ deduped?: true;
1302
+ /**
1303
+ * Present only on POST /v2/posts: the `intakeMode` the post was processed under
1304
+ * ('request' when the request named none). On an idempotent replay
1305
+ * (`deduped: true`) this is the mode the post was ORIGINALLY created with.
1306
+ */
1307
+ intakeMode?: 'request' | 'feedback';
1308
+ /**
1309
+ * On POST /v2/posts — `queued`: a processing run (claim extraction or the Organize
1310
+ * rewrite) was enqueued and its result lands asynchronously on the post.
1311
+ * `skipped`: nothing was enqueued; `reason` says which gate decided
1312
+ * ('request_mode' for every intakeMode: 'request' create). `existing`: the create
1313
+ * was an idempotent replay and the post was not processed again. On GET
1314
+ * /v2/posts/{id} this field is present only for posts created with
1315
+ * `intakeMode: 'feedback'` and reports how far that processing has got ('queued',
1316
+ * 'processing', 'complete', 'needs_review', or 'skipped' with the same `reason`
1317
+ * the create returned), with `results` listing what was made of the submission
1318
+ * once the run has finished.
1319
+ */
1320
+ processing?: PostsAPI.PostProcessing;
850
1321
  }
851
1322
  namespace Data {
1323
+ /**
1324
+ * When kind is 'insight', where exactly the insight points back into its origin:
1325
+ * an insight source record with character ranges into its fullText, or the native
1326
+ * conversation/message/comment/post ids.
1327
+ */
1328
+ interface Anchor {
1329
+ commentId?: string | null;
1330
+ conversationId?: string | null;
1331
+ messageId?: string | null;
1332
+ ranges?: Array<Anchor.Range> | null;
1333
+ sourceRecordId?: string | null;
1334
+ submissionId?: string | null;
1335
+ }
1336
+ namespace Anchor {
1337
+ interface Range {
1338
+ end: number;
1339
+ start: number;
1340
+ }
1341
+ }
1342
+ /**
1343
+ * Provenance of an insight: which channel it came from and how it was captured.
1344
+ */
1345
+ interface InsightSource {
1346
+ channel: 'slack' | 'discord' | 'email' | 'support' | 'widget' | 'call' | 'api' | 'feedback';
1347
+ capturedBy?: 'manual' | 'auto' | 'ai' | 'api' | null;
1348
+ conversationId?: string | null;
1349
+ externalId?: string | null;
1350
+ sourceLabel?: string | null;
1351
+ url?: string | null;
1352
+ }
852
1353
  /**
853
1354
  * Third-party integration links associated with this post
854
1355
  */
@@ -984,30 +1485,36 @@ export declare namespace PostSearchResponse {
984
1485
  }
985
1486
  }
986
1487
  export interface PostCreateParams {
987
- /**
988
- * Body param: Board ID to create post in
989
- */
990
- boardId: string;
991
- /**
992
- * Body param: Post title
993
- */
994
- title: string;
995
1488
  /**
996
1489
  * Body param: Admin ID to assign this post to
997
1490
  */
998
1491
  assigneeId?: string;
1492
+ /**
1493
+ * Body param: Id of an existing open request this post is evidence for. The post
1494
+ * is created, then linked.
1495
+ */
1496
+ attachTo?: string;
999
1497
  /**
1000
1498
  * Body param: Author to attribute the post to. If not provided, uses the
1001
- * authenticated user. Supports multiple identification methods: id (Featurebase
1002
- * ID), userId (external SSO ID), or email.
1499
+ * authenticated user unless `source` is given, in which case a guest author is
1500
+ * synthesised from `source.label` (or the channel name), because a relayed request
1501
+ * belongs to the customer who said it. Supports multiple identification methods:
1502
+ * id (Featurebase ID), userId (external SSO ID), or email.
1003
1503
  */
1004
1504
  author?: TicketsAPI.AuthorInput;
1505
+ /**
1506
+ * Body param: Board ID to create the post in. Omit to use the default board of the
1507
+ * organization.
1508
+ */
1509
+ boardId?: string;
1005
1510
  /**
1006
1511
  * Body param: Whether comments are enabled on this post
1007
1512
  */
1008
1513
  commentsEnabled?: boolean | null;
1009
1514
  /**
1010
- * Body param: Post content (HTML)
1515
+ * Body param: Post content (HTML). Required when `intakeMode` is 'feedback' and no
1516
+ * title is given. In 'feedback' mode its plain text is limited by `source.channel`
1517
+ * (see `intakeMode`); longer content is rejected with a 400.
1011
1518
  */
1012
1519
  content?: string;
1013
1520
  /**
@@ -1030,18 +1537,51 @@ export interface PostCreateParams {
1030
1537
  * Body param: Whether post is pending moderation
1031
1538
  */
1032
1539
  inReview?: boolean | null;
1540
+ /**
1541
+ * Body param: What the text is. 'request' (default): a finished request — stored
1542
+ * exactly as supplied, no AI claim extraction, regardless of author. 'feedback':
1543
+ * raw customer feedback — processed like a portal post (organized into a request,
1544
+ * or its claims extracted and matched against existing requests) under the
1545
+ * workspace's Autopilot dial, plan, AI budget and moderation settings. In
1546
+ * 'feedback' mode `title` is optional (the first line of `content` becomes it),
1547
+ * `statusId` and `eta` are rejected (400) because raw feedback has no decision
1548
+ * yet, and text is read in full up to the limit of its `source.channel` — 120,000
1549
+ * characters of plain text for 'call' (a two-hour transcript), 60,000 for 'email'
1550
+ * and 'api', 30,000 for 'slack' and 'discord'; without a `source.channel` the
1551
+ * 'api' limit applies — while anything longer is rejected (400) rather than
1552
+ * trimmed. Long text takes tens of minutes rather than seconds to process, and one
1553
+ * submission yields at most 30 requests.
1554
+ */
1555
+ intakeMode?: 'request' | 'feedback';
1033
1556
  /**
1034
1557
  * Body param: Push the created post to third-party integrations configured on your
1035
1558
  * organization. Each integration must be explicitly set to true to trigger;
1036
1559
  * omitted integrations will not be pushed to.
1037
1560
  */
1038
1561
  integrations?: PostCreateParams.Integrations;
1562
+ /**
1563
+ * Body param: Create this request on the internal board. Never visible on the
1564
+ * portal.
1565
+ */
1566
+ internal?: boolean;
1039
1567
  /**
1040
1568
  * Body param: Whether to send email notifications to admins when this post is
1041
1569
  * created. When true, admins will receive the same email notifications as when a
1042
1570
  * post is created from the dashboard. Defaults to false (no emails sent).
1043
1571
  */
1044
1572
  notifyAdmins?: boolean;
1573
+ /**
1574
+ * Body param: When true, hides the issue from portal/public surfaces. Omitted or
1575
+ * false is visible.
1576
+ */
1577
+ portalHidden?: boolean;
1578
+ /**
1579
+ * Body param: Provenance of this request, and the idempotency key for the create.
1580
+ * With `source` and no `author`, the post is attributed to a guest named after
1581
+ * `label` (or the channel) so it belongs to the customer who said it, not to the
1582
+ * API key.
1583
+ */
1584
+ source?: PostCreateParams.Source;
1045
1585
  /**
1046
1586
  * Body param: Status ID to set
1047
1587
  */
@@ -1050,6 +1590,12 @@ export interface PostCreateParams {
1050
1590
  * Body param: Tag names to attach
1051
1591
  */
1052
1592
  tags?: string | Array<string>;
1593
+ /**
1594
+ * Body param: Post title. Required unless `intakeMode` is 'feedback', where raw
1595
+ * customer text rarely has one: omit it (or send it blank) and the first line of
1596
+ * `content` becomes the title, cut to 120 characters.
1597
+ */
1598
+ title?: string;
1053
1599
  /**
1054
1600
  * Body param: Initial upvotes count. Defaults to 1 (post author is automatically
1055
1601
  * added as voter). Use 0 to create a post without any votes.
@@ -1099,6 +1645,40 @@ export declare namespace PostCreateParams {
1099
1645
  */
1100
1646
  slack?: boolean;
1101
1647
  }
1648
+ /**
1649
+ * Provenance of this request, and the idempotency key for the create. With
1650
+ * `source` and no `author`, the post is attributed to a guest named after `label`
1651
+ * (or the channel) so it belongs to the customer who said it, not to the API key.
1652
+ */
1653
+ interface Source {
1654
+ /**
1655
+ * Channel the request arrived on. 'feedback', 'widget' and 'support' are reserved
1656
+ * for posts authored on the portal, the widget and the inbox, and are rejected
1657
+ * with a 400. With `intakeMode: 'feedback'` the channel also sets how much text is
1658
+ * read: 'call' 120,000 characters, 'email' and 'api' 60,000, 'slack' and 'discord'
1659
+ * 30,000.
1660
+ */
1661
+ channel: 'slack' | 'discord' | 'email' | 'support' | 'widget' | 'call' | 'api' | 'feedback';
1662
+ /**
1663
+ * Stable id of the message/record in the source system. Sending the same (channel,
1664
+ * externalId) twice returns the post created the first time instead of a duplicate
1665
+ * (HTTP 200 with `deduped: true`). Stored namespaced as `api:<externalId>`.
1666
+ */
1667
+ externalId: string;
1668
+ /**
1669
+ * Id of the support conversation this request came from
1670
+ */
1671
+ conversationId?: string;
1672
+ /**
1673
+ * Display name of the specific source. Also names the guest author when no
1674
+ * `author` is given.
1675
+ */
1676
+ label?: string;
1677
+ /**
1678
+ * Deep link back to the original message/record
1679
+ */
1680
+ url?: string;
1681
+ }
1102
1682
  }
1103
1683
  export interface PostRetrieveParams {
1104
1684
  /**
@@ -1114,8 +1694,10 @@ export interface PostUpdateParams {
1114
1694
  assigneeId?: string | null;
1115
1695
  /**
1116
1696
  * Body param: Author to attribute the post to. If not provided, uses the
1117
- * authenticated user. Supports multiple identification methods: id (Featurebase
1118
- * ID), userId (external SSO ID), or email.
1697
+ * authenticated user unless `source` is given, in which case a guest author is
1698
+ * synthesised from `source.label` (or the channel name), because a relayed request
1699
+ * belongs to the customer who said it. Supports multiple identification methods:
1700
+ * id (Featurebase ID), userId (external SSO ID), or email.
1119
1701
  */
1120
1702
  author?: TicketsAPI.AuthorInput;
1121
1703
  /**
@@ -1192,6 +1774,12 @@ export interface PostListParams extends CursorPageParams {
1192
1774
  * Query param: Include posts that are in review
1193
1775
  */
1194
1776
  inReview?: boolean | null;
1777
+ /**
1778
+ * Query param: Filter by submission kind. Omitted or 'issue' returns work items
1779
+ * only. Pass 'record' for customer submissions whose claims were extracted into
1780
+ * insights. Insights are never served by this resource — use /v2/insights.
1781
+ */
1782
+ kind?: 'issue' | 'record';
1195
1783
  /**
1196
1784
  * Query param: Search query to filter posts by title/content
1197
1785
  */
@@ -1288,7 +1876,8 @@ export interface PostUnmergeParams {
1288
1876
  'Featurebase-Version'?: '2026-08-19.orbit' | '2026-01-01.nova' | '2025-12-12.clover';
1289
1877
  }
1290
1878
  export declare namespace Posts {
1291
- export { type Post as Post, type PostAccess as PostAccess, type PostAuthor as PostAuthor, type PostFeatures as PostFeatures, type PostTag as PostTag, type SearchFilter as SearchFilter, type SearchFilterGroup as SearchFilterGroup, type PostDeleteResponse as PostDeleteResponse, type PostSearchResponse as PostSearchResponse, type PostsCursorPage as PostsCursorPage, type PostCreateParams as PostCreateParams, type PostRetrieveParams as PostRetrieveParams, type PostUpdateParams as PostUpdateParams, type PostListParams as PostListParams, type PostDeleteParams as PostDeleteParams, type PostMergeParams as PostMergeParams, type PostSearchParams as PostSearchParams, type PostUnmergeParams as PostUnmergeParams, };
1879
+ export { type Post as Post, type PostAccess as PostAccess, type PostAuthor as PostAuthor, type PostFeatures as PostFeatures, type PostList as PostList, type PostProcessing as PostProcessing, type PostTag as PostTag, type SearchFilter as SearchFilter, type SearchFilterGroup as SearchFilterGroup, type PostDeleteResponse as PostDeleteResponse, type PostSearchResponse as PostSearchResponse, type PostsCursorPage as PostsCursorPage, type PostCreateParams as PostCreateParams, type PostRetrieveParams as PostRetrieveParams, type PostUpdateParams as PostUpdateParams, type PostListParams as PostListParams, type PostDeleteParams as PostDeleteParams, type PostMergeParams as PostMergeParams, type PostSearchParams as PostSearchParams, type PostUnmergeParams as PostUnmergeParams, };
1292
1880
  export { Voters as Voters, type VoterListResponse as VoterListResponse, type VoterAddResponse as VoterAddResponse, type VoterRemoveResponse as VoterRemoveResponse, type VoterListResponsesCursorPage as VoterListResponsesCursorPage, type VoterListParams as VoterListParams, type VoterAddParams as VoterAddParams, type VoterRemoveParams as VoterRemoveParams, };
1881
+ export { Insights as Insights, type InsightListParams as InsightListParams, type InsightConvertToPostParams as InsightConvertToPostParams, type InsightLinkParams as InsightLinkParams, type InsightUnlinkParams as InsightUnlinkParams, };
1293
1882
  }
1294
1883
  //# sourceMappingURL=posts.d.mts.map