@signa-so/sdk 0.15.0 → 0.17.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
@@ -455,51 +455,60 @@ export type WatchStatus = 'active' | 'paused' | 'disabled';
455
455
  * (= `ALERT_EVENT_TYPES` from `@signa/types`) and `DEFAULT_TRIGGER_EVENTS`.
456
456
  */
457
457
  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. */
458
+ /**
459
+ * Legacy attribution tier gate, echoed by diagnostics for a watch stored in
460
+ * the v1/v2 form. New watches use `min_tier` ({@link MatchTier}).
461
+ */
461
462
  export type WatchMinMatchTier = 'exact' | 'normalized' | 'fuzzy' | 'phonetic';
462
463
  /**
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
464
+ * Watch query DSL. Five watch types share one shape; the `watch_type`
465
+ * selects which scoping field is required. See the
466
466
  * [Watches guide](https://docs.signa.so/guides/monitoring/watches) for
467
467
  * the per-type required-field table.
468
468
  *
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).
469
+ * Send `version: 'v3'`, `q`, optional `similarity` (the search channels,
470
+ * same default as search) and optional `min_tier` (the weakest
471
+ * {@link MatchTier} that alerts; default `related`, everything through).
472
+ * The API stores every written query as `v3` whatever `version` it sends, so
473
+ * a plain `{ version: 'v2', q }` gets the default channels and `min_tier:
474
+ * 'related'` too. `filters` keeps its camelCase vocabulary (`trademarkIds`,
475
+ * `ownerId`, `niceClasses`, `jurisdictions`, `offices`, ...).
476
+ * `trigger_events` narrows which lifecycle events fire alerts. Watches do
477
+ * not accept the search `mark_text_*` filters or exclusions (400).
477
478
  *
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.
479
+ * The old `strategies` and `min_match_tier` keys are removed from this type
480
+ * (0.17.0). The API still accepts them until 2026-12-28: a watch written
481
+ * with them is kept as a legacy watch, with its original matching, until it
482
+ * is re-saved without them, and the write response lists them in
483
+ * `deprecations`. Stored watches are never rewritten: a watch saved in the
484
+ * v1/v2 form keeps its matching until its query changes.
485
+ *
486
+ * `score_threshold` is NOT supported on write (400); scores are
487
+ * informational (see `match.score` on alerts). Forbidden DSL keys
488
+ * (`function_score`, `script`, `sort`, `cursor`, `aggregations`,
489
+ * `highlight`) and `query.match` in any form are rejected with 400. Unknown
490
+ * `filters` keys are rejected with 400 listing the allowed vocabulary.
486
491
  */
487
492
  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. */
493
+ /**
494
+ * Required on write. `'v1'`, `'v2'` and `'v3'` are accepted; send `'v3'`. A new or changed query is
495
+ * stored as `'v3'` whatever version it sends, unless it uses the deprecated keys; `'v1'` / `'v2'`
496
+ * otherwise appear only on stored legacy queries.
497
+ */
498
+ version: 'v1' | 'v2' | 'v3';
499
+ /** Search text (required for similarity watches). */
491
500
  q?: string;
492
- /** Search strategies to use. Omit for the public-search default (`exact` + `fuzzy`). */
493
- strategies?: WatchSearchStrategy[];
501
+ /** Similarity channels for `q`. Omit for the search default (`identical`, `fuzzy`, `embedded`, `lookalike`). */
502
+ similarity?: readonly SimilarityChannel[];
503
+ /** The weakest similarity tier that alerts. Default `related` (every tier). */
504
+ min_tier?: MatchTier;
494
505
  /** Filter object — same vocabulary as the trademark search API. Common keys: `trademarkIds`, `ownerId`, `niceClasses`, `jurisdictions`, `offices`, `statusPrimary`. */
495
506
  filters?: Record<string, unknown>;
496
507
  /** Restrict alert generation to specific trigger event types. */
497
508
  trigger_events?: WatchTriggerEvent[];
498
- /** Minimum attribution tier for similarity watches. `phonetic` is the broad "any tier" setting. */
499
- min_match_tier?: WatchMinMatchTier;
500
509
  /**
501
510
  * NOT currently supported — sending this on create/update/bulk/preview is
502
- * rejected with 400. Scores are informational (see `match_score` on alerts).
511
+ * rejected with 400. Scores are informational (see `match.score` on alerts).
503
512
  * The field is retained on the type so existing stored watch queries still
504
513
  * deserialize on GET. Contact support for calibrated-band thresholds.
505
514
  */
@@ -522,6 +531,12 @@ export interface Watch {
522
531
  metadata: Record<string, unknown>;
523
532
  created_at: string;
524
533
  updated_at: string;
534
+ /**
535
+ * Present on create, update and bulk responses when the written query used
536
+ * a deprecated key (`strategies`, `min_match_tier`); the watch is kept as a
537
+ * legacy watch until re-saved without them.
538
+ */
539
+ deprecations?: SearchDeprecation[];
525
540
  }
526
541
  /**
527
542
  * Alert event types — what the API actually emits for `Alert.event_type`.
@@ -598,6 +613,12 @@ export interface AlertMatch {
598
613
  score: number | null;
599
614
  /** What the score is derived from, e.g. `opensearch_relevance`; null when none. */
600
615
  score_basis: string | null;
616
+ /**
617
+ * Similarity tier of the matched mark, the same label a search hit carries
618
+ * as `match.tier`. `null` for filter-only watches, marks found only by their
619
+ * number, and alerts emitted before 0.17.0.
620
+ */
621
+ tier: MatchTier | null;
601
622
  }
602
623
  /**
603
624
  * Compact mark summary embedded on the alert (Alerts v2 `trademark` block).
@@ -1133,6 +1154,12 @@ export interface WatchPreviewResponse {
1133
1154
  has_more?: boolean;
1134
1155
  /** Echo of the effective page size for `results`. Omitted when count_only. */
1135
1156
  result_limit?: number;
1157
+ /** The similarity channels the query runs. `null` without `q` and for a query with the deprecated keys. */
1158
+ similarity_applied: SimilarityChannel[] | null;
1159
+ /** The weakest tier that alerts. `null` for a query with the deprecated keys. */
1160
+ min_tier: MatchTier | null;
1161
+ /** Deprecated query keys the previewed query used (see {@link Watch.deprecations}). */
1162
+ deprecations?: SearchDeprecation[];
1136
1163
  request_id: string;
1137
1164
  }
1138
1165
  /**
@@ -1180,7 +1207,12 @@ export interface WatchDiagnostics {
1180
1207
  * INERT — no longer gates matching, and rejected on new writes.
1181
1208
  */
1182
1209
  score_threshold: number | null;
1210
+ /** Legacy tier gate of a watch stored in the v1/v2 form; `null` otherwise. */
1183
1211
  min_match_tier: WatchMinMatchTier | null;
1212
+ /** 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). */
1213
+ similarity_applied: SimilarityChannel[] | null;
1214
+ /** 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`. */
1215
+ min_tier: MatchTier | null;
1184
1216
  alert_fired: boolean;
1185
1217
  /**
1186
1218
  * Walked in order: alert fired → office not in scope → freshness limit →
@@ -1544,21 +1576,15 @@ export interface TrademarkDocument {
1544
1576
  }
1545
1577
  /** Owner related entity (GLEIF corporate hierarchy). */
1546
1578
  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` / `ranking_profile`; `contains`
1553
- * additionally needs a folded query of at least 3 characters.
1554
- */
1555
- export type MatchMode = 'similar' | 'exact' | 'starts_with' | 'ends_with' | 'contains';
1556
1579
  /**
1557
1580
  * Search metadata on trademark search and list responses.
1558
1581
  *
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;
1582
+ * 0.17.0: `similarity_applied` (the channels `q` ran on), `ranking_version`
1583
+ * (cursors are bound to it), `order` (the order applied), `complete` /
1584
+ * `incomplete_reason` (false only with `allow_partial`), `identifier` (when
1585
+ * `q` was read as a trademark number) and `deprecations` (old parameters the
1586
+ * request used). `strategies_used` and `match` are deprecated and removed on
1587
+ * 2026-12-28. `index_generation` names the index that served the page;
1562
1588
  * cursors are bound to it, so a cursor from before an index rebuild returns
1563
1589
  * `400 cursor_invalid` and pagination restarts.
1564
1590
  *
@@ -1566,11 +1592,45 @@ export type MatchMode = 'similar' | 'exact' | 'starts_with' | 'ends_with' | 'con
1566
1592
  * (`SignaList.total_count`) when the request sets `include_total`.
1567
1593
  */
1568
1594
  export type SearchMeta = NonNullable<components['schemas']['SearchResponseV2']['search_meta']>;
1595
+ /**
1596
+ * A similarity channel for a ranked `q`. The default set is `identical`,
1597
+ * `fuzzy`, `embedded` and `lookalike`; `identical` is always on. See
1598
+ * {@link Presets} for the knockout and clearance sets.
1599
+ */
1600
+ export type SimilarityChannel = SearchMeta['similarity_applied'][number];
1601
+ /**
1602
+ * `match` on a search hit: `tier` (strongest similarity tier matched; `null`
1603
+ * without `q` or for a hit found only by its number), `via` (channels that
1604
+ * matched, plus `identifier`), `terms` (the `mark_text_*` values the hit
1605
+ * satisfied) and, with `include: ['match_details']`, `details`.
1606
+ */
1607
+ export type TrademarkMatch = components['schemas']['TrademarkMatch'];
1608
+ /**
1609
+ * Similarity tier, strongest first: `identical`, `near_identical`, `similar`,
1610
+ * `related`. A retrieval category, not a measured edit distance. Used by
1611
+ * search hits (`match.tier`), watch `min_tier` and alerts (`match.tier`).
1612
+ */
1613
+ export type MatchTier = NonNullable<TrademarkMatch['tier']>;
1614
+ /**
1615
+ * Mark text operators (POST `filters.mark_text` and `exclude.mark_text`).
1616
+ * Values within one operator are OR; operators are AND. Up to 100 values of
1617
+ * 200 characters each.
1618
+ */
1619
+ export type MarkTextFilters = components['schemas']['MarkTextFilters'];
1620
+ /** One mark text operator: `is`, `word`, `starts_with`, `ends_with`, `contains`, `pattern`. */
1621
+ export type MarkTextOperator = keyof MarkTextFilters;
1622
+ /** POST `exclude`: rows matching any value are removed. Never affects ranking. */
1623
+ export type SearchExclude = components['schemas']['SearchExclude'];
1624
+ /**
1625
+ * A `search_meta.deprecations[]` (and watch `deprecations[]`) entry: an old
1626
+ * parameter the request used, its replacement, and the date (`sunset`) from
1627
+ * which the old parameter is a `400`.
1628
+ */
1629
+ export type SearchDeprecation = NonNullable<SearchMeta['deprecations']>[number];
1569
1630
  /**
1570
1631
  * 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.
1632
+ * and the code's own detail fields (`channel`, `affected_filter(s)`,
1633
+ * `affected_offices`, ...). Keep a default branch: new codes can appear.
1574
1634
  */
1575
1635
  export type SearchWarning = NonNullable<SearchMeta['warnings']>[number];
1576
1636
  /** API error body (RFC 9457-inspired). */
@@ -1674,7 +1734,84 @@ export interface ResourceQuotaExceededErrorBody extends APIErrorBody {
1674
1734
  */
1675
1735
  suggestion?: string;
1676
1736
  }
1677
- export type TrademarkSearchInclude = 'full_goods_services';
1737
+ /**
1738
+ * Optional search row projections. `full_goods_services` disables summary G&S
1739
+ * truncation; `match_details` adds `match.details` (matched lanes and applied
1740
+ * ranking factors) to each hit.
1741
+ */
1742
+ export type TrademarkSearchInclude = 'full_goods_services' | 'match_details';
1743
+ /**
1744
+ * One value or a list for a repeated-key GET param (`mark_text_*`, `*_not`).
1745
+ * A scalar is a one-element list; commas inside a value are never split.
1746
+ */
1747
+ export type SearchTextList = string | readonly string[];
1748
+ /**
1749
+ * The search request surface shared by `trademarks.list()` and the owner,
1750
+ * attorney, firm and entity `trademarks()` sub-resources (search v2, 0.17.0).
1751
+ *
1752
+ * `q` ranks; the `mark_text_*` filters decide which marks qualify; the
1753
+ * `mark_text_not_*` and `*_not` exclusions remove marks and never affect
1754
+ * ranking. Values within one key are OR; different keys (and `q`) are AND.
1755
+ * The `mark_text_*` and `*_not` lists go on the wire as repeated keys
1756
+ * (`mark_text_is=a&mark_text_is=b`), so a comma inside a mark is safe.
1757
+ *
1758
+ * ```typescript
1759
+ * import { Presets } from '@signa-so/sdk';
1760
+ * await signa.trademarks.list({ q: 'limber', ...Presets.clearance, mark_text_not_is: ['LIMBER'] });
1761
+ * ```
1762
+ */
1763
+ export interface SearchTextParams {
1764
+ /**
1765
+ * Search text, ranked through the `similarity` channels (1-500 characters,
1766
+ * at least 2 after folding; 1 on the party sub-resources). Always literal.
1767
+ * A trademark number in `q` (`1939139`, `US 5123456`, `tm_...`) is also
1768
+ * looked up, and its records lead the page (`search_meta.identifier`).
1769
+ */
1770
+ q?: string;
1771
+ /**
1772
+ * Similarity channels for `q`: `identical`, `fuzzy`, `embedded`,
1773
+ * `phonetic`, `lookalike`. Default `identical`, `fuzzy`, `embedded`,
1774
+ * `lookalike`; `identical` is always on. Requires `q`. See {@link Presets}.
1775
+ */
1776
+ similarity?: readonly SimilarityChannel[];
1777
+ /** Whole-mark equality (case, accents, punctuation, spacing and trademark notices ignored). Replaces a list in `q` and `match: 'exact'`. */
1778
+ mark_text_is?: SearchTextList;
1779
+ /** The value appears as a whole word, or consecutive words, of the mark. */
1780
+ mark_text_word?: SearchTextList;
1781
+ /** The folded mark begins with the value. Replaces `match: 'starts_with'`. */
1782
+ mark_text_starts_with?: SearchTextList;
1783
+ /** The folded mark ends with the value (at least 3 characters). Replaces `match: 'ends_with'`. */
1784
+ mark_text_ends_with?: SearchTextList;
1785
+ /** The value appears anywhere in the folded mark (at least 3 characters). Replaces `match: 'contains'`. */
1786
+ mark_text_contains?: SearchTextList;
1787
+ /** `*` any run, `?` one character, `\` escapes the next character; everything else literal. */
1788
+ mark_text_pattern?: SearchTextList;
1789
+ /** Exclude marks equal to any value (same folding as `mark_text_is`). */
1790
+ mark_text_not_is?: SearchTextList;
1791
+ /** Exclude marks containing any value as a whole word. */
1792
+ mark_text_not_word?: SearchTextList;
1793
+ /** Exclude marks beginning with any value. */
1794
+ mark_text_not_starts_with?: SearchTextList;
1795
+ /** Exclude marks ending with any value. */
1796
+ mark_text_not_ends_with?: SearchTextList;
1797
+ /** Exclude marks containing any value (punctuation and spacing folded, like the other operators). A list since 0.17.0. */
1798
+ mark_text_not_contains?: SearchTextList;
1799
+ /** Exclude marks matching any pattern. */
1800
+ mark_text_not_pattern?: SearchTextList;
1801
+ /** Exclude marks whose owners are linked to these entities (`ent_*`). */
1802
+ entity_id_not?: SearchTextList;
1803
+ /** Exclude marks linked to any entity in these entities' corporate families (`ent_*`). */
1804
+ entity_group_not?: SearchTextList;
1805
+ /** Exclude marks held by these owners (`own_*`). */
1806
+ owner_id_not?: SearchTextList;
1807
+ /** Exclude these trademarks (`tm_*`); on the grouped view, the family row containing them. */
1808
+ trademark_ids_not?: SearchTextList;
1809
+ /**
1810
+ * Return `200` with `search_meta.complete: false` when the search hits its
1811
+ * time limit or loses a shard, instead of a retryable `503`. Default false.
1812
+ */
1813
+ allow_partial?: boolean;
1814
+ }
1678
1815
  export type TrademarkDetailInclude = 'office_extensions';
1679
1816
  /**
1680
1817
  * How a `jurisdictions` filter matches. `protection` (default) selects rights
@@ -1720,7 +1857,7 @@ export type TrademarkAggregationName = 'status_stage' | 'office_code' | 'jurisdi
1720
1857
  | 'entity_count';
1721
1858
  /** How aggregation counts relate to filters (`aggregation_mode`). */
1722
1859
  export type TrademarkAggregationMode = 'filtered' | 'exclude_own_filter';
1723
- export interface TrademarkListParams {
1860
+ export interface TrademarkListParams extends SearchTextParams {
1724
1861
  /**
1725
1862
  * Coarse status bucket. Accepts a single value or an array to match any of
1726
1863
  * several values — passing `['active', 'pending']` yields TESS-style "live"
@@ -1809,15 +1946,6 @@ export interface TrademarkListParams {
1809
1946
  updated_at_gt?: string;
1810
1947
  updated_at_lte?: string;
1811
1948
  updated_at_lt?: string;
1812
- /**
1813
- * When the mark family last changed. Grouped view only (a record-grain
1814
- * request is a 400); pairs with `sort: 'family_updated_at'` for incremental
1815
- * sync, which pages past 10,000 results on filter-only requests.
1816
- */
1817
- family_updated_at_gte?: string;
1818
- family_updated_at_gt?: string;
1819
- family_updated_at_lte?: string;
1820
- family_updated_at_lt?: string;
1821
1949
  owner_id?: string;
1822
1950
  owner_name?: string;
1823
1951
  owner_publicly_traded?: boolean;
@@ -1845,43 +1973,19 @@ export interface TrademarkListParams {
1845
1973
  is_retracted?: boolean;
1846
1974
  is_series_mark?: boolean;
1847
1975
  international_registrations?: 'grouped' | 'expanded';
1848
- /**
1849
- * Optional text query (triggers relevance ranking when no explicit sort),
1850
- * or a list of exact terms: every mark that is an exact match under
1851
- * `match: 'exact'` rules (case, accents, punctuation and spacing) for ANY
1852
- * of the terms, each hit carrying `matched_terms[]`. A list takes 1-100
1853
- * terms, runs `match: 'exact'` (the default for a list) and costs the same
1854
- * as one search page. `list()` sends it as a JSON array
1855
- * (`q=["limber","bimber"]`), and by POST when the query string would pass
1856
- * the API's 2 KB GET limit.
1857
- */
1858
- q?: string | string[];
1859
1976
  /** ENG-67 — faceted bucket counts (TMview "Statistics view"). Field names to aggregate. */
1860
1977
  aggregations?: TrademarkAggregationName[];
1861
1978
  /** `filtered` (default): aggregations respect every filter. `exclude_own_filter`: each aggregation ignores its own filter (drill-down sidebars). */
1862
1979
  aggregation_mode?: TrademarkAggregationMode;
1863
1980
  /** ENG-67 — when true, return only aggregation counts (no result documents). */
1864
1981
  aggregations_only?: boolean;
1865
- /** Search strategies to apply (e.g. 'exact', 'phonetic', 'fuzzy', 'prefix'). */
1866
- strategies?: string[];
1867
- /** Ranking profile to use. */
1868
- ranking_profile?: string;
1869
- /**
1870
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
1871
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
1872
- * modes. Deterministic modes require `q` and disallow `strategies` /
1873
- * `ranking_profile`; `'contains'` needs a folded query ≥ 3 chars.
1874
- */
1875
- match?: MatchMode;
1876
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
1877
- mark_text_not_contains?: string;
1878
1982
  /** When true, include total_count in pagination (adds latency). */
1879
1983
  include_total?: boolean;
1880
1984
  /** When true, include match highlight spans. */
1881
1985
  highlights?: boolean;
1882
1986
  /** When true, include execution timing in search_meta. */
1883
1987
  include_timing?: boolean;
1884
- /** Optional row projections. `full_goods_services` disables summary G&S truncation. */
1988
+ /** Optional row projections: `full_goods_services`, `match_details`. */
1885
1989
  include?: TrademarkSearchInclude[];
1886
1990
  /** Sparse top-level field projection. `id` and `object` are always retained. */
1887
1991
  fields?: string[];
@@ -1892,8 +1996,10 @@ export interface TrademarkListParams {
1892
1996
  /**
1893
1997
  * Sort spec. Prefix with `-` for descending. Comma-separated for multi-field.
1894
1998
  * E.g. `-filing_date`, `registration_date`, `-filing_date,office_code`.
1895
- * When `q` is present and no sort is given, results are ranked by relevance.
1896
- * When no `q` and no sort, defaults to `-filing_date`.
1999
+ * Default: relevance with `q`; mark text order (exact fits first, then
2000
+ * prefix fits, then shorter marks) with a `mark_text_*` filter and no `q`;
2001
+ * otherwise `-filing_date`. With `q`, `relevance_score` and `match` stay on
2002
+ * every hit under any sort. `search_meta.order` reports the order applied.
1897
2003
  */
1898
2004
  sort?: string;
1899
2005
  limit?: number;
@@ -2006,7 +2112,7 @@ export interface OwnerListParams {
2006
2112
  limit?: number;
2007
2113
  cursor?: string;
2008
2114
  }
2009
- export interface OwnerTrademarksParams {
2115
+ export interface OwnerTrademarksParams extends SearchTextParams {
2010
2116
  /**
2011
2117
  * Coarse status bucket. Accepts a single value or an array to match any of
2012
2118
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2095,15 +2201,6 @@ export interface OwnerTrademarksParams {
2095
2201
  updated_at_gt?: string;
2096
2202
  updated_at_lte?: string;
2097
2203
  updated_at_lt?: string;
2098
- /**
2099
- * When the mark family last changed. Grouped view only (a record-grain
2100
- * request is a 400); pairs with `sort: 'family_updated_at'` for incremental
2101
- * sync, which pages past 10,000 results on filter-only requests.
2102
- */
2103
- family_updated_at_gte?: string;
2104
- family_updated_at_gt?: string;
2105
- family_updated_at_lte?: string;
2106
- family_updated_at_lt?: string;
2107
2204
  owner_name?: string;
2108
2205
  owner_publicly_traded?: boolean;
2109
2206
  owner_has_lei?: boolean;
@@ -2120,16 +2217,6 @@ export interface OwnerTrademarksParams {
2120
2217
  include_total?: boolean;
2121
2218
  include?: TrademarkSearchInclude[];
2122
2219
  fields?: string[];
2123
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2124
- q?: string;
2125
- /**
2126
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2127
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2128
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2129
- */
2130
- match?: MatchMode;
2131
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2132
- mark_text_not_contains?: string;
2133
2220
  limit?: number;
2134
2221
  cursor?: string;
2135
2222
  }
@@ -2151,7 +2238,7 @@ export interface AttorneyListParams {
2151
2238
  limit?: number;
2152
2239
  cursor?: string;
2153
2240
  }
2154
- export interface AttorneyTrademarksParams {
2241
+ export interface AttorneyTrademarksParams extends SearchTextParams {
2155
2242
  /**
2156
2243
  * Coarse status bucket. Accepts a single value or an array to match any of
2157
2244
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2240,15 +2327,6 @@ export interface AttorneyTrademarksParams {
2240
2327
  updated_at_gt?: string;
2241
2328
  updated_at_lte?: string;
2242
2329
  updated_at_lt?: string;
2243
- /**
2244
- * When the mark family last changed. Grouped view only (a record-grain
2245
- * request is a 400); pairs with `sort: 'family_updated_at'` for incremental
2246
- * sync, which pages past 10,000 results on filter-only requests.
2247
- */
2248
- family_updated_at_gte?: string;
2249
- family_updated_at_gt?: string;
2250
- family_updated_at_lte?: string;
2251
- family_updated_at_lt?: string;
2252
2330
  owner_name?: string;
2253
2331
  owner_id?: string;
2254
2332
  owner_publicly_traded?: boolean;
@@ -2265,16 +2343,6 @@ export interface AttorneyTrademarksParams {
2265
2343
  include_total?: boolean;
2266
2344
  include?: TrademarkSearchInclude[];
2267
2345
  fields?: string[];
2268
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2269
- q?: string;
2270
- /**
2271
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2272
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2273
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2274
- */
2275
- match?: MatchMode;
2276
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2277
- mark_text_not_contains?: string;
2278
2346
  limit?: number;
2279
2347
  cursor?: string;
2280
2348
  }
@@ -2302,7 +2370,7 @@ export interface FirmAttorneysParams {
2302
2370
  limit?: number;
2303
2371
  cursor?: string;
2304
2372
  }
2305
- export interface FirmTrademarksParams {
2373
+ export interface FirmTrademarksParams extends SearchTextParams {
2306
2374
  /**
2307
2375
  * Coarse status bucket. Accepts a single value or an array to match any of
2308
2376
  * several values (e.g. `['active', 'pending']` for TESS-style "live" marks).
@@ -2391,15 +2459,6 @@ export interface FirmTrademarksParams {
2391
2459
  updated_at_gt?: string;
2392
2460
  updated_at_lte?: string;
2393
2461
  updated_at_lt?: string;
2394
- /**
2395
- * When the mark family last changed. Grouped view only (a record-grain
2396
- * request is a 400); pairs with `sort: 'family_updated_at'` for incremental
2397
- * sync, which pages past 10,000 results on filter-only requests.
2398
- */
2399
- family_updated_at_gte?: string;
2400
- family_updated_at_gt?: string;
2401
- family_updated_at_lte?: string;
2402
- family_updated_at_lt?: string;
2403
2462
  owner_name?: string;
2404
2463
  owner_id?: string;
2405
2464
  owner_publicly_traded?: boolean;
@@ -2416,16 +2475,6 @@ export interface FirmTrademarksParams {
2416
2475
  include_total?: boolean;
2417
2476
  include?: TrademarkSearchInclude[];
2418
2477
  fields?: string[];
2419
- /** Text query to match against the mark text within this portfolio. Required for any deterministic `match` mode. */
2420
- q?: string;
2421
- /**
2422
- * ENG-106 — how `q` matches the mark text. `'similar'` (default, ranked) vs
2423
- * the deterministic `'exact'` / `'starts_with'` / `'ends_with'` / `'contains'`
2424
- * modes. Deterministic modes require `q`; `'contains'` needs a folded query ≥ 3 chars.
2425
- */
2426
- match?: MatchMode;
2427
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2428
- mark_text_not_contains?: string;
2429
2478
  limit?: number;
2430
2479
  cursor?: string;
2431
2480
  }
@@ -2512,7 +2561,7 @@ export interface ClassificationSuggestParams {
2512
2561
  description: string;
2513
2562
  }
2514
2563
  /**
2515
- * POST body for `POST /v1/trademarks` (complex queries with filters, aggregations, strategies).
2564
+ * POST body for `POST /v1/trademarks` (structured filters, `mark_text` operators, exclusions, aggregations).
2516
2565
  *
2517
2566
  * This replaces the old `POST /v1/trademarks/search` endpoint.
2518
2567
  */
@@ -2628,25 +2677,21 @@ export interface ImageSearchResults {
2628
2677
  }
2629
2678
  export interface TrademarkSearchBody {
2630
2679
  /**
2631
- * Optional text query, or a list of exact terms (see
2632
- * `TrademarkListParams.q`). When omitted, results are filter-only.
2633
- */
2634
- query?: string | string[];
2635
- /** Alias for `query`. Send one or the other, not both. */
2636
- q?: string | string[];
2637
- /** Search strategies (e.g. 'exact', 'phonetic', 'fuzzy', 'prefix'). */
2638
- strategies?: ('exact' | 'phonetic' | 'fuzzy' | 'prefix')[];
2639
- /** Ranking profile to use. */
2640
- ranking_profile?: string;
2641
- /**
2642
- * ENG-106 — how `query` matches the mark text. `'similar'` (default, ranked)
2643
- * vs the deterministic `'exact'` / `'starts_with'` / `'ends_with'` /
2644
- * `'contains'` modes. Deterministic modes require `query` and disallow
2645
- * `strategies` / `ranking_profile`; `'contains'` needs a folded query ≥ 3 chars.
2646
- */
2647
- match?: MatchMode;
2648
- /** ENG-106 — exclude marks whose text contains this substring (case/accent-insensitive). Composable with any match mode. */
2649
- mark_text_not_contains?: string;
2680
+ * Search text, ranked through the `similarity` channels. Always literal;
2681
+ * omit it for a filtered listing. See {@link SearchTextParams.q}.
2682
+ */
2683
+ q?: string;
2684
+ /**
2685
+ * Similarity channels for `q` (default `identical`, `fuzzy`, `embedded`,
2686
+ * `lookalike`; `identical` always on). Requires `q`. See {@link Presets}.
2687
+ */
2688
+ similarity?: readonly SimilarityChannel[];
2689
+ /**
2690
+ * Exclusions: `mark_text` operators and the `entity_id`, `entity_group`,
2691
+ * `owner_id` and `trademark_ids` lists. A row matching any value is removed;
2692
+ * exclusions never affect ranking.
2693
+ */
2694
+ exclude?: SearchExclude;
2650
2695
  filters?: {
2651
2696
  /**
2652
2697
  * Coarse status bucket. Accepts a single value or an array to match any
@@ -2689,8 +2734,6 @@ export interface TrademarkSearchBody {
2689
2734
  first_use_in_commerce_date?: DateRangeFilter;
2690
2735
  termination_date?: DateRangeFilter;
2691
2736
  updated_at?: DateRangeFilter;
2692
- /** When the mark family last changed (grouped view only). */
2693
- family_updated_at?: DateRangeFilter;
2694
2737
  owner_id?: string;
2695
2738
  owner_name?: string;
2696
2739
  owner_publicly_traded?: boolean;
@@ -2716,6 +2759,12 @@ export interface TrademarkSearchBody {
2716
2759
  is_madrid?: boolean;
2717
2760
  is_retracted?: boolean;
2718
2761
  is_series_mark?: boolean;
2762
+ /**
2763
+ * Mark text operators: `is`, `word`, `starts_with`, `ends_with`,
2764
+ * `contains`, `pattern`. Values within one operator are OR; operators
2765
+ * (and `q`) are AND.
2766
+ */
2767
+ mark_text?: MarkTextFilters;
2719
2768
  };
2720
2769
  options?: {
2721
2770
  aggregations?: TrademarkAggregationName[];
@@ -2724,12 +2773,14 @@ export interface TrademarkSearchBody {
2724
2773
  include_total?: boolean;
2725
2774
  highlights?: boolean;
2726
2775
  include_timing?: boolean;
2727
- include_profile?: boolean;
2776
+ /** Return `200` with `search_meta.complete: false` on an engine timeout or shard failure instead of `503`. Default false. */
2777
+ allow_partial?: boolean;
2728
2778
  };
2729
2779
  /**
2730
2780
  * Sort spec. Prefix with `-` for descending. Comma-separated for multi-field.
2731
- * When `query` is present and no sort is given, results are ranked by relevance.
2732
- * When explicit sort is set with `query`, relevance scoring is disabled.
2781
+ * Default: relevance with `q`; mark text order with a `filters.mark_text`
2782
+ * operator and no `q`; otherwise `-filing_date`. With `q`, `relevance_score`
2783
+ * and `match` stay on every hit under any sort.
2733
2784
  */
2734
2785
  sort?: string;
2735
2786
  limit?: number;