Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.signa.so/llms.txt

Use this file to discover all available pages before exploring further.

Choosing a watch type

The five watch types correspond to the five monitoring jobs we hear trademark teams talk about. Pick the type whose required filter is the narrowest fit for what you actually want.
You want to…watch_typeRequired field
Track one specific mark you own (renewals, status drift).markfilters.trademarkIds (single ID)
Watch an entire portfolio of marks at once.portfoliofilters.trademarkIds (1+ IDs)
Track a competitor by owner.ownerfilters.ownerId
Watch new filings in a Nice class (or class set), optionally by jurisdiction.classfilters.niceClasses
Detect confusingly-similar new filings (phonetic / fuzzy / combined).similarityq (text)
Every watch’s query body is the same shape as a GET /v1/trademarks search body — if you can build the search, you can save it as a watch. The watch_type is the predicate; the filters carry the scoping.

The query DSL (v1)

Every watch carries a query object:
interface WatchQuery {
  version: 'v1';
  q?: string;                          // optional keyword query (required for similarity)
  filters?: SearchFilters;             // trademarkIds, ownerId, niceClasses, jurisdictions, ...
  trigger_events?: WatchTriggerEvent[];
  score_threshold?: number;            // similarity only, 0..1
}
filters uses the canonical search vocabulary: trademarkIds, ownerId, niceClasses, jurisdictions, offices, statusPrimary, etc. See the trademark search reference for the full set.

q keyword constraints

  • Whitespace-separated. Max 20 keywords. Each ≥3 chars.
  • Stop words (the, and, or, …) are rejected with 400 to keep watches from matching too broadly.

trigger_events

Subset of trademark.created, trademark.updated, trademark.status_changed. Default: all three. Narrow this down to silence noisy update events that don’t matter to you.

score_threshold (similarity only)

For watch_type: "similarity", this gates which match scores fire alerts. Only matches with _score >= score_threshold produce alerts. 0.7 is a reasonable starting point; tighten to 0.85 for production opposition workflows. Use Preview to estimate volume before going live.

Per-jurisdiction watches

Build separate watches per jurisdiction when you want jurisdiction-specific delivery cadence, or when your in-house legal team is sliced by region. Otherwise pass filters.jurisdictions: ["US", "EU", "GB"] once and let one watch cover the set.
await signa.watches.create({
  name: 'Apple Inc — class 9 worldwide',
  watch_type: 'owner',
  query: {
    version: 'v1',
    filters: {
      ownerId: 'own_apple_inc_uuid',
      niceClasses: [9],
      jurisdictions: ['US', 'EU', 'GB', 'CA'],
    },
  },
});

Worked examples

Mark watch (one trademark)

await signa.watches.create({
  name: 'My core mark — status changes',
  watch_type: 'mark',
  query: {
    version: 'v1',
    filters: { trademarkIds: ['tm_01HK...'] },
    trigger_events: ['trademark.status_changed'],
  },
});

Portfolio watch (many trademarks)

await signa.watches.create({
  name: 'Q4 acquisitions portfolio',
  watch_type: 'portfolio',
  query: {
    version: 'v1',
    filters: { trademarkIds: ['tm_01HK...', 'tm_01HK...', 'tm_01HK...'] },
  },
});

Class watch

await signa.watches.create({
  name: 'New class-9 filings in US/EU',
  watch_type: 'class',
  query: {
    version: 'v1',
    filters: { niceClasses: [9], jurisdictions: ['US', 'EU'] },
    trigger_events: ['trademark.created'],
  },
});

Similarity watch (with threshold)

await signa.watches.create({
  name: 'Marks similar to ACME — opposition watch',
  watch_type: 'similarity',
  query: {
    version: 'v1',
    q: 'ACME',
    filters: { niceClasses: [9, 35] },
    score_threshold: 0.85,
  },
});

Forbidden DSL keys

The validator rejects function_score, script_score, script, sort, cursor, aggregations, aggs, highlight anywhere in the query (VAL-API-005). These are presentation/scripting concerns that don’t belong in a saved monitor. The validator also rejects query.match as an object — earlier versions of these docs showed match: { owner_id, trademark_id, nice_classes }, which was never honored by the evaluator. Use filters.ownerId, filters.trademarkIds, and filters.niceClasses instead.

Replay

If you create a watch retroactively (or the data backfills late), use POST /v1/watches/{id}/replay to bump evaluation_epoch. Requires the watches:admin scope.

Bulk

Create up to 100 watches in one call via POST /v1/watches/bulk. The whole batch validates upfront — partial failures don’t insert.

Pre-flight with Preview

Before creating a watch, dry-run the query:
const preview = await signa.watches.preview({
  query: myQuery,
  trial_window_days: 30,
});
console.log(`${preview.estimated_match_count} alerts in last 30 days`);
This uses the same evaluator code path as creation (VAL-API-011), so the count is faithful. If you see thousands, your query is too broad — tighten filters or score_threshold before going live.