The four window states
State transitions happen on every data update that touches the office. A mark published Friday afternoon and crossing into
critical the following week requires no extra scheduling in your application.
If the mark moves into a status that ends the window early (for example abandonment), opposition_window_status flips to closed on the next sync that observes the change.
Severity routing
severity is automatically escalated based on the window state, which makes it easy to page on-call only when a window is genuinely close to closing.
Worked example: USPTO publication
A new mark publishes in the USPTO Trademark Official Gazette on 2026-04-15. In the US, the standard opposition window is 30 days from publication.must_act_by is the latest moment to file, end of day in the office’s local timezone, ISO 8601.
Madrid designations: which publication starts the clock
A Madrid designation has two publications that can fill one date field. WIPO publishes the international registration in its Gazette of International Marks, and the designated office republishes the designation in its own journal. The two are routinely months apart, and offices run their opposition clock from different ones. Feed a rule the other office’s date and you get a plausible-looking date that is not the statutory bar. Each Madrid rule declares which publication it needs.POST /v1/oppositions/compute accepts an optional publication_date_kind on each item saying which one your date is:
DE runs from the WIPO Gazette like FR and CH. AU, CA, EU, SG and US all run from their own journal like GB, FI, PL and NO.
When the kind you send and the kind the rule needs disagree, the response is
status: "unknown" with null dates, rather than a date you should not act on. The item stays supported: true and keeps its rule_id, office_code, trigger_event and citation, so you can see exactly which rule declined — and a reason of publication_date_kind_mismatch says why. A window that is date-less merely because there was no publication date leaves reason as null, so the two are distinguishable on the wire.
Sending unknown is treated the same way. It is not a way of declining to answer: it is a positive statement that you looked and the source did not establish which publication the date is, and an adjudicated Madrid rule refuses an unestablished provenance exactly as it refuses a wrong one — same status, same reason.
Omitting the field entirely is the only value-free option, and nothing changes. Every caller written before the field existed keeps its current behaviour.
The same reason field, with the same vocabulary, is on derived.opposition_window in GET /v1/trademarks/{id}, so a stored record that declines reports it too.
Coverage
Opposition rules are wired for 28 jurisdictions: AU, BR, BX, CA, CH, CN, DE, DK, ES, EU, FI, FR, GB, IN, IS, IT, JP, KR, MX, NO, PH, PL, SE, SG, TH, TR, US, VN. Twenty of them carry a separate rule for Madrid designations alongside the domestic one: AU, BR, CA, CH, CN, DE, ES, EU, FI, FR, IN, IT, JP, KR, MX, NO, PL, SG, TR, US. That is 48 rules in all. The remaining eight carry a domestic rule only; a Madrid designation into one of those offices returnsopposition_window_status and must_act_by as null until its Madrid rule ships. GB is the deliberate hold: the rule is not written rather than guessed, because the current UK Journal source is not available to pin. There is no standalone WIPO rule, because an opposition always runs in the designated office under that office’s own rules.
The full registry is available via GET /v1/opposition-rules.
For marks in jurisdictions without a wired rule, opposition_window_status and must_act_by are both null.
When must_act_by is not calendar-verified
must_act_by is the statutory close after the office’s holiday calendar has been applied. What varies is whether a pinned closure list stands behind that year. Several calendars are built from an annual office notice (China’s State Council holiday notice, India’s DoPT memorandum, the Philippine presidential proclamations, Mexico’s IMPI acuerdos, the WIPO non-working-days notice), so a window closing in a year whose notice is not yet published is not calendar-verified and reports not_checked. Signa still applies the deterministic roll to it, weekends plus the fixed holidays the calendar computes from the law, so the date may have moved. A notice can only add closure days, so the true close is the same or later: such a date is correct-or-early, safe to act on, never a reason to file late.
Alerts carry the marker. Every alert reports deadline.must_act_by_adjustment alongside deadline.must_act_by, on GET /v1/alerts, on the alert detail, and in the signed webhook body. It is the value frozen at emit time, so it describes exactly the date that alert carries, not a fresh recomputation that may have moved since. null on alerts emitted before 23 September 2026, and on alerts with no opposition window; treat null as “no marker was recorded”, never as “verified”.
The same field appears as close_adjustment on GET /v1/watches/{id}/diagnostics, on POST /v1/oppositions/compute, and on the derived.opposition_window block of a trademark.
Monitoring and the index agree on the unverified band
There is a ~20-day band immediately after an unverified close where a closure day the notice adds could legitimately still have kept the window open, so the true state is unknowable from the data Signa holds. Both the search index and the watch evaluator resolve that band the same way: they serve the deterministically rolled close withnot_checked rather than declining to answer.
That matters because the evaluator freezes must_act_by onto the alert. Before 23 September 2026 the evaluator declined in that band and emitted the alert with no must_act_by at all, on precisely the marks whose deadline was nearest, while the index for the same mark carried the close, so the two surfaces disagreed about whether the mark had a window. They now agree: you get the date, plus must_act_by_adjustment: "not_checked" telling you it is correct-or-early and must not be diarised as final.
Search and compute can disagree for 20 days after an unverified close
One deliberate divergence, worth knowing before you reconcile two surfaces against each other. Anot_checked close was not verified against a pinned closure list, and a closure day the notice adds could only ever push it later, so for the 20 days after it the true state is genuinely unknown.
- Search treats those 20 days as open.
GET /v1/trademarksand the search index bucket a mark whoseclose_adjustmentisnot_checkedinto the open-window filters until 20 days past the baked close, so a window that may still be live is not filtered away from an opposer. POST /v1/oppositions/computereportsstatus: "closed"for the same window on the same day, because it answers strictly against the served, unverified date.
close_adjustment first: if it is moved, unchanged, or month_end_overflow the close is calendar-verified and both surfaces agree. (month_end_overflow means the close fell on a month-end overflow, so it moved to the first business day of the following month, and the calendar was consulted.) If it is not_checked and the close is within 20 days, treat the window as possibly still open and confirm with the office.