Watches
Watch Diagnostics
Explainable trace for a single (watch, trademark) pair — why an alert did or didn’t fire
GET
Overview
Self-service debugging for the question every monitoring customer eventually asks: “I expected an alert for this trademark. Why didn’t I get one?” Returns an 11-field, fully-explained trace of how Signa’s evaluator saw the trademark relative to this watch, walking from candidacy through trigger-event filtering through match outcome through delivery-mode resolution. When an alert was fired, the same response surfaces the cross-system trace IDs you need to correlate against your webhook receiver logs. Read-only. The endpoint never writes; it surfaces fields the evaluator and dispatchers already persisted. Required scope:portfolios:manage.
Path Parameters
Watch ID (
wat_*).Query Parameters
Trademark ID (
tm_*) to evaluate against this watch. Cross-org IDs return
404 (info-disclosure prevention).Response
Echoed watch ID (
wat_*).Echoed trademark ID (
tm_*).Office that issued the trademark (lowercase ISO-style code, e.g.
uspto, euipo).true if the watch evaluator processed this trademark in the current
retention window. false either because the trademark wasn’t in candidacy,
or because the relevant provenance has aged out of the retention window
(see data_window below). When false, reason explains why.true if this watch’s filters include this trademark’s office. Watch +
office routing happens via the office-checkpoint state; if the checkpoint
is missing or marked superseded, this is false.true if a change record exists for this trademark within the
retention window. Candidacy is a prerequisite for evaluation; if no change
was recorded the evaluator never saw the mark.The lifecycle event derived for the matched change (
trademark.created,
trademark.updated, trademark.status_changed, etc.). When an alert was
fired this is the frozen event type from the alert record; otherwise
it’s derived from the most recent change record.true if trigger_event_type is allowed by the watch’s
query.trigger_events filter. When false, the evaluator silently dropped
the candidate — that’s the answer to “why no alert”.The search relevance score at evaluation time, when applicable.
Currently always
null — the evaluator does not persist the per-trademark
score on the alert row. Documented gap; will populate on a future schema bump.The watch’s configured
query.score_threshold (0..1) for similarity
watches. null for non-similarity watches.true if an alert record exists for this (watch, trademark) pair.
When true, alert_id is the cross-system trace handle.Human-readable explanation for the outcome. Walked in this order:
"alert fired"— an alert row exists."watch does not include office {code}"— checkpoint missing/superseded."trademark evaluated more than {N} days ago; provenance no longer available"— past the diagnostic freshness horizon."trademark not in candidacy window for the most recent {office} sync run"— no recent change record."trigger event {type} not in watch.trigger_events"— change exists but the event type is filtered out."score {n} below threshold {t}"— similarity match below threshold (only fires when both are populated)."would alert but rolled into digest"— the watch’s effective delivery mode resolved to digest; alert is queued for the digest job."no matching reason available"— fallback; surface to support if you see it.
Resolved delivery mode using the same logic as the evaluator. For
digest_above_threshold this depends on the trailing 24h alert volume,
so the value is “current effective” not “effective at evaluation time” —
documented in the API contract. Since only always_per_alert watches can
be created today (digest modes are v1.1), in practice this is
per_alert or null.Best-effort classification of the per-(watch, office) evaluator lease.
held is unambiguous (active lease started < 15min ago);
epoch_raced indicates the evaluator’s last-seen epoch lags behind
the watch’s current epoch (replay race); released is the
default post-iteration state. abandoned / cas_lost are heuristic
hints, not guarantees.The watch’s current
evaluation_epoch. Bumped by POST /v1/watches/{id}/replay.When the alert was emitted under a replay-bumped epoch, this is the alert’s
frozen
evaluation_epoch. null when the watch was never replayed (epoch=0)
or no alert exists.The ingestion run referenced by the watch+office checkpoint’s
last_evaluated_sync_run_id.Public ID (
alt_*) of the alert that fired. Cross-reference against
alert_id on delivery audit rows under
GET /v1/webhooks//deliveries,
or retrieve the alert directly via GET /v1/alerts/{id}.
null when no alert fired.Computed opposition-window state for this trademark.
null when the
trademark has no publication_date_first or no rule applies for the
jurisdiction/route.Retention horizons for the data this endpoint reads. Past these horizons
the corresponding fields cannot be reconstructed and
reason will
surface “provenance no longer available”.Request identifier.
Errors
- 400 —
trademark_idquery parameter missing. - 403 — caller lacks
portfolios:manage. - 404 — watch does not exist, belongs to another org, the trademark does not exist, or this trademark is out of the watch’s office scope and no alert was ever produced for the pair. The endpoint deliberately does not distinguish between these cases (info-disclosure prevention).
Retention
Change records are retained for 90 days; delivery audit records for 30 days. Diagnostics queries past the 90-day horizon returnevaluated=false
with reason explaining the freshness limit.
Authentication
Standard API key viaAuthorization: Bearer $SIGNA_API_KEY. Org-scoped:
the watch must belong to the calling org.
See also
- Troubleshooting guide — walkthrough of the diagnostics → webhook-deliveries debug flow.
- List webhook deliveries
— pair
alert_idfrom this response with the delivery audit log to confirm webhook receipt.