@signa-so/sdk 0.16.0 → 0.21.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.
package/dist/types.d.ts CHANGED
@@ -199,8 +199,10 @@ export type DeadlineListRow = components['schemas']['DeadlineListRow'];
199
199
  * A maintenance rule that applies to a mark but was declined because the
200
200
  * record lacks the date the statute anchors it on, so no deadline row exists
201
201
  * for it. Carried as `unsupported_rules` on `POST /v1/deadlines/compute`
202
- * items and `unsupported_marks[]` entries, and as
203
- * `derived.deadlines.unsupported_rules` on a trademark row.
202
+ * items and `unsupported_marks[]` entries, as
203
+ * `derived.deadlines.unsupported_rules` on a trademark row, and as
204
+ * `computed.unsupported_rules` on a `POST /v1/reconcile` result requested
205
+ * with `verdict_detail: true`.
204
206
  */
205
207
  export type UnsupportedDeadlineRule = components['schemas']['UnsupportedDeadlineRule'];
206
208
  /**
@@ -455,51 +457,60 @@ export type WatchStatus = 'active' | 'paused' | 'disabled';
455
457
  * (= `ALERT_EVENT_TYPES` from `@signa/types`) and `DEFAULT_TRIGGER_EVENTS`.
456
458
  */
457
459
  export type WatchTriggerEvent = 'trademark.created' | 'trademark.updated' | 'trademark.status_changed' | 'trademark.retracted' | 'trademark.corrected';
458
- /** Search strategy names accepted by watch similarity queries. */
459
- export type WatchSearchStrategy = 'exact' | 'phonetic' | 'fuzzy' | 'prefix';
460
- /** Attribution tier gate for watch similarity queries. */
460
+ /**
461
+ * Legacy attribution tier gate, echoed by diagnostics for a watch stored in
462
+ * the v1/v2 form. New watches use `min_tier` ({@link MatchTier}).
463
+ */
461
464
  export type WatchMinMatchTier = 'exact' | 'normalized' | 'fuzzy' | 'phonetic';
462
465
  /**
463
- * Watch query DSL. Five watch types share one shape — the
464
- * `watch_type` selects which scoping field is required, but the body
465
- * shape is identical to a trademark search body. See the
466
+ * Watch query DSL. Five watch types share one shape; the `watch_type`
467
+ * selects which scoping field is required. See the
466
468
  * [Watches guide](https://docs.signa.so/guides/monitoring/watches) for
467
469
  * the per-type required-field table.
468
470
  *
469
- * `q` is a whitespace-separated keyword list (max 20, each ≥3 chars, no
470
- * stop words). `filters` accepts the same vocabulary as the trademark
471
- * search API (`trademarkIds`, `ownerId`, `niceClasses`, `jurisdictions`,
472
- * `offices`, etc.). `strategies` uses the same selector as public trademark
473
- * search. `trigger_events` narrows which lifecycle events fire alerts.
474
- * `min_match_tier` gates similarity matches by retrieval attribution tier.
475
- * `score_threshold` is NOT currently supported — sending it on a write is
476
- * rejected with 400; scores are informational (see `match_score` on alerts).
471
+ * Send `version: 'v3'`, `q`, optional `similarity` (the search channels,
472
+ * same default as search) and optional `min_tier` (the weakest
473
+ * {@link MatchTier} that alerts; default `related`, everything through).
474
+ * The API stores every written query as `v3` whatever `version` it sends, so
475
+ * a plain `{ version: 'v2', q }` gets the default channels and `min_tier:
476
+ * 'related'` too. `filters` keeps its camelCase vocabulary (`trademarkIds`,
477
+ * `ownerId`, `niceClasses`, `jurisdictions`, `offices`, ...).
478
+ * `trigger_events` narrows which lifecycle events fire alerts. Watches do
479
+ * not accept the search `mark_text_*` filters or exclusions (400).
480
+ *
481
+ * The old `strategies` and `min_match_tier` keys are removed from this type
482
+ * (0.17.0). The API still accepts them until 2026-12-28: a watch written
483
+ * with them is kept as a legacy watch, with its original matching, until it
484
+ * is re-saved without them, and the write response lists them in
485
+ * `deprecations`. Stored watches are never rewritten: a watch saved in the
486
+ * v1/v2 form keeps its matching until its query changes.
477
487
  *
478
- * Forbidden DSL keys (`function_score`, `script`, `sort`, `cursor`,
479
- * `aggregations`, `highlight`) are rejected with 400. `query.match` is
480
- * rejected in ANY form (object or string) — earlier doc revisions described
481
- * shapes that were never honored by the evaluator. Use `filters.ownerId`,
482
- * `filters.trademarkIds`, `filters.niceClasses` for scoping and
483
- * `min_match_tier` for similarity precision. Unknown `filters` keys are
484
- * rejected with 400 listing the allowed vocabulary; `filters.offices`
485
- * accepts any casing and is stored lowercase.
488
+ * `score_threshold` is NOT supported on write (400); scores are
489
+ * informational (see `match.score` on alerts). Forbidden DSL keys
490
+ * (`function_score`, `script`, `sort`, `cursor`, `aggregations`,
491
+ * `highlight`) and `query.match` in any form are rejected with 400. Unknown
492
+ * `filters` keys are rejected with 400 listing the allowed vocabulary.
486
493
  */
487
494
  export interface WatchQuery {
488
- /** `"v2"` for tier-based watch matching. `"v1"` is accepted during migration. */
489
- version: 'v1' | 'v2';
490
- /** Optional keyword query (required for similarity watches). Whitespace-separated; each ≥3 chars; no stop words. */
495
+ /**
496
+ * Required on write. `'v1'`, `'v2'` and `'v3'` are accepted; send `'v3'`. A new or changed query is
497
+ * stored as `'v3'` whatever version it sends, unless it uses the deprecated keys; `'v1'` / `'v2'`
498
+ * otherwise appear only on stored legacy queries.
499
+ */
500
+ version: 'v1' | 'v2' | 'v3';
501
+ /** Search text (required for similarity watches). */
491
502
  q?: string;
492
- /** Search strategies to use. Omit for the public-search default (`exact` + `fuzzy`). */
493
- strategies?: WatchSearchStrategy[];
503
+ /** Similarity channels for `q`. Omit for the search default (`identical`, `fuzzy`, `embedded`, `lookalike`). */
504
+ similarity?: readonly SimilarityChannel[];
505
+ /** The weakest similarity tier that alerts. Default `related` (every tier). */
506
+ min_tier?: MatchTier;
494
507
  /** Filter object — same vocabulary as the trademark search API. Common keys: `trademarkIds`, `ownerId`, `niceClasses`, `jurisdictions`, `offices`, `statusPrimary`. */
495
508
  filters?: Record<string, unknown>;
496
509
  /** Restrict alert generation to specific trigger event types. */
497
510
  trigger_events?: WatchTriggerEvent[];
498
- /** Minimum attribution tier for similarity watches. `phonetic` is the broad "any tier" setting. */
499
- min_match_tier?: WatchMinMatchTier;
500
511
  /**
501
512
  * NOT currently supported — sending this on create/update/bulk/preview is
502
- * rejected with 400. Scores are informational (see `match_score` on alerts).
513
+ * rejected with 400. Scores are informational (see `match.score` on alerts).
503
514
  * The field is retained on the type so existing stored watch queries still
504
515
  * deserialize on GET. Contact support for calibrated-band thresholds.
505
516
  */
@@ -522,6 +533,16 @@ export interface Watch {
522
533
  metadata: Record<string, unknown>;
523
534
  created_at: string;
524
535
  updated_at: string;
536
+ /** Health state; populated on list and retrieve, `null` on create/update responses. */
537
+ health_status: components['schemas']['Watch']['health_status'];
538
+ /** Health with per-office coverage and issues; populated only on retrieve, `null` elsewhere. */
539
+ health: components['schemas']['Watch']['health'];
540
+ /**
541
+ * Present on create, update and bulk responses when the written query used
542
+ * a deprecated key (`strategies`, `min_match_tier`); the watch is kept as a
543
+ * legacy watch until re-saved without them.
544
+ */
545
+ deprecations?: SearchDeprecation[];
525
546
  }
526
547
  /**
527
548
  * Alert event types — what the API actually emits for `Alert.event_type`.
@@ -598,6 +619,12 @@ export interface AlertMatch {
598
619
  score: number | null;
599
620
  /** What the score is derived from, e.g. `opensearch_relevance`; null when none. */
600
621
  score_basis: string | null;
622
+ /**
623
+ * Similarity tier of the matched mark, the same label a search hit carries
624
+ * as `match.tier`. `null` for filter-only watches, marks found only by their
625
+ * number, and alerts emitted before 0.17.0.
626
+ */
627
+ tier: MatchTier | null;
601
628
  }
602
629
  /**
603
630
  * Compact mark summary embedded on the alert (Alerts v2 `trademark` block).
@@ -728,19 +755,21 @@ export interface Alert {
728
755
  /**
729
756
  * Webhook event types delivered by the dispatcher.
730
757
  *
731
- * The first three are the STATIC subscribable set for `enabled_events` — the
758
+ * The first four are the STATIC subscribable set for `enabled_events`: the
732
759
  * API accepts them at all times, independently of our rollout state. Source of
733
760
  * truth: `WEBHOOK_SUBSCRIBABLE_EVENT_TYPES` in `@signa/types`, pinned by
734
761
  * `packages/types/src/api-events.test.ts` (a source-text pin, because the
735
762
  * published SDK must not depend on `@signa/types` at runtime).
736
763
  *
737
- * `trademark.status_changed` and `office_action.issued` are delivered only for
738
- * marks in one of the organization's portfolios.
764
+ * `trademark.status_changed`, `trademark.corrected` and `office_action.issued`
765
+ * are delivered only for marks in one of the organization's portfolios. An
766
+ * endpoint subscribed to `trademark.status_changed` also receives
767
+ * `trademark.corrected` ({@link TrademarkCorrectedEvent}).
739
768
  *
740
769
  * `webhook.test` is the shape delivered by `webhooks.test()` only; it is not a
741
770
  * subscribable type and `enabled_events` rejects it.
742
771
  */
743
- export type WebhookEventType = 'alert.created' | 'trademark.status_changed' | 'office_action.issued' | 'webhook.test';
772
+ export type WebhookEventType = 'alert.created' | 'trademark.status_changed' | 'trademark.corrected' | 'office_action.issued' | 'webhook.test';
744
773
  /**
745
774
  * What arrives at a customer webhook endpoint, in the body of the POST
746
775
  * (Round 4 R4.5 — TSK-111 monitoring v1).
@@ -934,6 +963,31 @@ export type TrademarkStatusChangedEvent = Omit<WebhookEvent<TrademarkStatusChang
934
963
  type: 'trademark.status_changed';
935
964
  payload_version: number;
936
965
  };
966
+ /**
967
+ * Why a `trademark.corrected` status change is a correction of a status Signa
968
+ * published earlier.
969
+ *
970
+ * - `status`: Signa published a wrong status and this event reverses it (for
971
+ * example a mark shown as expired that the office records as renewed).
972
+ * - `late_office_record`: office records reached Signa late and show the mark
973
+ * lapsing, or a dead mark returning.
974
+ */
975
+ export interface TrademarkCorrection {
976
+ kind: 'status' | 'late_office_record';
977
+ }
978
+ /**
979
+ * `trademark.corrected` data: the {@link TrademarkStatusChangedData} body (same
980
+ * keys, same `payload_version` rules) plus `correction`. Delivered for marks in
981
+ * one of the organization's portfolios, to every endpoint subscribed to
982
+ * `trademark.status_changed` or `trademark.corrected`.
983
+ */
984
+ export interface TrademarkCorrectedData extends TrademarkStatusChangedData {
985
+ correction: TrademarkCorrection;
986
+ }
987
+ export type TrademarkCorrectedEvent = Omit<WebhookEvent<TrademarkCorrectedData>, 'type' | 'payload_version'> & {
988
+ type: 'trademark.corrected';
989
+ payload_version: number;
990
+ };
937
991
  /**
938
992
  * `office_action.issued` data at `payload_version` 1: the prosecution row's
939
993
  * fields flattened beside the identity fields.
@@ -1133,6 +1187,12 @@ export interface WatchPreviewResponse {
1133
1187
  has_more?: boolean;
1134
1188
  /** Echo of the effective page size for `results`. Omitted when count_only. */
1135
1189
  result_limit?: number;
1190
+ /** The similarity channels the query runs. `null` without `q` and for a query with the deprecated keys. */
1191
+ similarity_applied: SimilarityChannel[] | null;
1192
+ /** The weakest tier that alerts. `null` for a query with the deprecated keys. */
1193
+ min_tier: MatchTier | null;
1194
+ /** Deprecated query keys the previewed query used (see {@link Watch.deprecations}). */
1195
+ deprecations?: SearchDeprecation[];
1136
1196
  request_id: string;
1137
1197
  }
1138
1198
  /**
@@ -1180,7 +1240,12 @@ export interface WatchDiagnostics {
1180
1240
  * INERT — no longer gates matching, and rejected on new writes.
1181
1241
  */
1182
1242
  score_threshold: number | null;
1243
+ /** Legacy tier gate of a watch stored in the v1/v2 form; `null` otherwise. */
1183
1244
  min_match_tier: WatchMinMatchTier | null;
1245
+ /** The similarity channels the watch query runs. `null` without `q`, and for a legacy watch (stored with the deprecated keys, or before v3 and not re-saved since). */
1246
+ similarity_applied: SimilarityChannel[] | null;
1247
+ /** The weakest tier that alerts. `null` for a legacy watch (stored with the deprecated keys, or before v3 and not re-saved since), which reports `min_match_tier`. */
1248
+ min_tier: MatchTier | null;
1184
1249
  alert_fired: boolean;
1185
1250
  /**
1186
1251
  * Walked in order: alert fired → office not in scope → freshness limit →
@@ -1233,6 +1298,13 @@ export interface WatchDiagnostics {
1233
1298
  close_adjustment: HolidayAdjustment | null;
1234
1299
  window_status: WatchDiagnosticsWindowStatus | null;
1235
1300
  } | null;
1301
+ /** Consecutive evaluation failures on this watch/office checkpoint (0 = healthy); null without a checkpoint. */
1302
+ evaluation_consecutive_failures: number | null;
1303
+ /**
1304
+ * Sanitized class of the last evaluation error for this office (e.g.
1305
+ * `entity_unresolved`, `budget_declined`); never a raw error string.
1306
+ */
1307
+ last_evaluation_error: string | null;
1236
1308
  data_window: {
1237
1309
  trademark_changes_retention_days: number;
1238
1310
  outbox_retention_days: number;
@@ -1438,6 +1510,8 @@ export interface TrademarkOrgEventDetail extends OrgEvent {
1438
1510
  source_date?: string | null;
1439
1511
  /** Frozen membership snapshot. See {@link EventPortfolioRef}. */
1440
1512
  portfolios?: EventPortfolioRef[];
1513
+ /** `trademark.corrected` only: why this status change is a correction. See {@link TrademarkCorrection}. */
1514
+ correction?: TrademarkCorrection;
1441
1515
  request_id: string;
1442
1516
  }
1443
1517
  /** Alert-family event detail. Family-specific trademark fields are absent. */
@@ -1544,21 +1618,14 @@ export interface TrademarkDocument {
1544
1618
  }
1545
1619
  /** Owner related entity (GLEIF corporate hierarchy). */
1546
1620
  export type OwnerRelated = components['schemas']['OwnerRelated'];
1547
- /**
1548
- * ENG-106 — how the query text is matched against the mark text.
1549
- * `similar` (default) runs the ranked strategies ladder (relevance scoring).
1550
- * `exact` | `starts_with` | `ends_with` | `contains` are deterministic
1551
- * (date-led sort, `relevance_score` null on every row). Deterministic modes
1552
- * require a query and disallow `strategies`; `contains` additionally needs a
1553
- * folded query of at least 3 characters.
1554
- */
1555
- export type MatchMode = 'similar' | 'exact' | 'starts_with' | 'ends_with' | 'contains';
1556
1621
  /**
1557
1622
  * Search metadata on trademark search and list responses.
1558
1623
  *
1559
- * 0.14.0: `fallback_reason` is gone; every caveat is a coded entry in
1560
- * `warnings[]` (e.g. `expanded_fallback` with `affected_filters`, or
1561
- * `partial_results`). `index_generation` names the index that served the page;
1624
+ * 0.17.0: `similarity_applied` (the channels `q` ran on), `ranking_version`
1625
+ * (cursors are bound to it), `order` (the order applied), `complete` /
1626
+ * `incomplete_reason` (false only with `allow_partial`), `identifier` (when
1627
+ * `q` was read as a trademark number) and `deprecations` (old parameters the
1628
+ * request used). `index_generation` names the index that served the page;
1562
1629
  * cursors are bound to it, so a cursor from before an index rebuild returns
1563
1630
  * `400 cursor_invalid` and pagination restarts.
1564
1631
  *
@@ -1566,11 +1633,45 @@ export type MatchMode = 'similar' | 'exact' | 'starts_with' | 'ends_with' | 'con
1566
1633
  * (`SignaList.total_count`) when the request sets `include_total`.
1567
1634
  */
1568
1635
  export type SearchMeta = NonNullable<components['schemas']['SearchResponseV2']['search_meta']>;
1636
+ /**
1637
+ * A similarity channel for a ranked `q`. The default set is `identical`,
1638
+ * `fuzzy`, `embedded` and `lookalike`; `identical` is always on. See
1639
+ * {@link Presets} for the knockout and clearance sets.
1640
+ */
1641
+ export type SimilarityChannel = SearchMeta['similarity_applied'][number];
1642
+ /**
1643
+ * `match` on a search hit: `tier` (strongest similarity tier matched; `null`
1644
+ * without `q` or for a hit found only by its number), `via` (channels that
1645
+ * matched, plus `identifier`), `terms` (the `mark_text_*` values the hit
1646
+ * satisfied) and, with `include: ['match_details']`, `details`.
1647
+ */
1648
+ export type TrademarkMatch = components['schemas']['TrademarkMatch'];
1649
+ /**
1650
+ * Similarity tier, strongest first: `identical`, `near_identical`, `similar`,
1651
+ * `related`. A retrieval category, not a measured edit distance. Used by
1652
+ * search hits (`match.tier`), watch `min_tier` and alerts (`match.tier`).
1653
+ */
1654
+ export type MatchTier = NonNullable<TrademarkMatch['tier']>;
1655
+ /**
1656
+ * Mark text operators (POST `filters.mark_text` and `exclude.mark_text`).
1657
+ * Values within one operator are OR; operators are AND. Up to 100 values of
1658
+ * 200 characters each.
1659
+ */
1660
+ export type MarkTextFilters = components['schemas']['MarkTextFilters'];
1661
+ /** One mark text operator: `is`, `word`, `starts_with`, `ends_with`, `contains`, `pattern`. */
1662
+ export type MarkTextOperator = keyof MarkTextFilters;
1663
+ /** POST `exclude`: rows matching any value are removed. Never affects ranking. */
1664
+ export type SearchExclude = components['schemas']['SearchExclude'];
1665
+ /**
1666
+ * A `search_meta.deprecations[]` (and watch `deprecations[]`) entry: an old
1667
+ * parameter the request used, its replacement, and the date (`sunset`) from
1668
+ * which the old parameter is a `400`.
1669
+ */
1670
+ export type SearchDeprecation = NonNullable<SearchMeta['deprecations']>[number];
1569
1671
  /**
1570
1672
  * A `search_meta.warnings[]` element: a stable `code` plus a human `message`,
1571
- * and the code's own detail fields (`strategy`, `affected_filter(s)`,
1572
- * `affected_offices`, `dropped_strategies`, ...). Keep a default branch: new
1573
- * codes can appear.
1673
+ * and the code's own detail fields (`channel`, `affected_filter(s)`,
1674
+ * `affected_offices`, ...). Keep a default branch: new codes can appear.
1574
1675
  */
1575
1676
  export type SearchWarning = NonNullable<SearchMeta['warnings']>[number];
1576
1677
  /** API error body (RFC 9457-inspired). */
@@ -1674,7 +1775,84 @@ export interface ResourceQuotaExceededErrorBody extends APIErrorBody {
1674
1775
  */
1675
1776
  suggestion?: string;
1676
1777
  }
1677
- export type TrademarkSearchInclude = 'full_goods_services';
1778
+ /**
1779
+ * Optional search row projections. `full_goods_services` disables summary G&S
1780
+ * truncation; `match_details` adds `match.details` (matched lanes and applied
1781
+ * ranking factors) to each hit.
1782
+ */
1783
+ export type TrademarkSearchInclude = 'full_goods_services' | 'match_details';
1784
+ /**
1785
+ * One value or a list for a repeated-key GET param (`mark_text_*`, `*_not`).
1786
+ * A scalar is a one-element list; commas inside a value are never split.
1787
+ */
1788
+ export type SearchTextList = string | readonly string[];
1789
+ /**
1790
+ * The search request surface shared by `trademarks.list()` and the owner,
1791
+ * attorney, firm and entity `trademarks()` sub-resources (search v2, 0.17.0).
1792
+ *
1793
+ * `q` ranks; the `mark_text_*` filters decide which marks qualify; the
1794
+ * `mark_text_not_*` and `*_not` exclusions remove marks and never affect
1795
+ * ranking. Values within one key are OR; different keys (and `q`) are AND.
1796
+ * The `mark_text_*` and `*_not` lists go on the wire as repeated keys
1797
+ * (`mark_text_is=a&mark_text_is=b`), so a comma inside a mark is safe.
1798
+ *
1799
+ * ```typescript
1800
+ * import { Presets } from '@signa-so/sdk';
1801
+ * await signa.trademarks.list({ q: 'limber', ...Presets.clearance, mark_text_not_is: ['LIMBER'] });
1802
+ * ```
1803
+ */
1804
+ export interface SearchTextParams {
1805
+ /**
1806
+ * Search text, ranked through the `similarity` channels (1-500 characters,
1807
+ * at least 2 after folding; 1 on the party sub-resources). Always literal.
1808
+ * A trademark number in `q` (`1939139`, `US 5123456`, `tm_...`) is also
1809
+ * looked up, and its records lead the page (`search_meta.identifier`).
1810
+ */
1811
+ q?: string;
1812
+ /**
1813
+ * Similarity channels for `q`: `identical`, `fuzzy`, `embedded`,
1814
+ * `phonetic`, `lookalike`. Default `identical`, `fuzzy`, `embedded`,
1815
+ * `lookalike`; `identical` is always on. Requires `q`. See {@link Presets}.
1816
+ */
1817
+ similarity?: readonly SimilarityChannel[];
1818
+ /** Whole-mark equality (case, accents, punctuation, spacing and trademark notices ignored), letters as written. Replaces `match: 'exact'`. */
1819
+ mark_text_is?: SearchTextList;
1820
+ /** The value appears as a whole word, or consecutive words, of the mark. */
1821
+ mark_text_word?: SearchTextList;
1822
+ /** The folded mark begins with the value. Replaces `match: 'starts_with'`. */
1823
+ mark_text_starts_with?: SearchTextList;
1824
+ /** The folded mark ends with the value (at least 3 characters). Replaces `match: 'ends_with'`. */
1825
+ mark_text_ends_with?: SearchTextList;
1826
+ /** The value appears anywhere in the folded mark (at least 3 characters). Replaces `match: 'contains'`. */
1827
+ mark_text_contains?: SearchTextList;
1828
+ /** `*` any run, `?` one character, `\` escapes the next character; everything else literal. */
1829
+ mark_text_pattern?: SearchTextList;
1830
+ /** Exclude marks equal to any value (same folding as `mark_text_is`). */
1831
+ mark_text_not_is?: SearchTextList;
1832
+ /** Exclude marks containing any value as a whole word. */
1833
+ mark_text_not_word?: SearchTextList;
1834
+ /** Exclude marks beginning with any value. */
1835
+ mark_text_not_starts_with?: SearchTextList;
1836
+ /** Exclude marks ending with any value. */
1837
+ mark_text_not_ends_with?: SearchTextList;
1838
+ /** Exclude marks containing any value (punctuation and spacing folded, like the other operators). A list since 0.17.0. */
1839
+ mark_text_not_contains?: SearchTextList;
1840
+ /** Exclude marks matching any pattern. */
1841
+ mark_text_not_pattern?: SearchTextList;
1842
+ /** Exclude marks whose owners are linked to these entities (`ent_*`). */
1843
+ entity_id_not?: SearchTextList;
1844
+ /** Exclude marks linked to any entity in these entities' corporate families (`ent_*`). */
1845
+ entity_group_not?: SearchTextList;
1846
+ /** Exclude marks held by these owners (`own_*`). */
1847
+ owner_id_not?: SearchTextList;
1848
+ /** Exclude these trademarks (`tm_*`); on the grouped view, the family row containing them. */
1849
+ trademark_ids_not?: SearchTextList;
1850
+ /**
1851
+ * Return `200` with `search_meta.complete: false` when the search hits its
1852
+ * time limit or loses a shard, instead of a retryable `503`. Default false.
1853
+ */
1854
+ allow_partial?: boolean;
1855
+ }
1678
1856
  export type TrademarkDetailInclude = 'office_extensions';
1679
1857
  /**
1680
1858
  * How a `jurisdictions` filter matches. `protection` (default) selects rights
@@ -1720,7 +1898,17 @@ export type TrademarkAggregationName = 'status_stage' | 'office_code' | 'jurisdi
1720
1898
  | 'entity_count';
1721
1899
  /** How aggregation counts relate to filters (`aggregation_mode`). */
1722
1900
  export type TrademarkAggregationMode = 'filtered' | 'exclude_own_filter';
1723
- export interface TrademarkListParams {
1901
+ export interface TrademarkListParams extends Omit<SearchTextParams, 'q'> {
1902
+ /**
1903
+ * Search text (see {@link SearchTextParams.q}), or a list of 1-100 terms
1904
+ * (e.g. spelling variants) ranked together through the same `similarity`
1905
+ * channels: a hit ranks by its best term and `match.terms` names the terms
1906
+ * that reached it. A list over 10 terms needs `similarity` limited to
1907
+ * `identical` and `lookalike`; with `fuzzy`, `embedded` or `phonetic` a list
1908
+ * takes 10 terms and 30 words in total. A list is never read as a trademark
1909
+ * number.
1910
+ */
1911
+ q?: string | readonly string[];
1724
1912
  /**
1725
1913
  * Coarse status bucket. Accepts a single value or an array to match any of
1726
1914
  * several values — passing `['active', 'pending']` yields TESS-style "live"
@@ -1836,41 +2024,19 @@ export interface TrademarkListParams {
1836
2024
  is_retracted?: boolean;
1837
2025
  is_series_mark?: boolean;
1838
2026
  international_registrations?: 'grouped' | 'expanded';
1839
- /**
1840
- * Optional text query (triggers relevance ranking when no explicit sort),
1841
- * or a list of exact terms: every mark that is an exact match under
1842
- * `match: 'exact'` rules (case, accents, punctuation and spacing) for ANY
1843
- * of the terms, each hit carrying `matched_terms[]`. A list takes 1-100
1844
- * terms, runs `match: 'exact'` (the default for a list) and costs the same
1845
- * as one search page. `list()` sends it as a JSON array
1846
- * (`q=["limber","bimber"]`), and by POST when the query string would pass
1847
- * the API's 2 KB GET limit.
1848
- */
1849
- q?: string | string[];
1850
2027
  /** ENG-67 — faceted bucket counts (TMview "Statistics view"). Field names to aggregate. */
1851
2028
  aggregations?: TrademarkAggregationName[];
1852
2029
  /** `filtered` (default): aggregations respect every filter. `exclude_own_filter`: each aggregation ignores its own filter (drill-down sidebars). */
1853
2030
  aggregation_mode?: TrademarkAggregationMode;
1854
2031
  /** ENG-67 — when true, return only aggregation counts (no result documents). */
1855
2032
  aggregations_only?: boolean;
1856
- /** Search strategies to apply (e.g. 'exact', 'phonetic', 'fuzzy', 'prefix'). */
1857
- strategies?: string[];
1858
- /**
1859
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
1860
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
1861
- * modes. Deterministic modes require `q` and disallow `strategies`;
1862
- * `'contains'` needs a folded query ≥ 3 chars.
1863
- */
1864
- match?: MatchMode;
1865
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
1866
- mark_text_not_contains?: string;
1867
2033
  /** When true, include total_count in pagination (adds latency). */
1868
2034
  include_total?: boolean;
1869
2035
  /** When true, include match highlight spans. */
1870
2036
  highlights?: boolean;
1871
2037
  /** When true, include execution timing in search_meta. */
1872
2038
  include_timing?: boolean;
1873
- /** Optional row projections. `full_goods_services` disables summary G&S truncation. */
2039
+ /** Optional row projections: `full_goods_services`, `match_details`. */
1874
2040
  include?: TrademarkSearchInclude[];
1875
2041
  /** Sparse top-level field projection. `id` and `object` are always retained. */
1876
2042
  fields?: string[];
@@ -1881,8 +2047,10 @@ export interface TrademarkListParams {
1881
2047
  /**
1882
2048
  * Sort spec. Prefix with `-` for descending. Comma-separated for multi-field.
1883
2049
  * E.g. `-filing_date`, `registration_date`, `-filing_date,office_code`.
1884
- * When `q` is present and no sort is given, results are ranked by relevance.
1885
- * When no `q` and no sort, defaults to `-filing_date`.
2050
+ * Default: relevance with `q`; mark text order (exact fits first, then
2051
+ * prefix fits, then shorter marks) with a `mark_text_*` filter and no `q`;
2052
+ * otherwise `-filing_date`. With `q`, `relevance_score` and `match` stay on
2053
+ * every hit under any sort. `search_meta.order` reports the order applied.
1886
2054
  */
1887
2055
  sort?: string;
1888
2056
  limit?: number;
@@ -1995,7 +2163,7 @@ export interface OwnerListParams {
1995
2163
  limit?: number;
1996
2164
  cursor?: string;
1997
2165
  }
1998
- export interface OwnerTrademarksParams {
2166
+ export interface OwnerTrademarksParams extends SearchTextParams {
1999
2167
  /**
2000
2168
  * Coarse status bucket. Accepts a single value or an array to match any of
2001
2169
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2100,16 +2268,6 @@ export interface OwnerTrademarksParams {
2100
2268
  include_total?: boolean;
2101
2269
  include?: TrademarkSearchInclude[];
2102
2270
  fields?: string[];
2103
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2104
- q?: string;
2105
- /**
2106
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2107
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2108
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2109
- */
2110
- match?: MatchMode;
2111
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2112
- mark_text_not_contains?: string;
2113
2271
  limit?: number;
2114
2272
  cursor?: string;
2115
2273
  }
@@ -2131,7 +2289,7 @@ export interface AttorneyListParams {
2131
2289
  limit?: number;
2132
2290
  cursor?: string;
2133
2291
  }
2134
- export interface AttorneyTrademarksParams {
2292
+ export interface AttorneyTrademarksParams extends SearchTextParams {
2135
2293
  /**
2136
2294
  * Coarse status bucket. Accepts a single value or an array to match any of
2137
2295
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2236,16 +2394,6 @@ export interface AttorneyTrademarksParams {
2236
2394
  include_total?: boolean;
2237
2395
  include?: TrademarkSearchInclude[];
2238
2396
  fields?: string[];
2239
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2240
- q?: string;
2241
- /**
2242
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2243
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2244
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2245
- */
2246
- match?: MatchMode;
2247
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2248
- mark_text_not_contains?: string;
2249
2397
  limit?: number;
2250
2398
  cursor?: string;
2251
2399
  }
@@ -2273,7 +2421,7 @@ export interface FirmAttorneysParams {
2273
2421
  limit?: number;
2274
2422
  cursor?: string;
2275
2423
  }
2276
- export interface FirmTrademarksParams {
2424
+ export interface FirmTrademarksParams extends SearchTextParams {
2277
2425
  /**
2278
2426
  * Coarse status bucket. Accepts a single value or an array to match any of
2279
2427
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2378,16 +2526,6 @@ export interface FirmTrademarksParams {
2378
2526
  include_total?: boolean;
2379
2527
  include?: TrademarkSearchInclude[];
2380
2528
  fields?: string[];
2381
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2382
- q?: string;
2383
- /**
2384
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2385
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2386
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2387
- */
2388
- match?: MatchMode;
2389
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2390
- mark_text_not_contains?: string;
2391
2529
  limit?: number;
2392
2530
  cursor?: string;
2393
2531
  }
@@ -2398,8 +2536,25 @@ export interface ProceedingListParams {
2398
2536
  trademark_role?: 'contested' | 'asserted';
2399
2537
  proceeding_type?: string;
2400
2538
  status?: string;
2539
+ /**
2540
+ * Case-insensitive substring of a recorded party name. Combined with
2541
+ * `party_role` / `party_owner_id` / `party_entity_id`, all must match the
2542
+ * same party (`q: 'Acme', party_role: 'opponent'` = Acme is the opponent).
2543
+ */
2401
2544
  q?: string;
2545
+ /**
2546
+ * Proceedings where a party is linked to this owner. Only linked parties
2547
+ * match. Most Canadian and Australian opponents are not linked (they are
2548
+ * matched only against the owner of the mark under challenge), nor are
2549
+ * suffix-only name matches and multi-party names; use `q` for name matching
2550
+ * or complete coverage.
2551
+ */
2402
2552
  party_owner_id?: string;
2553
+ /**
2554
+ * Proceedings where a party is linked to any member owner of the entity.
2555
+ * Linked parties only, as for `party_owner_id`; use `q` for name matching.
2556
+ * Malformed id → 400; over the member-owner cap → 422 `entity_too_large`.
2557
+ */
2403
2558
  party_entity_id?: string;
2404
2559
  /** Alias for party_entity_id. */
2405
2560
  entity_id?: string;
@@ -2474,7 +2629,7 @@ export interface ClassificationSuggestParams {
2474
2629
  description: string;
2475
2630
  }
2476
2631
  /**
2477
- * POST body for `POST /v1/trademarks` (complex queries with filters, aggregations, strategies).
2632
+ * POST body for `POST /v1/trademarks` (structured filters, `mark_text` operators, exclusions, aggregations).
2478
2633
  *
2479
2634
  * This replaces the old `POST /v1/trademarks/search` endpoint.
2480
2635
  */
@@ -2590,23 +2745,22 @@ export interface ImageSearchResults {
2590
2745
  }
2591
2746
  export interface TrademarkSearchBody {
2592
2747
  /**
2593
- * Optional text query, or a list of exact terms (see
2594
- * `TrademarkListParams.q`). When omitted, results are filter-only.
2748
+ * Search text, ranked through the `similarity` channels. Always literal;
2749
+ * omit it for a filtered listing. See {@link SearchTextParams.q}; a list of
2750
+ * terms as in {@link TrademarkListParams.q}.
2751
+ */
2752
+ q?: string | readonly string[];
2753
+ /**
2754
+ * Similarity channels for `q` (default `identical`, `fuzzy`, `embedded`,
2755
+ * `lookalike`; `identical` always on). Requires `q`. See {@link Presets}.
2595
2756
  */
2596
- query?: string | string[];
2597
- /** Alias for `query`. Send one or the other, not both. */
2598
- q?: string | string[];
2599
- /** Search strategies (e.g. 'exact', 'phonetic', 'fuzzy', 'prefix'). */
2600
- strategies?: ('exact' | 'phonetic' | 'fuzzy' | 'prefix')[];
2757
+ similarity?: readonly SimilarityChannel[];
2601
2758
  /**
2602
- * ENG-106 — how `query` matches the mark text. `'similar'` (default, ranked)
2603
- * vs the deterministic `'exact'` / `'starts_with'` / `'ends_with'` /
2604
- * `'contains'` modes. Deterministic modes require `query` and disallow
2605
- * `strategies`; `'contains'` needs a folded query ≥ 3 chars.
2759
+ * Exclusions: `mark_text` operators and the `entity_id`, `entity_group`,
2760
+ * `owner_id` and `trademark_ids` lists. A row matching any value is removed;
2761
+ * exclusions never affect ranking.
2606
2762
  */
2607
- match?: MatchMode;
2608
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2609
- mark_text_not_contains?: string;
2763
+ exclude?: SearchExclude;
2610
2764
  filters?: {
2611
2765
  /**
2612
2766
  * Coarse status bucket. Accepts a single value or an array to match any
@@ -2674,6 +2828,12 @@ export interface TrademarkSearchBody {
2674
2828
  is_madrid?: boolean;
2675
2829
  is_retracted?: boolean;
2676
2830
  is_series_mark?: boolean;
2831
+ /**
2832
+ * Mark text operators: `is`, `word`, `starts_with`, `ends_with`,
2833
+ * `contains`, `pattern`. Values within one operator are OR; operators
2834
+ * (and `q`) are AND.
2835
+ */
2836
+ mark_text?: MarkTextFilters;
2677
2837
  };
2678
2838
  options?: {
2679
2839
  aggregations?: TrademarkAggregationName[];
@@ -2682,12 +2842,14 @@ export interface TrademarkSearchBody {
2682
2842
  include_total?: boolean;
2683
2843
  highlights?: boolean;
2684
2844
  include_timing?: boolean;
2845
+ /** Return `200` with `search_meta.complete: false` on an engine timeout or shard failure instead of `503`. Default false. */
2846
+ allow_partial?: boolean;
2685
2847
  };
2686
2848
  /**
2687
2849
  * Sort spec. Prefix with `-` for descending. Comma-separated for multi-field.
2688
- * When `query` is present and no sort is given, results are ranked by relevance.
2689
- * When no `query` and no sort, defaults to `-filing_date`.
2690
- * When explicit sort is set with `query`, relevance scoring is disabled.
2850
+ * Default: relevance with `q`; mark text order with a `filters.mark_text`
2851
+ * operator and no `q`; otherwise `-filing_date`. With `q`, `relevance_score`
2852
+ * and `match` stay on every hit under any sort.
2691
2853
  */
2692
2854
  sort?: string;
2693
2855
  limit?: number;
@@ -3027,6 +3189,7 @@ export interface WebhookDeliveryListParams {
3027
3189
  since?: string;
3028
3190
  }
3029
3191
  export interface OrgEventListParams {
3192
+ /** Event type(s). As on webhooks, `trademark.status_changed` also matches `trademark.corrected`. */
3030
3193
  event_type?: string | string[];
3031
3194
  office_code?: string | string[];
3032
3195
  trademark_id?: string;
@@ -3259,6 +3422,12 @@ export interface ScreeningHit {
3259
3422
  owner_portfolio_size: number | null;
3260
3423
  };
3261
3424
  trademark: TrademarkSummary;
3425
+ /** Origin of the served risk band. Informational; not legal advice. */
3426
+ band_source?: components['schemas']['ScreeningHit']['band_source'];
3427
+ /** Additive v3 scorer read; never the served band. Informational; not legal advice. */
3428
+ model_assessment?: components['schemas']['ScreeningHit']['model_assessment'];
3429
+ /** DuPont factor ledger with supporting evidence. Informational; not legal advice. */
3430
+ factor_ledger?: ScreeningFactorEntry[];
3262
3431
  }
3263
3432
  /** `GET /v1/screening` response — bespoke list envelope. */
3264
3433
  export interface ScreenResult {
@@ -3660,6 +3829,10 @@ export interface ListingCandidate {
3660
3829
  verdict: ListingVerdict;
3661
3830
  nice_classes_used: number[];
3662
3831
  hits: ListingCandidateHit[];
3832
+ /** Derived confidence that this candidate is a real conflict (a projection of verdict and band, not a model). */
3833
+ confidence?: components['schemas']['ListingCandidate']['confidence'];
3834
+ /** Severity rank within the listing (0 = most severe); does not reorder `data`. */
3835
+ rank?: number;
3663
3836
  }
3664
3837
  /** A candidate that was NOT screened, with a closed reason code (auditability). */
3665
3838
  export interface SuppressedListingCandidate {