Watches
Preview Watch
Dry-run a query — match count without writing to the DB
POST
Overview
Returns the number of trademarks that would have alerted if this query had been a live watch over the lasttrial_window_days (default 7). Uses the
same evaluation logic as a live watch, so the count is a faithful preview
— not a separate query engine.
Useful before Create Watch to
estimate volume and tune score_threshold for similarity watches.
Preview is a read-shaped operation (it creates nothing), so the
Idempotency-Key header is accepted but no longer required. Sending one
(as in the example below) is always safe — the header is format-validated
and otherwise ignored.Body Parameters
Same DSL as Create Watch —
see the canonical query reference.
ID-bearing filters (
filters.trademarkIds, filters.ownerId, …) accept
the same prefixed (tm_* / own_*) or raw-UUID forms as create.Backtest window (1—365). Default 7.
Response
Always
"watch_preview".Trademarks that would have alerted in the trial window.
Present only when the count is an upper-bound estimate rather than an
exact count. The single value is
"candidacy_upper_bound", set by any of
three triggers: the candidacy scan overflowed the server-side cap, the
search backend was unreachable (the count falls back to the candidacy
scan), or the server-side time budget expired after candidates were found
(partial result). When the field is absent, the count is exact.Echo of the requested window.
Request identifier.
Latency and the time budget
Preview runs synchronously with a server-side time budget of roughly 20 seconds. Typical latency:class, mark, and owner previews complete
in a few seconds; similarity previews over broad scopes and long windows
are the heaviest and can approach the budget. When the budget is exceeded
there are three cases:
- Zero candidates found in the trial window — normal
200withestimated_match_count: 0(exact; never a timeout). - Budget expired after candidates were found —
200with a partial count: matches counted so far plus an upper bound for the unprocessed remainder, labeledestimate_basis: "candidacy_upper_bound". - Budget (or the database statement timeout) expired before any usable
result existed —
504with apreview_timeouterror envelope andretryable: false. Retrying the same query will hit the same wall — narrow it instead (fewer offices, shortertrial_window_days, tighter filters).
Errors
- 400 — invalid
query(see Create Watch). - 413 —
querypayload exceeds 256 KB. - 429 — another preview is already running for your organization (or
the server’s preview capacity is saturated).
rate_limitedenvelope; honor theRetry-Afterheader (roughly the server-side budget, ~20s) before retrying. The official SDK does this automatically. Unlike window429s (numeric{limit};w={sec}policies), these concurrency429s replace the policy header with a named policy —RateLimit-Policy: "preview-concurrency";c=1;w=20when your org’s own preview holds the slot, or"preview-concurrency-global";c=2;w=20when the instance-wide cap is saturated — wherecis the concurrency cap, and theRateLimitheader readsremaining=0, reset=20. - 504 —
preview_timeoutenvelope (case 3 above). The body carriesretryable: false— do not blind-retry.
504 preview_timeout