featurebase-node 0.11.0 → 0.13.0

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 (103) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/internal/utils/log.d.mts.map +1 -1
  3. package/internal/utils/log.d.ts.map +1 -1
  4. package/internal/utils/log.js +2 -0
  5. package/internal/utils/log.js.map +1 -1
  6. package/internal/utils/log.mjs +2 -0
  7. package/internal/utils/log.mjs.map +1 -1
  8. package/package.json +1 -1
  9. package/resources/feedback/comments.d.mts +340 -1
  10. package/resources/feedback/comments.d.mts.map +1 -1
  11. package/resources/feedback/comments.d.ts +340 -1
  12. package/resources/feedback/comments.d.ts.map +1 -1
  13. package/resources/feedback/comments.js +160 -0
  14. package/resources/feedback/comments.js.map +1 -1
  15. package/resources/feedback/comments.mjs +160 -0
  16. package/resources/feedback/comments.mjs.map +1 -1
  17. package/resources/feedback/feedback.d.mts +4 -4
  18. package/resources/feedback/feedback.d.mts.map +1 -1
  19. package/resources/feedback/feedback.d.ts +4 -4
  20. package/resources/feedback/feedback.d.ts.map +1 -1
  21. package/resources/feedback/feedback.js.map +1 -1
  22. package/resources/feedback/feedback.mjs.map +1 -1
  23. package/resources/feedback/index.d.mts +2 -2
  24. package/resources/feedback/index.d.mts.map +1 -1
  25. package/resources/feedback/index.d.ts +2 -2
  26. package/resources/feedback/index.d.ts.map +1 -1
  27. package/resources/feedback/index.js.map +1 -1
  28. package/resources/feedback/index.mjs.map +1 -1
  29. package/resources/feedback/posts/index.d.mts +1 -1
  30. package/resources/feedback/posts/index.d.mts.map +1 -1
  31. package/resources/feedback/posts/index.d.ts +1 -1
  32. package/resources/feedback/posts/index.d.ts.map +1 -1
  33. package/resources/feedback/posts/index.js.map +1 -1
  34. package/resources/feedback/posts/index.mjs.map +1 -1
  35. package/resources/feedback/posts/posts.d.mts +547 -1
  36. package/resources/feedback/posts/posts.d.mts.map +1 -1
  37. package/resources/feedback/posts/posts.d.ts +547 -1
  38. package/resources/feedback/posts/posts.d.ts.map +1 -1
  39. package/resources/feedback/posts/posts.js +181 -0
  40. package/resources/feedback/posts/posts.js.map +1 -1
  41. package/resources/feedback/posts/posts.mjs +181 -0
  42. package/resources/feedback/posts/posts.mjs.map +1 -1
  43. package/resources/help-center/articles.d.mts +407 -1
  44. package/resources/help-center/articles.d.mts.map +1 -1
  45. package/resources/help-center/articles.d.ts +407 -1
  46. package/resources/help-center/articles.d.ts.map +1 -1
  47. package/resources/help-center/articles.js +130 -0
  48. package/resources/help-center/articles.js.map +1 -1
  49. package/resources/help-center/articles.mjs +130 -0
  50. package/resources/help-center/articles.mjs.map +1 -1
  51. package/resources/help-center/help-center.d.mts +2 -2
  52. package/resources/help-center/help-center.d.mts.map +1 -1
  53. package/resources/help-center/help-center.d.ts +2 -2
  54. package/resources/help-center/help-center.d.ts.map +1 -1
  55. package/resources/help-center/help-center.js.map +1 -1
  56. package/resources/help-center/help-center.mjs.map +1 -1
  57. package/resources/help-center/index.d.mts +1 -1
  58. package/resources/help-center/index.d.mts.map +1 -1
  59. package/resources/help-center/index.d.ts +1 -1
  60. package/resources/help-center/index.d.ts.map +1 -1
  61. package/resources/help-center/index.js.map +1 -1
  62. package/resources/help-center/index.mjs.map +1 -1
  63. package/resources/support/conversations/conversations.d.mts +27 -19
  64. package/resources/support/conversations/conversations.d.mts.map +1 -1
  65. package/resources/support/conversations/conversations.d.ts +27 -19
  66. package/resources/support/conversations/conversations.d.ts.map +1 -1
  67. package/resources/support/conversations/conversations.js +20 -14
  68. package/resources/support/conversations/conversations.js.map +1 -1
  69. package/resources/support/conversations/conversations.mjs +20 -14
  70. package/resources/support/conversations/conversations.mjs.map +1 -1
  71. package/resources/users/companies/companies.d.mts +33 -20
  72. package/resources/users/companies/companies.d.mts.map +1 -1
  73. package/resources/users/companies/companies.d.ts +33 -20
  74. package/resources/users/companies/companies.d.ts.map +1 -1
  75. package/resources/users/companies/companies.js +28 -17
  76. package/resources/users/companies/companies.js.map +1 -1
  77. package/resources/users/companies/companies.mjs +28 -17
  78. package/resources/users/companies/companies.mjs.map +1 -1
  79. package/resources/users/contacts/contacts.d.mts +33 -21
  80. package/resources/users/contacts/contacts.d.mts.map +1 -1
  81. package/resources/users/contacts/contacts.d.ts +33 -21
  82. package/resources/users/contacts/contacts.d.ts.map +1 -1
  83. package/resources/users/contacts/contacts.js +27 -17
  84. package/resources/users/contacts/contacts.js.map +1 -1
  85. package/resources/users/contacts/contacts.mjs +27 -17
  86. package/resources/users/contacts/contacts.mjs.map +1 -1
  87. package/src/internal/utils/log.ts +2 -0
  88. package/src/resources/feedback/comments.ts +396 -0
  89. package/src/resources/feedback/feedback.ts +8 -0
  90. package/src/resources/feedback/index.ts +4 -0
  91. package/src/resources/feedback/posts/index.ts +2 -0
  92. package/src/resources/feedback/posts/posts.ts +671 -0
  93. package/src/resources/help-center/articles.ts +686 -0
  94. package/src/resources/help-center/help-center.ts +4 -0
  95. package/src/resources/help-center/index.ts +2 -0
  96. package/src/resources/support/conversations/conversations.ts +27 -19
  97. package/src/resources/users/companies/companies.ts +38 -19
  98. package/src/resources/users/contacts/contacts.ts +40 -20
  99. package/src/version.ts +1 -1
  100. package/version.d.mts +1 -1
  101. package/version.d.ts +1 -1
  102. package/version.js +1 -1
  103. package/version.mjs +1 -1
@@ -313,6 +313,188 @@ export class Posts extends APIResource {
313
313
  ]),
314
314
  });
315
315
  }
316
+
317
+ /**
318
+ * Search feedback posts with a structured filter AST, full-text search, sorting,
319
+ * and cursor pagination.
320
+ *
321
+ * ### Two modes (combinable)
322
+ *
323
+ * - **Filter mode** — pass a structured `query` AST (and/or `sort`) and the
324
+ * endpoint returns posts matching the filter, ordered by `sort` (default
325
+ * `createdAt:desc`). Same shape as `/v2/conversations/search`,
326
+ * `/v2/companies/search`, `/v2/contacts/search`.
327
+ * - **Search mode** — pass a top-level `search` string and the endpoint runs a
328
+ * hybrid full-text + vector search (BM25 + embeddings, semanticRatio 0.5) over
329
+ * post `title` and `content`, returning matches ranked by relevance. Optional:
330
+ * combine with `query` to constrain the search to a board / status / time
331
+ * window, and/or `sort` to override relevance ranking with chronological order.
332
+ *
333
+ * ```json
334
+ * {
335
+ * "search": "mobile dark mode",
336
+ * "query": {
337
+ * "operator": "AND",
338
+ * "value": [
339
+ * {
340
+ * "field": "boardId",
341
+ * "operator": "IN",
342
+ * "value": ["507f1f77bcf86cd799439011"]
343
+ * }
344
+ * ]
345
+ * },
346
+ * "limit": 20
347
+ * }
348
+ * ```
349
+ *
350
+ * `search` is server-managed: no operators, no field selection, no special syntax
351
+ * — same plain-text contract as `/v2/conversations/search`. The string must be
352
+ * 1–500 characters; up to ~1024 BM25-tokenizer characters are forwarded to
353
+ * Turbopuffer (longer queries are truncated at a word boundary).
354
+ *
355
+ * ### Structured query AST
356
+ *
357
+ * Each clause has the shape `{ field, operator, value }`. You can pass a single
358
+ * clause or wrap up to 15 in a top-level `AND` group:
359
+ *
360
+ * ```json
361
+ * {
362
+ * "query": {
363
+ * "operator": "AND",
364
+ * "value": [
365
+ * {
366
+ * "field": "boardId",
367
+ * "operator": "IN",
368
+ * "value": ["507f1f77bcf86cd799439011"]
369
+ * },
370
+ * { "field": "upvotes", "operator": ">", "value": 10 }
371
+ * ]
372
+ * },
373
+ * "sort": "upvotes:desc",
374
+ * "limit": 20
375
+ * }
376
+ * ```
377
+ *
378
+ * To list every post a contact has upvoted (the inverse of
379
+ * `feedback.posts.voters.list(postId)`):
380
+ *
381
+ * ```json
382
+ * {
383
+ * "query": {
384
+ * "field": "voterId",
385
+ * "operator": "=",
386
+ * "value": "507f1f77bcf86cd799439011"
387
+ * },
388
+ * "sort": "upvotes:desc",
389
+ * "limit": 100
390
+ * }
391
+ * ```
392
+ *
393
+ * Top-level `OR` groups and nested groups are not supported in this version.
394
+ *
395
+ * ### Supported fields and operators
396
+ *
397
+ * Field names are camelCase, matching the rest of the v2 public API. Snake_case
398
+ * names that this endpoint originally shipped with (`board_id`, `status_id`,
399
+ * `tag_id`, `author_id`, `voter_id`, `assignee_id`, `company_id`, `created_at`,
400
+ * `updated_at`, `comment_count`, `monthly_spend`, `opportunity_amount`,
401
+ * `in_review`, `is_pinned`) are still accepted for back-compat but are deprecated
402
+ * — please migrate to camelCase in new code.
403
+ *
404
+ * | Field | Type | Operators |
405
+ * | -------------------------------------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
406
+ * | `boardId` | id (categoryId) | `=`, `!=`, `IN`, `NIN` |
407
+ * | `statusId` | id (postStatus) | `=`, `!=`, `IN`, `NIN` |
408
+ * | `tagId` | id (postTags) | `=`, `!=`, `IN`, `NIN` |
409
+ * | `authorId` | string (user id) | `=`, `!=`, `IN`, `NIN` |
410
+ * | `voterId` | id (customer) | `=`, `IN` (use to list every post a contact has upvoted; only matches `type: customer` upvoters — guests/admins are not searchable here) |
411
+ * | `assigneeId` | id or null (admin) | `=`, `!=`, `IN`, `NIN` (use `null` for unassigned) |
412
+ * | `companyId` | string (external company id) | `=`, `!=`, `IN`, `NIN` |
413
+ * | `createdAt`, `updatedAt`, `eta` | unix seconds | `=`, `!=`, `>`, `<`, `>=`, `<=` |
414
+ * | `upvotes`, `commentCount`, `monthlySpend`, `opportunityAmount` | number | `=`, `!=`, `>`, `<`, `>=`, `<=` |
415
+ * | `inReview`, `isPinned` | boolean | `=`, `!=` |
416
+ *
417
+ * Use the top-level `search` field for full-text search across `title` and
418
+ * `content` (see "Search mode" above). The clause-level operators `~`, `!~`, `^`,
419
+ * `$` are reserved for future use and currently return `400`.
420
+ *
421
+ * A filter-mode query (no `search`) consisting only of `!=` or `NIN` clauses on
422
+ * unbounded fields is rejected with `query_too_broad` to prevent full-org scans.
423
+ * Combine the negation with at least one positive clause (`=`, `IN`, `>`, `<`)
424
+ * instead. Boolean fields (`inReview`, `isPinned`) are bounded so a standalone
425
+ * negation on them is allowed. Search mode (with `search` set) relaxes this — the
426
+ * FTS query itself acts as the positive constraint.
427
+ *
428
+ * ### Sort
429
+ *
430
+ * Allowed values:
431
+ *
432
+ * - `createdAt:desc` (default), `createdAt:asc`
433
+ * - `updatedAt:desc`, `updatedAt:asc`
434
+ * - `upvotes:desc`, `upvotes:asc`
435
+ * - `eta:desc`, `eta:asc`
436
+ * - `monthlySpend:desc`, `monthlySpend:asc` (sum of upvoters' monthly spend)
437
+ * - `opportunityAmount:desc`, `opportunityAmount:asc` (linked HubSpot/Salesforce
438
+ * value)
439
+ * - `commentCount:desc`, `commentCount:asc`
440
+ *
441
+ * Snake_case sort axes (`created_at:desc`, `monthly_spend:asc`, etc.) are accepted
442
+ * for back-compat — the cursor encodes the canonical camelCase identity, so a
443
+ * caller can switch naming conventions mid-pagination without restarting.
444
+ *
445
+ * When `search` is set, results are ranked by relevance unless `sort` is also set,
446
+ * in which case the matching posts are returned in the requested order. The chosen
447
+ * sort axis (or relevance) is encoded in the cursor; switching `sort` (or toggling
448
+ * `search` on/off) mid-pagination returns `400 invalid_cursor`. Restart pagination
449
+ * without a cursor when changing the sort or search shape.
450
+ *
451
+ * ### Pagination
452
+ *
453
+ * Cursor-based, `limit` between 1 and 100 (default 10). In filter mode,
454
+ * `totalCount` is approximate and capped at 5000; `totalCountCapped` is `true`
455
+ * when the real count may be higher. In search mode, `totalCount` reflects the
456
+ * matching survivor set after the AST filter and is capped at 200 (the Turbopuffer
457
+ * top-K).
458
+ *
459
+ * ### Server-side guards
460
+ *
461
+ * These exclusions are always applied and CANNOT be disabled via the AST:
462
+ *
463
+ * - Spam posts (`isSpam: true`) are excluded.
464
+ * - Merged posts (those rolled into another post) are excluded — the canonical row
465
+ * is what's returned.
466
+ * - Support-board (ticket) categories are excluded — tickets have their own
467
+ * `/v2/tickets` surface.
468
+ *
469
+ * ### Response
470
+ *
471
+ * Returns a standard list envelope with post rows identical to
472
+ * `GET /v2/posts/{id}`.
473
+ *
474
+ * ### Version Availability
475
+ *
476
+ * This endpoint is only available in API version 2026-01-01.nova and newer.
477
+ *
478
+ * @example
479
+ * ```ts
480
+ * const response = await client.feedback.posts.search();
481
+ * ```
482
+ */
483
+ search(params: PostSearchParams, options?: RequestOptions): APIPromise<PostSearchResponse> {
484
+ const { 'Featurebase-Version': featurebaseVersion, ...body } = params;
485
+ return this._client.post('/v2/posts/search', {
486
+ body,
487
+ ...options,
488
+ headers: buildHeaders([
489
+ {
490
+ ...(featurebaseVersion?.toString() != null ?
491
+ { 'Featurebase-Version': featurebaseVersion?.toString() }
492
+ : undefined),
493
+ },
494
+ options?.headers,
495
+ ]),
496
+ });
497
+ }
316
498
  }
317
499
 
318
500
  export type PostsCursorPage = CursorPage<Post>;
@@ -673,6 +855,377 @@ export interface PostDeleteResponse {
673
855
  object: 'post';
674
856
  }
675
857
 
858
+ export interface PostSearchResponse {
859
+ /**
860
+ * Array of search results
861
+ */
862
+ data: Array<PostSearchResponse.Data>;
863
+
864
+ /**
865
+ * Cursor for fetching the next page (null if no more results)
866
+ */
867
+ nextCursor: string | null;
868
+
869
+ /**
870
+ * Object type identifier
871
+ */
872
+ object: 'list';
873
+
874
+ /**
875
+ * Total number of posts matching the query, capped at 5000. When the actual total
876
+ * is at or above the cap, `totalCountCapped` is true and the value is exactly the
877
+ * cap.
878
+ */
879
+ totalCount?: number;
880
+
881
+ /**
882
+ * True when `totalCount` is exactly the cap and the real count may be higher. UI
883
+ * can render as e.g. "5000+".
884
+ */
885
+ totalCountCapped?: boolean;
886
+ }
887
+
888
+ export namespace PostSearchResponse {
889
+ export interface Data {
890
+ /**
891
+ * Unique identifier
892
+ */
893
+ id: string;
894
+
895
+ access: Data.Access;
896
+
897
+ /**
898
+ * ID of the admin assigned to this post, null if unassigned
899
+ */
900
+ assigneeId: string | null;
901
+
902
+ author: Data.Author | null;
903
+
904
+ /**
905
+ * Board (category) ID this post belongs to
906
+ */
907
+ boardId: string;
908
+
909
+ /**
910
+ * Total number of comments
911
+ */
912
+ commentCount: number;
913
+
914
+ /**
915
+ * Post content in HTML format
916
+ */
917
+ content: string;
918
+
919
+ /**
920
+ * ISO 8601 timestamp when created
921
+ */
922
+ createdAt: string;
923
+
924
+ /**
925
+ * Custom field values keyed by field ID
926
+ */
927
+ customFields: { [key: string]: unknown };
928
+
929
+ /**
930
+ * Estimated completion time as ISO 8601 timestamp, null if not set
931
+ */
932
+ eta: string | null;
933
+
934
+ features: Data.Features;
935
+
936
+ /**
937
+ * Whether the post is pending moderation review
938
+ */
939
+ inReview: boolean;
940
+
941
+ /**
942
+ * Third-party integration links associated with this post
943
+ */
944
+ integrations: Data.Integrations;
945
+
946
+ /**
947
+ * Whether the post is pinned to the top
948
+ */
949
+ isPinned: boolean;
950
+
951
+ /**
952
+ * Object type identifier
953
+ */
954
+ object: 'post';
955
+
956
+ /**
957
+ * Total opportunity amount from linked HubSpot deals and Salesforce opportunities
958
+ */
959
+ opportunityAmount: number | null;
960
+
961
+ /**
962
+ * Full URL to view the post
963
+ */
964
+ postUrl: string;
965
+
966
+ /**
967
+ * URL-friendly slug
968
+ */
969
+ slug: string;
970
+
971
+ status: PostStatusesAPI.PostStatus;
972
+
973
+ /**
974
+ * Tags attached to this post
975
+ */
976
+ tags: Array<Data.Tag>;
977
+
978
+ /**
979
+ * Post title
980
+ */
981
+ title: string;
982
+
983
+ /**
984
+ * ISO 8601 timestamp when last modified
985
+ */
986
+ updatedAt: string;
987
+
988
+ /**
989
+ * Total number of upvotes
990
+ */
991
+ upvotes: number;
992
+ }
993
+
994
+ export namespace Data {
995
+ export interface Access {
996
+ /**
997
+ * External company IDs explicitly granted access to this post. Empty array means
998
+ * no company-level restrictions. Non-empty means only users belonging to these
999
+ * companies can see the post.
1000
+ */
1001
+ companyExternalIds: Array<string>;
1002
+
1003
+ /**
1004
+ * User IDs explicitly granted access to this post. Empty array means no user-level
1005
+ * restrictions (post uses board/org visibility). Non-empty means only these users
1006
+ * (plus admins) can see the post.
1007
+ */
1008
+ userIds: Array<string>;
1009
+ }
1010
+
1011
+ export interface Author {
1012
+ /**
1013
+ * Author unique identifier
1014
+ */
1015
+ id: string | null;
1016
+
1017
+ /**
1018
+ * Author email (if available)
1019
+ */
1020
+ email: string | null;
1021
+
1022
+ /**
1023
+ * Author display name
1024
+ */
1025
+ name: string;
1026
+
1027
+ /**
1028
+ * Author profile picture URL
1029
+ */
1030
+ profilePicture: string | null;
1031
+
1032
+ /**
1033
+ * Type of user who authored the post
1034
+ */
1035
+ type: 'admin' | 'customer' | 'guest' | 'integration' | 'bot' | 'lead';
1036
+ }
1037
+
1038
+ export interface Features {
1039
+ /**
1040
+ * Whether comments are allowed on this post
1041
+ */
1042
+ commentsEnabled: boolean;
1043
+ }
1044
+
1045
+ /**
1046
+ * Third-party integration links associated with this post
1047
+ */
1048
+ export interface Integrations {
1049
+ clickup: Array<Integrations.Clickup>;
1050
+
1051
+ devops: Array<Integrations.Devop>;
1052
+
1053
+ github: Array<Integrations.GitHub>;
1054
+
1055
+ hubspot: Array<Integrations.Hubspot>;
1056
+
1057
+ jira: Array<Integrations.Jira>;
1058
+
1059
+ linear: Array<Integrations.Linear>;
1060
+
1061
+ salesforce: Array<Integrations.Salesforce>;
1062
+ }
1063
+
1064
+ export namespace Integrations {
1065
+ export interface Clickup {
1066
+ /**
1067
+ * ClickUp task ID
1068
+ */
1069
+ id: string;
1070
+
1071
+ /**
1072
+ * ClickUp task title
1073
+ */
1074
+ title: string;
1075
+
1076
+ /**
1077
+ * URL to the ClickUp task
1078
+ */
1079
+ url: string;
1080
+ }
1081
+
1082
+ export interface Devop {
1083
+ /**
1084
+ * Azure DevOps work item ID
1085
+ */
1086
+ id: number;
1087
+
1088
+ /**
1089
+ * Azure DevOps project ID
1090
+ */
1091
+ projectId: string;
1092
+
1093
+ /**
1094
+ * Azure DevOps project name
1095
+ */
1096
+ projectName: string;
1097
+
1098
+ /**
1099
+ * Work item title
1100
+ */
1101
+ title: string;
1102
+
1103
+ /**
1104
+ * URL to the work item
1105
+ */
1106
+ url: string;
1107
+ }
1108
+
1109
+ export interface GitHub {
1110
+ /**
1111
+ * GitHub issue ID
1112
+ */
1113
+ id: string;
1114
+
1115
+ /**
1116
+ * GitHub issue number
1117
+ */
1118
+ number: string;
1119
+
1120
+ /**
1121
+ * Full repository name (owner/repo)
1122
+ */
1123
+ repositoryFullName: string;
1124
+
1125
+ /**
1126
+ * Repository name
1127
+ */
1128
+ repositoryName: string;
1129
+
1130
+ /**
1131
+ * GitHub issue title
1132
+ */
1133
+ title: string;
1134
+
1135
+ /**
1136
+ * URL to the GitHub issue
1137
+ */
1138
+ url: string;
1139
+ }
1140
+
1141
+ export interface Hubspot {
1142
+ /**
1143
+ * Deal amount (for DEAL type)
1144
+ */
1145
+ dealAmount: number | null;
1146
+
1147
+ /**
1148
+ * Whether the deal is closed (for DEAL type)
1149
+ */
1150
+ dealClosed: boolean | null;
1151
+
1152
+ /**
1153
+ * HubSpot object ID
1154
+ */
1155
+ objectId: number;
1156
+
1157
+ /**
1158
+ * HubSpot object type
1159
+ */
1160
+ type: 'TICKET' | 'DEAL' | 'CONTACT';
1161
+ }
1162
+
1163
+ export interface Jira {
1164
+ /**
1165
+ * Jira issue ID
1166
+ */
1167
+ issueId: string;
1168
+
1169
+ /**
1170
+ * URL to the Jira issue
1171
+ */
1172
+ issueUrl: string | null;
1173
+ }
1174
+
1175
+ export interface Linear {
1176
+ /**
1177
+ * Linear issue ID
1178
+ */
1179
+ issueId: string;
1180
+
1181
+ /**
1182
+ * URL to the Linear issue
1183
+ */
1184
+ issueUrl: string | null;
1185
+ }
1186
+
1187
+ export interface Salesforce {
1188
+ /**
1189
+ * Opportunity amount (for Opportunity type)
1190
+ */
1191
+ amount: number | null;
1192
+
1193
+ /**
1194
+ * Whether the opportunity is closed (for Opportunity type)
1195
+ */
1196
+ isClosed: boolean | null;
1197
+
1198
+ /**
1199
+ * Salesforce record ID
1200
+ */
1201
+ objectId: string;
1202
+
1203
+ /**
1204
+ * Salesforce object type
1205
+ */
1206
+ objectType: 'Opportunity' | 'Case';
1207
+ }
1208
+ }
1209
+
1210
+ export interface Tag {
1211
+ /**
1212
+ * Tag unique identifier
1213
+ */
1214
+ id: string;
1215
+
1216
+ /**
1217
+ * Tag color hex code
1218
+ */
1219
+ color: string | null;
1220
+
1221
+ /**
1222
+ * Tag name
1223
+ */
1224
+ name: string;
1225
+ }
1226
+ }
1227
+ }
1228
+
676
1229
  export interface PostCreateParams {
677
1230
  /**
678
1231
  * Body param: Board ID to create post in
@@ -960,18 +1513,136 @@ export interface PostDeleteParams {
960
1513
  'Featurebase-Version'?: '2026-01-01.nova' | '2025-12-12.clover';
961
1514
  }
962
1515
 
1516
+ export interface PostSearchParams {
1517
+ /**
1518
+ * Body param: An opaque cursor for pagination. Use the `nextCursor` value from a
1519
+ * previous response to fetch the next page of results.
1520
+ */
1521
+ cursor?: string;
1522
+
1523
+ /**
1524
+ * Body param: A limit on the number of objects to be returned, between 1 and 100.
1525
+ */
1526
+ limit?: number;
1527
+
1528
+ /**
1529
+ * Body param: Structured filter AST. Either a single filter clause or one
1530
+ * top-level AND group (max 15 clauses). Top-level OR groups are not yet supported.
1531
+ */
1532
+ query?: PostSearchParams.SearchFilter | PostSearchParams.SearchFilterGroup;
1533
+
1534
+ /**
1535
+ * Body param: Plain-text full-text search across post `title` and `content`.
1536
+ * Server-managed (hybrid BM25 + vector) — no operators, no field selection. When
1537
+ * `search` is set, results are ranked by relevance unless `sort` is also set, in
1538
+ * which case the matching posts are returned in the requested order. Combine with
1539
+ * `query` to constrain the search to a board / status / time window.
1540
+ */
1541
+ search?: string;
1542
+
1543
+ /**
1544
+ * Body param: Sort field + direction. Defaults to `createdAt:desc`. The chosen
1545
+ * sort axis is encoded in the cursor; switching `sort` mid-pagination returns
1546
+ * `400 invalid_cursor`. Snake_case names (`created_at:desc`, `monthly_spend:asc`,
1547
+ * …) are accepted for back-compat — prefer camelCase in new code.
1548
+ */
1549
+ sort?:
1550
+ | 'createdAt:desc'
1551
+ | 'createdAt:asc'
1552
+ | 'updatedAt:desc'
1553
+ | 'updatedAt:asc'
1554
+ | 'upvotes:desc'
1555
+ | 'upvotes:asc'
1556
+ | 'eta:desc'
1557
+ | 'eta:asc'
1558
+ | 'monthlySpend:desc'
1559
+ | 'monthlySpend:asc'
1560
+ | 'opportunityAmount:desc'
1561
+ | 'opportunityAmount:asc'
1562
+ | 'commentCount:desc'
1563
+ | 'commentCount:asc'
1564
+ | 'created_at:desc'
1565
+ | 'created_at:asc'
1566
+ | 'updated_at:desc'
1567
+ | 'updated_at:asc'
1568
+ | 'monthly_spend:desc'
1569
+ | 'monthly_spend:asc'
1570
+ | 'opportunity_amount:desc'
1571
+ | 'opportunity_amount:asc'
1572
+ | 'comment_count:desc'
1573
+ | 'comment_count:asc';
1574
+
1575
+ /**
1576
+ * Header param: API version for this request. Defaults to your organization's
1577
+ * configured API version if not specified.
1578
+ */
1579
+ 'Featurebase-Version'?: '2026-01-01.nova' | '2025-12-12.clover';
1580
+ }
1581
+
1582
+ export namespace PostSearchParams {
1583
+ export interface SearchFilter {
1584
+ /**
1585
+ * Field name to filter on (e.g. `state`, `tag_ids`, `created_at`)
1586
+ */
1587
+ field: string;
1588
+
1589
+ /**
1590
+ * Comparison operator
1591
+ */
1592
+ operator: '=' | '!=' | 'IN' | 'NIN' | '>' | '<' | '>=' | '<=' | '~' | '!~' | '^' | '$';
1593
+
1594
+ /**
1595
+ * Value to compare against (primitive or array of primitives)
1596
+ */
1597
+ value: string | number | boolean | Array<string | number> | null;
1598
+ }
1599
+
1600
+ export interface SearchFilterGroup {
1601
+ /**
1602
+ * Group operator: AND (all match) or OR (any match)
1603
+ */
1604
+ operator: 'AND' | 'OR';
1605
+
1606
+ /**
1607
+ * Array of filter clauses (1-15 entries)
1608
+ */
1609
+ value: Array<SearchFilterGroup.Value>;
1610
+ }
1611
+
1612
+ export namespace SearchFilterGroup {
1613
+ export interface Value {
1614
+ /**
1615
+ * Field name to filter on (e.g. `state`, `tag_ids`, `created_at`)
1616
+ */
1617
+ field: string;
1618
+
1619
+ /**
1620
+ * Comparison operator
1621
+ */
1622
+ operator: '=' | '!=' | 'IN' | 'NIN' | '>' | '<' | '>=' | '<=' | '~' | '!~' | '^' | '$';
1623
+
1624
+ /**
1625
+ * Value to compare against (primitive or array of primitives)
1626
+ */
1627
+ value: string | number | boolean | Array<string | number> | null;
1628
+ }
1629
+ }
1630
+ }
1631
+
963
1632
  Posts.Voters = Voters;
964
1633
 
965
1634
  export declare namespace Posts {
966
1635
  export {
967
1636
  type Post as Post,
968
1637
  type PostDeleteResponse as PostDeleteResponse,
1638
+ type PostSearchResponse as PostSearchResponse,
969
1639
  type PostsCursorPage as PostsCursorPage,
970
1640
  type PostCreateParams as PostCreateParams,
971
1641
  type PostRetrieveParams as PostRetrieveParams,
972
1642
  type PostUpdateParams as PostUpdateParams,
973
1643
  type PostListParams as PostListParams,
974
1644
  type PostDeleteParams as PostDeleteParams,
1645
+ type PostSearchParams as PostSearchParams,
975
1646
  };
976
1647
 
977
1648
  export {