Skip to main content
POST
Compare Marks
Alpha, internal testing. Compare is not open to customers yet, and the risk bands are still being calibrated. These endpoints run on internal and design-partner keys during internal testing and their request and response shapes can still change. Email support@signa.so to join the early access list. Compare returns an informational comparison, not legal advice or a registrability determination.

Overview

Screening finds possible conflicts for a candidate. Compare scores pairs you already chose: one candidate against 1–10 register records or inline marks. Each request-ordered result includes the same coarse risk-band vocabulary used by served screening, plus numeric string, phonetic, and goods/services measurements. Compare does not return an overall or confusion-probability score. The endpoint is synchronous and deterministic within the reported rule, mapping, resolver, and corpus versions. Each request is billed at 10 units, regardless of the number of conflicts (up to 10). Optionally supply an Idempotency-Key; retrying the same body with the same key replays the original response without billing the comparison again.

Request

Supply the candidate either as an existing trademark_id or as an inline { mark, use } object. Each conflict is either a trademark_id or an inline { mark, nice_classes, goods_services?, status? } object. These alternatives are mutually exclusive.

Response

comparison_status, risk levels, and match levels are closed vocabularies. reason_codes, data[].warnings, and comparison.warnings are open vocabularies; tolerate new values. matched_levels names engine clauses for the pair. Screening calls its corresponding post-sensitivity-gate field admitted_match_levels; Compare has no sensitivity admission gate. similarity.semantic is reserved and currently always null. review_recommended is true exactly when the comparison succeeded and at least one mark-similarity clause fired. It deliberately includes dead-mark and below_screening_band pairs: it is a conservative human-review triage bit, independent of risk_level. summary.review_recommended counts those results. An unknown conflict ID degrades to not_found. A conflict whose database record exists but cannot be compared, because it is design-only or its search document is still being indexed, degrades to not_comparable; index lag is reported in that item’s warnings. The other batch items still succeed. The The five risk/status buckets in summary count every requested conflict exactly once; review_recommended is an additional, overlapping count.

Error codes

Compare can return insufficient_use_profile when the candidate’s intended use cannot be resolved, batch_too_large when more than 10 conflicts are supplied, or not_screenable when a candidate trademark has no screenable mark text.

Why can risk_level be null?

An ok comparison has no band only when no mark-similarity clause fired. Those pairs count in summary.none:

Suggest → screen → compare

Use classification suggestion to turn plain English into classes, screening to find candidates, then Compare to inspect a selected pair. This sequence uses jq to pass results between calls:

Intent-to-use candidates

You do not need to know the Nice system before comparing a proposed mark. Describe the planned business in ordinary language, call Suggest Classifications, review its ranked classes, then place those class numbers and the original description in candidate.use. Compare resolves that intent into the effective classes echoed in comparison.candidate.effective_nice_classes before scoring every pair.

SDK

Limitations

  • Compare v1 is text-only; it does not compare logos, designs, or images.
  • Numeric dimensions are measurements beneath the band, not a legal conclusion or an overall confusion probability.
  • The band table is under active recalibration.

Compare vs Screening divergence FAQ

Compare and Screening use the same mark and goods/services levels. Compare must never return a less alarming band for a pair that the equivalent broad screen surfaced. A few differences are expected because Screening searches a corpus while Compare evaluates a chosen pair.

Why can Screening say medium when Compare says high?

Screening can demote a weak or crowded mark using corpus-wide evidence that a pair-only comparison cannot see. The Screening hit then includes weak_mark_demoted or crowded_field. Compare deliberately gives the more conservative reading, and it can be only one band higher.
What to do: treat Compare’s higher band as the conservative pair reading; retain Screening’s strength reason codes in your audit trail.

Why does Compare score a pair that default Screening did not show?

Compare evaluates every match tier. Screening defaults to standard, while a fuzzy_2-only match is admitted only at broad sensitivity.
What to do: use sensitivity=broad&include=all when validating Screening against Compare.

Why does a Madrid-family result change when I add a jurisdiction?

Madrid families can contain both live and dead territories. An unscoped call uses family-wide liveness; a scoped call evaluates only the requested territories. Passing a jurisdiction to one surface but not the other therefore changes the record state being evaluated.
What to do: pass the same jurisdictions (and offices, when used) to both calls.

Why can Compare score an identical mark in an unrelated class?

Supplying nice_classes to Screening is a retrieval hard filter, so a record outside those classes is never surfaced. Compare does not use class as a retrieval filter: it evaluates the supplied pair and an identical, live mark in an unrelated class can score medium.
What to do: omit the Screening class filter when you need discovery across all classes, then use Compare for pair-level class context. The response disclaimer is authoritative: This comparison is informational, not legal advice or a registrability determination; the band table is under active recalibration.