October 11, 2026: screening coverage classes, usage summary window, calendar office codes
Screeningcoverage.classes names the classes searched.
GET /v1/screening can match classes from
your goods_services text and search them too. coverage.classes.resolved
now lists the classes matched from nice_classes plus goods_services;
searched is the class filter applied by the class-filtered retrieval lanes
(the containment lane, which finds marks that contain the name, is not
class-filtered); and expanded lists the classes searched adds beyond
requested. Before, a screen with nice_classes=16 and a coffee description
searched classes 16 and 30 but reported resolved: [16], searched: [16]
and expanded: []. Results, risk levels and verdicts are unchanged.
Usage summary rows match billing_period. Without start_date and
end_date,
GET /v1/organization/usage/summary
and the MCP get_usage_summary tool now list rows for the same window as
billing_period: the current plan period, from the moment it started, the
same period as credits_used. A period that started mid-day has a first row that
starts at billing_period.start and holds only the spend after it. Before,
an organization whose plan renewed mid-month got rows from its billing anchor
day, including spend from the previous period, next to the new period’s
credits_used.
Calendar feed office codes. The portfolio deadlines calendar (.ics) names
the office by its public code (US, EM), as the JSON deadline rows do. It
said USPTO.
October 11, 2026: TypeScript SDK 0.22.0; MCP proceedings filters and compact results
MCPlist_proceedings takes every filter of
GET /v1/proceedings:
party name (q), party_role, filed_date_gte/filed_date_lt,
decision_date_gte/decision_date_lt, contested_class and aggregations,
so an agent can ask for oppositions against a company in a date range.
Cursors are bound to the new filters too. An unknown status,
proceeding_type or party_role now returns validation_error; before, an
unknown status or proceeding_type returned an empty page that read as “no
proceedings”.
MCP results are compact JSON, without indentation, so tool results cost
agents fewer context tokens. The content is unchanged.
TypeScript SDK 0.22.0 types everything the API added since 0.21.0: the
deadline row numbers and warnings (on SignaList, so horizon_truncated
reaches SDK users), office_class, the owner, attorney and firm trademark
filters the API already accepted (sort, goods_services_text and more), the
filing_route aliases on the rule catalogs and the designation_date filters.
trademarks.search() sends request bodies up to 64 KB. Install it with
npm install @signa-so/sdk@0.22.0 once it is on
npm.
October 11, 2026: API contract fixes
OpenAPI contract. The spec now matches what the API sends:request_idis optional on the four publicly cached single responses (GET /v1/offices/{code},/v1/jurisdictions/{code},/v1/classifications/{classNumber},/v1/design-codes/{code}). They leave it out so a shared cache never hands one caller’s id to another; the cached lists already said so. Clients that validate responses against the spec no longer reject these.- Fields the API already sent are now declared:
created_atandupdated_aton proceedings,revoked_aton API keys, andattorneyswithattorneys_has_moreon firm detail requested withinclude=attorneys.
GET /v1/deadline-rules accepts
direct_national (read as national), direct_regional (as regional), and
madrid_ir and madrid_designation (as madrid).
GET /v1/opposition-rules accepts
direct_national and direct_regional (as domestic). The other trademark
values (transformation, divisional, unknown, and madrid_ir on
opposition rules) still return 400 with the accepted list. The rule values
keep working.
Credit pricing. The read row of
GET /v1/credits/pricing
is per_request, which is how it is billed: one record, or one page of a list
such as /v1/owners/{id}/trademarks. It said per_record. POST /v1/trademarks/batch, billed per submitted identifier, including the ones
returned in not_found, carries unit: "per_record"
on its endpoint entry. The rate limits page now
shows a real RateLimit-Policy header, with both limits it lists.
Swedish office links. office_url is null on Swedish (SE) trademarks,
in detail, search and coverage rows. The link Sweden’s office used to serve
(was.prv.se/VarumarkesDb) now ends at a page that does not exist.
Deadline rows name the mark’s numbers. Rows of
GET /v1/deadlines and
GET /v1/portfolios/{id}/deadlines
carry application_number, registration_number and ir_number, so rows of
marks with the same name can be told apart and the rows of one international
registration’s designations grouped. The
calendar file puts the number in each
event’s title and adds a URL link to the office record when the office serves
one. A deadline already in its grace period is placed on the grace period’s
last day, so its alarms are still ahead; before, it sat on the passed due date.
Long lines are folded at 75 octets as RFC 5545 requires, and the calendar is
named <portfolio name> deadlines.
Deadline horizon warning. Deadlines are computed five years ahead. A
due_before later than that on
GET /v1/deadlines or
GET /v1/portfolios/{id}/deadlines now
returns warnings with a horizon_truncated entry naming the horizon date;
before, the rows past the horizon were missing without a word.
Coverage and billing period times. coverage_through on
GET /v1/monitoring/status and on watch
health is never later than the time of the response. Offices that publish
whole days used to read “covered through the end of today” hours before the day
ended. GET /v1/organization/plan and
GET /v1/organization/usage report the same billing_period as
GET /v1/organization/usage/summary:
for an organization on credits, the window of its current plan credits, which
is when they reset. Before, the plan and usage endpoints gave the anchor day at
midnight.
Classes as the office states them. Each entry of classifications on
trademark detail carries
office_class, the class as the office states it. A row with no Nice class now
says what it is: US A and B (certification marks for goods and for
services), US 200 (collective membership marks) or Spain’s 00. It is null
on an international registration’s classes rolled up from its designations.
October 11, 2026: status counts add up, and France has a pending pipeline
Every stats count now sorts status stages into buckets from one table, so each status stage lands in exactly one bucket and the buckets add up to the total. Before, some stages were in no bucket.- Pending includes the opposition period.
opposition_periodrecords were in no bucket. They now count aspending. France’s office analyticspending_countgoes from 1 to about 41,700, and market and classby_status.pendingrise by the same records. - A pending cancellation is still registered.
pending_cancellationrecords (about 3,800, all EUIPO) were in no bucket. They now count asregistered, since the mark stays on the register until the cancellation is decided.registered_countand the grant rate change for the owners, attorneys and firms that hold them (including the per-firm grant rate onGET /v1/firms/{id}/attorneys), and for the EUIPO office (registered_count,registration_rateand theregisteredyearly trend). - New
unknown_count. Records whose status stage isunknown(about 913,000, mostly WIPO and USPTO) now have their own count:unknown_counton office analytics, on the owner and attorneystatsobject, and on the analyticsportfolioblock, and next toby_statuson market and class analytics, where it isnulluntil those stats are next recomputed. With it, the bucket counts sum tototal_marks(office, market, class), tomark_count(portfolio), or to the records counted (owner and attorney stats). - Attorney, firm and entity
active_countrise. They now countopposition_periodandpending_cancellationmarks as active, as owneractive_countalready did. The analyticsportfolio.active_countdoes the same, soactive_count,dead_countandunknown_countadd up tomark_count.
October 11, 2026: EU legs read EU everywhere; every country filter matches every spelling
Follow-up to “filters that match nothing now say so” below, so the same spellings behave the same on every endpoint.- Deadlines of EU legs. The WIPO record of a Madrid designation of the EU
(stored by WIPO as
EM) already readjurisdiction_code: "EU". Its deadline rows now readEUtoo:derived.next_deadlineandderived.deadlines.itemson trademarks,GET /v1/deadlines, portfolio deadlines,POST /v1/deadlines/compute(the item and its rows) and the reconcilecomputedcontext. Trademark and portfolio ETags change once. - Webhooks. The
trademark.status_changed,trademark.correctedandoffice_action.issuedpayloads carryjurisdiction_code: "EU"for that record, where they carriedEM, and so doestrademark_event.territory_codeonoffice_action.issued(andterritory_codeonGET /v1/trademarks/{id}/events). This is the same territory written the way the trademark row writes it, not a new meaning, sopayload_versiondoes not change. Events and deliveries stored before the change readEUtoo:GET /v1/events/{id}, automatic retries andPOST .../redeliverall serveEU(the stored copy keepsEM). - Compute jurisdiction.
jurisdictiononPOST /v1/deadlines/computereadsEMasEU,UKasGBandWIPOasWO, as/v1/deadline-rulesdoes, and the item answers with the code it was read as.UKandEMused to answerunsupported_jurisdiction. A code that is neither a country code nor known to the deadline rules (XX,ZZ) now fails only its own item, as an unknown ID does: adeadline_computation_errorwithid: nullanderror.codeunknown_jurisdiction_code, while the other items are computed.deadline_computation_error.idcan therefore benull. A real country with no modeled rules still returnsunsupported_jurisdiction. - Country filters.
owner_countryon trademark search and on the owner, attorney, firm and entity trademark lists,country_codeon/v1/entities,/v1/attorneysand/v1/firms, and a watch’sfilters.ownerCountry(and the same filters on the MCP tools) now match every spelling, ascountry_codeon/v1/ownersdoes:EUandEMboth match records stored under either, as doGBandUK.owner_country=EUused to miss the owners stored asEM. Any two-letter code is accepted, an empty value is no filter, and a value that is not two letters returns400 unknown_country_code. - Trademark jurisdictions.
jurisdictions=UKon trademark search, the party trademark lists, image search,/v1/screening, listing screening,/v1/compareand the MCP search tools is read asGBinstead of returning400(or matching nothing), andWIPOasWO.jurisdictions=EMstill returns400pointing atoffices=EM:EMis EUIPO’s office code, andjurisdictions=EUalready matches the EU legs WIPO stores asEM. - Watches.
filters.jurisdictionsreadsEMasEU,UKasGBandWIPOasWO(["EM"]used to fail withno_live_office). Stored watch queries are not rewritten, but evaluation and preview now treatEUandEMas one territory: a stored watch withjurisdictionsEUand WIPO in its offices may now alert on WIPO’s records of EU designations, which it missed before.filters.ownerCountrymust be a two-letter country code or a list of them (400 unknown_country_codeotherwise); an empty value is no filter, and a value a stored watch already holds is accepted on edit. Creating, previewing or editing a watch with an owner, attorney or firm ID that was merged into another now returns400naming the surviving ID to watch (owner own_X was merged into own_Y; watch own_Y). A merged ID a stored watch already holds is still accepted when you edit the watch, but that watch does not alert on the merged ID’s marks whileWATCH_MERGE_FOLLOWis off (the default): point it at the surviving ID. - Cursors. A list cursor issued before this change for a request with a
country_codeorowner_countryfilter returns400 cursor_expiredonce, because the filter now resolves to every stored spelling; restart from the first page. search_meta.warnings[].codenow documentsall_words_requiredandmulti_word_retry_skipped.
October 10, 2026: no restoration for Madrid designations, and nothing past an expired mark’s last renewal grace
Two corrections to maintenance deadlines onPOST /v1/deadlines/compute,
the deadline lists, derived on trademark records and
POST /v1/reconcile. Both remove rows
that were served in error, and one case gains a row: a live Madrid designation in its
renewal grace now also shows its next international renewal, which the removed
restoration row used to hide. On affected records derived.term,
derived.expiry_date and derived.next_deadline change with them.
- Madrid designations get no national restoration window. A designation
of Japan, the UK, Singapore, India or Iceland was served a
restorationrow (jp_restoration,gb_restoration, …) after its renewal grace. Those remedies restore a national renewal, and a designation renews only at WIPO: Japan’s Trademark Act Article 68-22(1) and the UK’s International Registration Order 2008 disapply them for designations, and Singapore’s International Registration Rules, India’s Trade Marks Act section 36E(4) and Iceland’s Regulation 850/2020 do not extend them to designations. A cancelled designation is now served nothing (for example IR 2015-03-10, term end 2023-07-19: the row running 2024-01-19 to 2024-07-19 is gone), and an expired one only the international renewal while its six-month grace is open. National registrations keep their restoration windows. InGET /v1/deadline-rulesevery restoration rule now hasapplies_to: "domestic", sofiling_route=madridno longer returns them. Because no restoration row follows the grace any more, a live designation inside its grace period is shown the next international renewal, as designations of other countries already were. - An expired mark owes nothing past its last renewal grace. Once the
grace period of an
expiredmark’s latest renewal whose window has opened has passed with no renewal on record, no row due after it is served, with or without a statedexpiry_date. Before, a Philippine mark registered 2010-01-15 and expired was served, as of 2025-06-01, a declaration of use due 2026-01-15 for the fifth anniversary of a renewal that never happened. A renewal whose window is open is still served, and a renewal on record keeps the next term’s rows. On compute, an expired national mark with no renewal on record no longer lists the Philippine fifth-anniversary declaration inunsupported_rules.
October 10, 2026: POST /v1/trademarks accepts bodies up to 64 KB
POST /v1/trademarks
accepts request bodies up to 64 KB, up from 8 KB, so an exclusion list of the
documented 1,000 trademark_ids now fits in one search. Before, a body over
8 KB (about 190 ids) got a 413 before it reached the API. A GET query
string is still limited to 2 KB (403), so send long lists by POST.
October 10, 2026: lien releases cited in their text pair with their lien; owner list drops the redacted placeholder; related owners page fully
Lien releases. Assignments gainrelease_match on
GET /v1/assignments,
GET /v1/assignments/{id}
and GET /v1/trademarks/{id}/assignments:
pointer when a release cites the security interest’s reel/frame, and null
otherwise (always null for other conveyance types). A release now also cites
a security interest when its text names the reel/frame (RECORDED AT R/F 1234/0567, REEL 1234/FRAME 0567, REEL NO. 1234 FRAME NO. 0567) and the
release covers one of its marks; before, only the release_of_* fields
counted. Owner and entity analytics
(GET /v1/owners/{id}/analytics,
GET /v1/entities/{id}/analytics)
unreleased_security_interests and marks_with_liens use the same pairing, so
both counts drop where a release cites its lien only in its text. Most USPTO
lien releases cite no reel/frame, so these two counts can still include liens
that were in fact released: only releases that cite their security interest are
paired. Pairing uncited releases by lender, borrower and mark is planned. New recordings described with these
citation forms, in the plural (“release of liens and security interests”), as
“release by secured party” or as a bare “security agreement” are now classified
as releases and security interests; recordings stored before this change keep
their type for now.
Owner list. GET /v1/owners no
longer leads with “Redacted applicant (PRV #2)”, the placeholder Sweden’s office
uses for applicants whose names it redacts. Placeholder owners are left out of
the owner list, owner search and suggestions, as the docs already said.
GET /v1/owners/{id} still answers for
a placeholder owner, because the Swedish trademarks it holds link to it.
Related owners. GET /v1/owners/{id}/related
returns every relationship when paging. A related owner with two relationships
(for example the direct and the ultimate parent) used to lose one of them at a
page boundary. A cursor issued before this change returns
400 cursor_expired; restart from the first page.
October 10, 2026: screening no longer clears non-Latin marks; real coverage figures; compare flags self-comparisons
These changes apply to the alpha screening and compare endpoints.- Non-Latin marks need review.
GET /v1/screeningmatches Latin text, but a mark written mostly in another script, such asНАЙКor耐克, could come backclearbecause nothing matched. When a mark’s non-Latin letters, all scripts together, outnumber its Latin letters, the screen now reportscoverage.language.supported: falseand the main script incoverage.language.detected, and a would-beclearbecomesneeds_reviewwith theunsupported_languagewarning. Accented and fullwidth Latin letters count as Latin. Found conflicts still band as before. Because the verdict gate changed for these marks, theirscreening_idchanges too; screens of Latin marks keep their ids. - Coverage figures.
coverage.horizonreportedanalyzed: 0andcap: 0on every screen. It now gives the conflicts analysed and the cap (200).cappedistruewhen the overall horizon or a retrieval lane’s quota had more matches than it could analyse. Atrademark_idscreen sent withoutnice_classesorgoods_serviceslists the record’s classes it searched incoverage.classes.resolvedandsearchedinstead of empty lists.coverage.lanesis reserved and stays empty. - Self-comparison.
POST /v1/compareadds aself_comparisonwarning to a result whosetrademark_idconflict is the candidate record or another record in its Madrid family. The risk level is unchanged.
October 10, 2026: owner, attorney and firm search lists the real name first
q on GET /v1/owners,
GET /v1/attorneys and
GET /v1/firms returns its matches in a
new order. Before, a name that was only close to the query (a longer word that
starts with it, a typo, two names run together) could rank above the party you
searched for: q=nike on owners listed “nike”, “NIKEL” and “nikema”, with no
trademarks, ahead of NIKE, Inc. Now a name that contains every word of the
query gets a boost for its trademark count and ranks above typo matches, so
among those names the party with more trademarks ranks higher. A name with a
longer word that starts with the query can still rank high. Typos still match,
lower in the list.
The new order applies when sort is not sent. An explicit sort orders the
matches by that field, as before, and so do owner searches with ticker, lei,
publicly_traded or has_lei, which order matches by trademark count. One kind of match is gone on every order: a
query word with a typo has to be close to a whole word of the name, and no
longer matches a name that only starts with a similar word.
A cursor issued before this release for a q list without sort can skip or
repeat rows; start that walk again from the first page. The reference pages
described q as a trigram or substring search. They now describe what it does.
October 10, 2026: filters from other endpoints return 400 instead of being ignored
A filter an endpoint does not support used to be ignored, so the answer looked filtered when it was not:GET /v1/analytics/market?offices=US returned the
worldwide totals and GET /v1/deadline-rules?office=EM the whole catalogue.
- Filters from other endpoints. A GET request with a query parameter the
endpoint does not support, when that parameter is a filter on another
endpoint (
offices,office,jurisdiction,q,status,nice_classes, and so on), returns400with codeunknown_parameter. The message names the parameter this endpoint has for it, if any:deadline-rules?office=EMsays to usejurisdiction. - Common spellings. A few spellings no endpoint uses are rejected the same
way:
country,nice_class,queryandtrademark_ids. watch_idonGET /v1/alerts. It never filtered that list; it now returns400pointing atGET /v1/watches/{id}/alerts.- Still ignored. Paging and shaping parameters (
limit,cursor,include_total,sort,order,fields,include,format,language,page,per_page,offset) and other names no endpoint uses. Endpoints that already rejected unknown parameters,/v1/trademarksincluded, behave as before.
October 10, 2026: filters that match nothing now say so
Several filters matched nothing, with a 200, for a value that only differed in spelling or case from one Signa knows, or that was no code at all. These requests now return400 validation_error with a hint, or are read the way you
meant them.
New 400 responses:
- Jurisdiction codes.
jurisdictionon/v1/deadline-rulesand/v1/opposition-rulesreturns400for a value that is not a country or jurisdiction code, such asZZorUSPTO. A real country with no data still returns an empty list, and historic Madrid designation codes the rules cover, such asYUorSU, keep working.jurisdictions=ZZon trademark search also returns400:ZZis internal and was never a jurisdiction you could search.country_codeon/v1/ownersreturns400only for a value that is not two letters; historical codes owners carry, such asDDorSU, keep working. - Fee catalog.
GET /v1/fees?office=returns400for a value that is not an office or country code (XX,JPO). Other offices and countries still return an empty list. - Event types.
event_typeonGET /v1/trademarks/{id}/eventsandGET /v1/eventsreturns400for an unknown type, listing the valid ones.
- Office spellings of a jurisdiction.
EMis read asEU,UKasGBandWIPOasWOinjurisdictionon/v1/deadline-rulesand/v1/opposition-rules.deadline-rules?jurisdiction=EMused to return only the Madrid renewal rule; it now returns the EU rules too.GET /v1/fees?office=UKnow returns the GB fees. - Owner country.
country_codeon/v1/ownersis case-insensitive and matches every spelling owners are stored under:EUandEMboth return the owners recorded as either, as doGBandUK. - Event type case.
event_typeis case-insensitive:Renewalmatchesrenewal. - EU legs of Madrid marks. With
territory_match=direct,jurisdictions=EUnow also matches the WIPO record of a Madrid designation of the EU, which WIPO stores asEM. That record’sjurisdiction_codenow readsEUin every mode and on trademark detail, as territory codes already did, and thejurisdiction_codeaggregation and the party analyticsjurisdiction_spreadcount it underEU.
- Every
validation_errornow carries anerrorsarray. An error that is not about one field has a single entry with field(request). - A misspelt parameter on an endpoint that rejects unknown parameters gets a
suggestion:
stautssays to usestatus_stage. - A trademark number used as a trademark ID (
GET /v1/trademarks/73120444) points atGET /v1/trademarks?q=73120444.
search_meta.warnings includes partial_owner_country_coverage
when you filter by owner_country and EUIPO records are in scope. EUIPO
publishes no owner country, so the filter matches no EUIPO trademark and EU
trademark counts are missing from the result.
Because the EU leg’s jurisdiction_code changed with no write to the mark,
trademark and portfolio ETags change once: a client holding an older validator
gets the new body with a 200 instead of a 304.
October 10, 2026: near_identical means about the same length; fewer look-alike rows for Cyrillic and Greek names
match.tier on GET /v1/trademarks
read near_identical for a one-letter difference or a strong sound-alike even
when the mark had more words than q: q=BRANDX labelled MARLON BRANDO and
BRANDX ACTIVEWEAR near_identical. Such a match is q inside a longer mark,
and is now similar, as the tier table says. Each name of a q list is
measured against its own word count. Ranking and the rows returned are
unchanged; only the label moves.
The same tier gates watches: a watch with min_tier: near_identical no longer
alerts on a mark that matches only this way, and alerts carry the new tier. A
watch with min_tier: similar or weaker is unaffected.
A q written only in Cyrillic or Greek letters, such as Кока-Кола, no longer
runs the look-alike matches that allow a changed letter. Those matches folded
the whole name into Latin letters and returned unrelated marks (KODA LUNA, KOGA
PACE) as near_identical. Whole-mark look-alike matches still run (ВОТОХ written in Cyrillic still
finds BOTOX), and a name that mixes Latin with Cyrillic or Greek letters keeps
every look-alike match. Watches match the same way: an existing watch whose q
is written only in Cyrillic or Greek letters stops alerting on marks it reached
only through those matches, without being re-saved.
Because these searches return different rows, search_meta.ranking_version is
now v13, and a search cursor issued before this release is rejected once with
400 cursor_invalid: restart that search from its first page.
October 10, 2026: batch and reconcile find numbers written with separators; one IR number format
POST /v1/trademarks/batch and
POST /v1/reconcile now find numbers
written the way docketing systems export them. A number that finds nothing as
sent is tried again with spaces, commas, periods, slashes and hyphens removed
(and a leading WO removed from a batch ir_number), when what is left is a
number: 73/273,292, 1,201,370 and WO1874500 find 73273292, 1201370
and IR 1874500, where they used to come back in not_found. A record stored
with the separators still wins. On reconcile with verdict_detail: true,
lookup.identifier_normalization is separators_removed when this happened,
and lookup names the numbers looked up. A batch application number that more
than one record shares now always answers the same record.
ir_number on trademark rows (search, list, detail, batch and every party’s
trademark list) and on assignment properties is now always the international
registration number without leading zeros. USPTO, EUIPO and CIPO records of a
Madrid registration used to show it as stored (0551089) while the WIPO rows
showed 551089, so linking them by string equality failed. If you stored the
zero-padded value for a US designation, match on the new value; the ir_number
filters accept both forms, as before.
Because the value changed with no change to the records, the trademark detail,
portfolio and assignment ETags change once: a cached copy revalidates into a
200 with the new value.
October 10, 2026: search says when a name of several words found little
Aq of several words on GET /v1/trademarks
generally requires its words to appear in the mark, so
q=stone lion capital does not find LION CAPITAL. Such a
search that returns fewer than 5 rows in all now carries an all_words_required
warning in search_meta.warnings (not with the phonetic channel, which also
finds marks sharing one sound-alike word), with a ranked list of shorter phrases to send
instead (q=["stone lion","lion capital"]). When Signa skips its second search
for a multi-word name with no results (one that allows a one-letter difference
in each word) because the first took too long, the response now carries
multi_word_retry_skipped instead of saying nothing. Results are unchanged.
The search docs and the MCP search_trademarks description now explain the
rule.
October 10, 2026: reconcile no longer counts an empty register field as a mismatch
POST /v1/reconcile: a field the office
does not publish at all now comes back with match: null instead of
match: false, and it no longer counts toward mismatch_count or turns
result into mismatch. That is the expiry and renewal due date at USPTO,
which publishes neither, and the renewal due date at most other offices. A US
mark sent with expiry_date or renewal_due_date used to read mismatch on
every item, and now reads match when everything else agrees. A field the
office does publish but this record lacks, such as the registration number of a
pending application, is still match: false. match on fields[] is now boolean | null. With
verdict_detail: true, field_verdicts still gives Signa’s computed date for
those fields.
October 10, 2026: watch previews apply every filter; dead watch settings are rejected
Preview. On a busy office, a watch without a text query used to report every changed mark at the watched offices: a US class 25 watch, a class 46 watch and a watch on a made-up owner all previewed 167,817 withestimate_basis: "candidacy_upper_bound". Such a watch is now previewed like a
text watch, with its filters as the search, so classes, owners, statuses and
trigger_events apply. The count is exact, or estimate_basis: "lower_bound"
when more than 10,000 marks matching the filters changed in the window.
candidacy_upper_bound remains only for a watch scoped by offices or trademark
IDs alone, or a time budget that ran out. When the search backend is down, such
a preview returns 503 service_unavailable (retryable), as a text watch already
did, instead of an unfiltered count.
New 400 responses on create, PATCH, bulk create and preview:
- a
filters.niceClassesentry that is not a class from 1 to 45 (fieldquery.filters.niceClasses[i]). A class sent as a numeric string, such as"25", is still accepted and stored as the number25; - a
filters.ownerId,attorneyIdorfirmIdthat is not a non-empty ID string, names no record, or names an owner Signa has retired.
PATCH that sends the stored value back is
accepted. A watch whose stored Nice classes include a value outside 1-45 now
shows status: "degraded" with invalid_filter in its health.issues.
Merged owners, attorneys and firms. Support for a watch to follow an owner,
attorney or firm that is later merged into another record ships disabled: it is
being rolled out behind a switch, and until it is on a watch matches the marks
of the ID it names. The stored watch keeps the ID you saved either way.
Diagnostics names a merge, with merge follow not enabled while it is off.
Bulk create. A failed batch lists every failing item in one 400, and each
errors[].field starts with the item’s index (watches[2].query.q). Before,
only the first error came back, without an index.
Diagnostics. reason now says when the change predates the watch, when the
watch is paused (with the cause: paused, out of credits, or disabled) or has
not evaluated the change yet, when a watched owner was
retired, and otherwise mark did not match the watch query or filters (naming
a merged owner, attorney or firm).
It no longer returns no matching reason available. An unknown trademark_id
on your own watch returns a 404 that names the trademark, not the watch.
Attestation. In the month a watch was created, an office with no
evaluations shows its gap from the watch’s creation, not from the start of the
month, so the attestation no longer records a lapse before the watch existed.
This changes content_hash for those periods. A period that ended before the
watch was created, with no evaluations recorded in it, returns
422 period_before_watch.
October 10, 2026: Madrid renewal deadlines for zero-padded IR numbers
Some offices store an international registration number with leading zeros (0921642), while WIPO stores it without (921642). Signa missed the WIPO
registration for those designations, so their renewal deadlines were anchored
on the designation’s own date, or not computed at all. They now anchor on the
international registration date, like every other Madrid designation. This
changes the derived deadlines on trademark detail, batch and search
responses, the deadline endpoints, portfolio deadline lists and calendar
feeds, and /v1/reconcile for the affected designations: a few dozen EUIPO
and CIPO records.
October 10, 2026: documentation corrected where it could lead to a wrong legal read
No API behavior changed. These pages stated something the API does not do, or left out a limit that changes how to read a value:- US Section 71 deadlines. The guides named
protection_grant_dateas the trigger for US Madrid Section 71 and Section 15 deadlines. Signa computes them fromregistration_date. On the USPTO’s own 79-series record that is the date of the certificate of extension of protection, the date 15 U.S.C. 1141k sets for Section 71. A US designation row from WIPO’s records carries the date WIPO recorded instead, so docket from the USPTO record. With Compute Deadlines, send the certificate date asregistration_date. See Deadline rules. - Compute Deadlines
operative_date_basis. The office action fact’soperative_date_basiswas described as defaulting tocaller_supplied. It is required and has no default; omitting it returns400. - US proceeding outcomes. Most ended US (TTAB) oppositions and cancellations read
outcome: other, so a US win rate, includingwin_rateon owner and entity analytics, covers only cases decided on the record. The opposition guide, Search Proceedings and the analytics pages now say so. - Watch preview. The quickstart showed an exact count for a US class watch that the preview could not produce then: on a busy office it reported every changed mark at the watched offices. Since the same day’s preview change (see the entry above), preview applies the class filter there too, and the quickstart shows that. See Watches.
- Record fields.
filing_basesare the bases as filed; later changes are not reflected.legal_formis a normalized value (US LLCs map tocorporation), not the form as filed.figurativemarks can contain words in stylized lettering. - Search. The USPTO publishes no expiry date, so
expiry_date_*never matches USPTO records, andrenewal_due_date_*matches only USPTO Madrid extensions (79-series) carrying the international renewal date, never a domestic Section 8 or 9 date. A name written as one word (cocacola) does not find it split by punctuation inside a longer mark (COCA-COLA ZERO); search each spelling, or sendmark_text_containswithoutq. - Analytics and liens. Office, market and class counts are trademark records, one per office record: a Madrid international registration counts for its own record, for each designation record, and again for any national office’s own record of a designation (such as a USPTO 79-series record). The office
registration_rateis not reliable forGB. An unreleased lien can be a released one whose release cites no reel/frame.citation_issuedcan follow a final refusal whose text Signa has not extracted yet. - Portfolios. Managed marks count on the daily monitoring meter, free during the beta.
October 10, 2026: office_action.issued fires only for USPTO examiner actions
For USPTO marks, office_action.issued now fires only when the office issues
an action, for example a non-final or final refusal, a suspension letter or
inquiry, an examiner’s amendment or a post-registration audit action (63 USPTO
codes in all). Before, 206 other USPTO codes that the office files under the
same heading could raise it too: your own filings (a voluntary amendment or a
response received), transactions with WIPO such as a grant of protection,
suspension checks, abandonment notices and decisions on petitions (grants,
denials, dismissals). A docketing system that opens a response deadline per event would
have opened one for each.
Those rows still appear on GET /v1/trademarks/{id}/events with the same
event_type. An abandonment still raises trademark.status_changed. Other
offices are unchanged.
October 9, 2026: US deadline corrections
Five corrections to US deadlines. All of them apply to every response from today, on trademark detail and search (derived), GET /v1/deadlines,
portfolio deadlines and the calendar feed, POST /v1/deadlines/compute and
POST /v1/reconcile.
- WIPO records of US designations no longer show Section 71 or Section 15
deadlines. A WIPO record designating the US (
office_code: "WO",jurisdiction_code: "US") showedus_madrid_declaration_of_use_s71_first,us_madrid_declaration_of_use_s71_at_renewalandus_madrid_declaration_of_incontestability_s15dated from the WIPO registration date. The law runs them from the date the USPTO issued its certificate of extension of protection, which only the USPTO’s own record of the designation carries. Where the US is the home office of the international registration there is no US designation at all. These records now show no rows for those rules and list each of them inunsupported_ruleswith the new reasoncomputed_on_office_leg. The USPTO record of the same designation keeps its rows, dated from the US registration date. If you imported these rows from WIPO records, remove them and use the USPTO record’s rows instead. - Supplemental Register registrations no longer show Section 15. The
Section 15 declaration of incontestability is not available on the
Supplemental Register (15 USC 1094), so
us_declaration_of_incontestability_s15no longer appears for a US registration whoseregister.typeissupplemental.POST /v1/deadlines/computetakes an optionalregister_type(principalorsupplemental) for the same result. - Extended response and statement of use deadlines are counted from the issue date. An extended Office action response deadline now runs six months from the Office action issue date, and each statement of use extension runs from the notice of allowance (37 CFR 2.62(a)(2), 2.89), so extended dates that landed after a short month move 1 to 3 days later, to the correct date. For example, an Office action issued 30 November 2025 and extended is due 1 June 2026, not 28 May 2026.
- Maximum dates move off weekends and federal holidays. A deadline that
reaches its maximum (the six-month response limit, the 36-month statement of
use limit) on a Saturday, Sunday or federal holiday is now due on the next
open day (37 CFR 2.196), with
due_date_adjustment: "moved". Before, it was served on the closed day withnot_checked. For example, a refusal of a Madrid designation sent on 25 June 2026 is due 28 December 2026, not on Christmas Day. - An unrenewed US registration shows its term ended. When a US
registration’s renewal (the combined Section 8 and Section 9 filing) is not
on record and its six-month grace period has passed,
derived.term.statenow readsrenewal_not_on_recordandderived.expiry_dateis the term end that passed, instead ofin_termwith the next ten-year renewal. The next cycle’s renewal row is no longer shown. This applies only when Signa has the registration’s USPTO prosecution history, that history records at least one Section 8 or Section 9 filing (such as the six-year Section 8; a Section 15 filing does not count), and the USPTO status does not say the registration was renewed. For a past computation date, only filings and a status dated by then count. The USPTO keeps such a registration “registered” until it cancels it, usually within a few weeks; Signa’sstatuskeeps the office’s value until then.
October 8, 2026: an attorney’s firms come from its filings
An attorney’s firm and address are now what its filings say.GET /v1/attorneys/{id} gains
firms: the firms named on the attorney’s current filings, with id, name,
trademark_count (the attorney’s trademarks filed with that firm) and
latest_filing_date, most trademarks first, at most 20 (the firm in firm_id
is added when it ranks lower).
firm_id and firm_name on the attorney detail, and firm_name on
GET /v1/attorneys, are now the firm
on the attorney’s most recent current filing (by filing date) that names a
firm, null when none does. Before, they were the firm on whichever filing
first created the attorney record, which could be a firm the attorney filed
with once, years ago: an attorney with thousands of filings could show a firm
named on three of them. firm_id and firm_name on the detail are deprecated
in favour of firms.
address on the attorney detail is the address on the attorney’s most recent
current filing that carries one, null when none does. For WIPO, Sweden and
Italy attorneys, whose older filings were stored without an attorney address,
the address the office holds for the representative is shown when no filing
address is on record.
GET /v1/attorneys?firm_id= lists the attorneys with at least one current
filing that names the firm, so an attorney appears under every firm its filings
name. Searching attorneys by q also matches the names of every firm on their
filings once the attorney search index has been rebuilt, which follows this
release; until then q matches the attorney’s name.
The firms and the address are recomputed with the nightly statistics, so a
filing that changes them shows up the next day.
October 10, 2026: a listed GLEIF ultimate parent passes its ticker to subsidiaries
An entity now inherits a listed company’s ticker when GLEIF reports that company as its ultimate parent, even when its direct-parent chain never reaches a listed company. Before, only the direct-parent chain counted, so an IP-holding subsidiary whose direct parent is an unlisted holding company carried no ticker. For example, NIKE INNOVATE C.V., which holds about 1,960 Nike marks, did not matchticker=NKE.
What changes for such an entity:
- Entities. Retrieve Entity shows a
listingblock withstatus: "subsidiary_of_listed", the ultimate parent’s ticker and LEI,publicly_traded: true, and the ticker intickers.ticker=on Search Entities and Search Owners, andpublicly_traded=trueon Search Entities, match it. - The direct chain still wins. When the direct-parent chain reaches a listed company, that company stays the listed ancestor.
- The newest ultimate parent counts. GLEIF reports one ultimate parent at a time. When older ultimate-parent records are still present, only the most recent one is used: if it is not listed, the entity gets no inherited ticker. If two or more different companies share the most recent start date, the entity gets none.
- Timing. Listing data refreshes with the weekly GLEIF update, so these entities change after the first weekly refresh following this release. Entity search and detail, and owner search and detail, show the change the same day. The
owner_tickerandowner_publicly_tradedfilters on trademark search and on watches follow within about a week, when the weekly public-company check refreshes each affected trademark. - Unchanged. Entity Family and
include_familystill follow direct parent and subsidiary edges only.
October 8, 2026: a filing shows only the firm it names
A trademark’s attorney now shows the firm named on that filing, and no other. Before, when a filing named no firm, Signa filled in a firm the same attorney was named with on some other filing. That borrowed firm could be a firm the attorney had never filed this mark through, so trademarks, search results and firm totals credited marks to the wrong firm. What changes:- Trademark detail and batch.
attorneys[].firm_idandfirm_nameare the firm the filing names, andnullwhen it names none.attorneys[].addressis the address on the filing, andnullwhen the filing has none. WIPO, PRV (Sweden) and Italian records never carry the address on the filing, so they keep showing the attorney’s address on file. - Madrid international registrations. The detail lists an attorney once
per firm its designations name, each row with the
territory_codesof the designations naming that firm. Designations that name the attorney with no firm get their own row withfirm_id: null; they no longer take another designation’s firm. - Search. The
firm_idfilter and facet match only filings that name the firm.attorney_firm_namematches the firm name the filing states for its first (primary) attorney. - Watches. A watch filtered by
firm_idorattorney_firm_namematches fewer marks once the search index is rebuilt: only the filings that name the firm. - Firm totals.
trademark_count,active_countand the other counts on/v1/firmsand/v1/firms/{id}count the filings that name the firm.attorney_countcounts the attorneys on those filings. Firms credited through borrowed firms drop sharply: a firm that showed 5,031 trademarks can now show 3. A firm that no filing names has no counts. - Firm attorneys.
GET /v1/firms/{id}/attorneysandGET /v1/firms/{id}?include=attorneyslist the attorneys with at least one current filing that names the firm. Each row’strademark_count,grant_rateandlatest_filing_datecover the filings naming this firm, not the attorney’s whole portfolio, and the list is sorted by that count.firm_nameis this firm’s name.
attorneys[].firm_id, expect more null
values and smaller groups. A null firm means the filing names no firm. It
does not mean the attorney practises alone. Search results and firm counts
switch over after the next search rebuild and stats recompute.
This supersedes the firm-of-record fallback described on October 4 and
September 29.
October 7, 2026: renewal deadlines for Madrid designations without their own rules
A Madrid designation of a jurisdiction that has no deadline rules of its own now gets its renewal. That covers the EU designated through Madrid (WIPO’s codeEM), Russia, Ukraine, Austria and 93 more codes in Signa’s data, historic ones
such as DT, SU and YU included: about 3.2 million WIPO designation records,
2.1 million of them live. The EUIPO’s own records of Madrid designations of the
EU (EU on the Madrid route) take the same rule. One new rule_id:
madrid_designation_renewal, named “International Registration Renewal (Madrid
designations)” in the catalog.
The rule serves only codes WIPO designates: the WIPO Standard ST.3 codes of the
117 Madrid members (the EU as EM, Belgium, Luxembourg and the Netherlands as
BX), the territories the Protocol extends to (Curaçao, Sint Maarten, Bonaire,
Sint Eustatius and Saba, Guernsey, Jersey), and the historic codes WIPO’s
register still carries (DD, DT, CS, SU, YU, AN). Any other code,
UK or ZZ for example, stays unsupported_jurisdiction.
The designation renews with the international registration at WIPO. Renewal is
one payment there, it takes effect on the same date for every designation, and
a later designation ends with the international registration (Madrid Protocol
arts. 3ter(2), 6(1) and 7(1); Regulations Rules 30 and 31(2)). So the rule runs
10 years from the international registration date, or from the expiry WIPO
states, with a window opening 6 months before the due date, a 6-month grace
period against a surcharge, and due dates moved off WIPO’s closed days. Every
value cites the Madrid texts, the WIPO Guide or the EUIPO guidelines with a
verbatim quote and a pinned snapshot.
These records now carry derived.expiry_date, derived.term with its
grace_expiry_date, and the next renewal in derived.next_deadline. Before,
derived.deadlines read supported: false with
reason: "unsupported_jurisdiction" and derived.term.state read
not_applicable. The rule’s rows carry the designated jurisdiction’s code
(RU on a Russian designation). GET /v1/deadline-rules
lists the rule once, under WO, and also returns it for ?jurisdiction= any
code it serves.
Points to know:
- A Madrid designation of the EU, WIPO’s
EMrecord or the EUIPO’sEUrecord on the Madrid route, is not served the EUIPO renewal (eu_renewal) or restitutio (eu_restitutio): the EUIPO does not handle renewal of international registrations designating the EU. On the EUIPO’s records this changes the rule, the consequence (lapse_of_international_registration), the calendar (wipo_geneva, so a due date on a EUIPO-only closure day such as 1 May no longer moves) and drops the restitutio row. Both EU rules now readapplies_to: "domestic"in the catalog. EU trade marks filed at the EUIPO keep their dates; their rows’last_verifiedreads2026-10-07and the EUsourcesno longer list the Madrid Protocol citation that covered the designation case. - On the EUIPO’s records of Madrid designations of the EU, each renewal row’s
occurrence_keystarts with the newrule_id(madrid_designation_renewal:where it readeu_renewal:), so it changes once. The portfolio iCal feed builds its event UID from that key, so a subscribed calendar sees each such event replaced once: the old event removed and a new one added. Anyeu_restitutioevent is removed. POST /v1/deadlines/computeandPOST /v1/reconcileapply the same rule to the items you send.{"jurisdiction": "EU", "filing_route": "madrid"}now returnsmadrid_designation_renewalwhere it returnedeu_renewal(and noeu_restitutiorow), and a Madrid-route item codedRU,EMor any other served code is nowsupportedwhere it readreason: "unsupported_jurisdiction". The prosecution half (facts[]) is unchanged: an EU Madrid item keeps the EUIPO provisional-refusal rule (euipo_madrid_oa_response), and a jurisdiction without its own rules still readsunsupported_jurisdictionfor every prosecution type, with nostated_deadlinerow served.- The schedule is the renewal only. Cabo Verde, Cambodia and Mozambique also
require use declarations filed with their national office (WIPO Information
Notices 27/2022, 11/2016 and 37/2016), which are not computed; every row of
such a designation says so in its
note, naming the notice. - A designation whose status stage is
unknown(about 143,000 of these WIPO records, 49,681 of them Jersey) is served like any other record, with one exception: it is not credited a later expiry WIPO published for its international registration, because that renewal may have left it out. It keeps the term WIPO states for it, lapsed or not. On 7 October that held back 211 records whose family showed a later term. The same now applies to Madrid designations in jurisdictions with their own rules (16 records on 7 October). - A designation that WIPO reports refused, invalidated, surrendered, cancelled
or expired past its grace gets no later renewal. One with neither an
international registration date nor a stated expiry returns
reason: "requires_office_date". National records of these jurisdictions, and every other jurisdiction that has its own rules, are unchanged.
ruleset_version on derived changes once, so trademark detail and portfolio
ETags change once on deploy. Maintenance rows are computed per request and need
no reindex.
October 6, 2026: Portugal (INPI) deadline rules
New jurisdiction.PT now has a maintenance config, so GET /v1/deadline-rules,
POST /v1/deadlines/compute and the derived block on a trademark answer for
Portuguese marks. Two new rule_id values: pt_renewal, pt_renewal_madrid.
Renewal runs 10 years from the FILING date (Código da Propriedade Industrial
art. 247.º), with the fee due in the last 6 months of the term and a 6-month
window after it against a surcharge; missing both ends the right (arts. 368.º
n.º 6-7 and 36.º). That is pt_renewal, for national marks. A Madrid
designation of Portugal has no Portuguese term to renew: the international
registration is renewed at WIPO, so pt_renewal_madrid runs the same 10 years
and 6-month windows from the international registration date (Madrid Protocol
arts. 6(1) and 7(1), Regulations Rule 30(1)) and moves off WIPO’s closed days.
Every value cites the Code, the Madrid texts or the INPI service page it comes
from, with a verbatim quote and a pinned snapshot.
Every Portuguese mark Signa holds today is a Madrid designation, about 78.7k
marks. They now carry derived.expiry_date, derived.term with its
grace_expiry_date, and the next renewal in derived.next_deadline. Before,
derived.deadlines read supported: false with
reason: "unsupported_jurisdiction" and derived.term.state read
not_applicable.
Two limits are documented rather than hidden. A national mark granted before
1 July 2019, when the current Code took effect, keeps the previous Code’s term,
which ran from the grant (Decreto-Lei n.º 110/2018 art. 7.º n.º 2), and the
text does not say whether its later renewals run from the filing anniversary or
from the end of that term. Until INPI clarifies the transitional rule, such a
mark, or one with no grant date filed before that day, returns
supported: false with reason: "requires_office_date" unless the office’s
term end is supplied. And no closed-day roll is applied to national dates: the
Code’s periods are continuous (art. 27.º), so every adjustment reads
not_checked. Madrid designations are affected by neither. See
Portugal (INPI): Marks Granted Before 2019-07-01.
ruleset_version on derived changes once, so trademark detail and portfolio
ETags change once on deploy. Maintenance rows are computed per request and need
no reindex.
October 6, 2026: class suggestion and goods and services on every plan
Suggest Classifications, Suggest Goods and Services and Validate Goods and Services are now available on Free. On a Free key,POST /v1/classifications/suggest, POST /v1/goods-services/suggest and POST /v1/goods-services/validate no longer return 403 plan_gated. Credit prices are unchanged: 10, 100 and 50 credits per request, spent from the plan’s monthly pool. Get Credit Pricing reports min_plan: "free" for all three.
October 5, 2026: rank many spellings in one search with a list in q
q on GET and POST /v1/trademarks and the MCP search_trademarks tool takes a list of up to 100 names, such as every spelling of a mark you are clearing. Each name runs through the same similarity channels in one search. A mark that resembles several names appears once, ranked by its closest name, and match.terms lists the names that found it. With include=match_details, match.details.terms gives each name’s own tier and channels.
- Look-alikes are found. With
lookalike,onyxalso finds 0NYX (a zero for the O). Before, a list inqwas an alias ofmark_text_is, an exact filter, and missed such marks. - Limits. Up to 100 names when
similarityis onlyidenticalandlookalike. Withfuzzy,embeddedorphonetic, including the default, up to 10 names and 30 words in total. More than 100 names returns400withcode: too_big. More than 10 names or 30 words with those channels returns400withcode: too_complex, naming the fix. - Same price. A list costs 10 credits per page, like any search.
- Not a number lookup. A list is never read as a trademark number; use Batch Retrieve.
- Pages are ranked across all names. A name with no hits on the pages you read is not proof that it is clear: page to the end, or search that name on its own.
- Owner, attorney, firm and entity
/trademarkslists take one search text; a list there returns400.
q without similarity now runs the default channels, so a list over 10 names returns 400 until you add similarity=identical,lookalike, and its rows are ranked, with relevance_score. For an exact, letters-as-written filter over several spellings, send mark_text_is. A list with match=exact, starts_with, ends_with or contains returns 400. Cursors issued for a list before this change return 400 cursor_invalid.
Removed: match_explanation and matched_terms on results, and search_meta.strategies_used and search_meta.match. Read match and search_meta.similarity_applied. See the migration guide.
October 5, 2026: owner list ticker and lei match the owner’s detail
GET /v1/owners?ticker= and ?lei= now match the tickers and LEIs Retrieve Owner returns. Before, they matched only the owner’s own company matches, so an owner linked to an entity was missing from ?ticker= of the ticker its detail showed.
tickermatches any of the owner’s tickers: its own SEC tickers or, when it has none, its entity’s (the members’ SEC tickers and the entity’s listing ticker, which can be inherited from a listed parent). This is howGET /v1/entities?ticker=matches an entity. Thetickeron the owner’s detail is always one of them. Matching is case-insensitive.leimatches any of the owner’s LEIs: its own GLEIF LEIs or, when it has none, its entity’s (the entity’s own LEI and the members’ LEIs). Theleion the owner’s detail is always one of them. Matching is case-insensitive.- A ticker on a GLEIF record is not one of the owner’s tickers, as on detail, so it no longer matches
?ticker=. - An owner whose entity is no longer served (
GET /v1/entities/{id}returns 404) is matched on its own company matches only.
?publicly_traded= and ?has_lei= are unchanged: they read the owner’s own company matches, so for an owner linked to an entity they can disagree with the publicly_traded and has_lei its detail shows. No fields are added or removed.
October 5, 2026: MCP list_proceedings filters by party owner or entity
The MCP list_proceedings tool takes the party filters GET /v1/proceedings already supports: party_owner_id (own_...) returns proceedings where a party is linked to that owner, and party_entity_id (ent_..., alias entity_id) where a party is linked to any member owner of that entity. Validation matches REST: a malformed or wrong-type ID returns validation_error (or id_type_mismatch), an entity with more member owners than the cap returns entity_too_large, and an unknown entity returns an empty page. Parties without an owner link are not matched; use the REST q filter to match by name.
October 4, 2026: Deadline coverage for expired, cancelled and dead marks; reconcile names declined rules
-
Expired and cancelled marks name the rules they can still be served. A mark that has expired or been cancelled was registered, so a deadline that runs from the registration date (or, in Brazil and Mexico, the grant date) is owed when the mark’s status can still be served it. An expired mark is served any rule whose miss costs something while that rule’s window is open; a one-off declaration of a national mark (such as US Section 8, the Philippine third- and fifth-year declarations or the Mexican third-year declaration) closes before its term ends, so an expired national mark is not asked for its date, while a Madrid designation granted late in the term of its international registration still is. A cancelled mark is served only a renewal that opens a restoration window Signa models (EU, GB, IS, IN, JP, SG); of those renewals only Japan’s runs from the registration date, so a cancelled Japanese mark is the one that can lack it. With
include_missed: trueonPOST /v1/deadlines/compute, and always onPOST /v1/reconcile, both statuses also owe every rule whose missed cycle would be returned, provided some date the mark could carry would return its row as of the computation date (a US mark cancelled three years after filing owes no Section 8 or 9 date yet). A Mexican national mark registered before 10 August 2018 is never asked for its grant date for the third-year declaration, which covers later grants only; a Madrid designation still is, since its statement of grant can come years after its international registration. Before, such a mark with noregistration_dateorgrant_datewas reported assupported: true, and the rules it could not compute were not named. Now, when it owes such a rule and no rule can be computed, it readssupported: falsewithreason: "requires_office_date"onPOST /v1/deadlines/computeand inderived.deadlines, and it is listed inunsupported_marksonGET /v1/deadlinesand portfolio deadlines, as a registered mark with the same missing date already was. For example, the compute item{ "jurisdiction": "US", "status": "expired", "filing_date": "2010-01-04" }returnssupported: false. With"status": "cancelled"it stayssupported: truewith no deadlines, because the US models no restoration; add"include_missed": trueand it returnssupported: false, since its missed Section 8 and Section 9 cycles need the registration date. When some rule can still be computed, the mark stays supported and the owed rules it cannot compute are listed inunsupported_rules(and the mark inunsupported_marks). For example, a Philippine national mark with statusexpired, a filing date and no registration date listsph_renewal,ph_declaration_of_use_renewalandph_declaration_of_use_mid_renewal(and, withinclude_missed: true,ph_declaration_of_use_5yr, whose missed row would be returned). Send the registration date and those rules are computed; an office-stated expiry date anchors only the renewal. -
A mark whose status ends every obligation is never declined. An abandoned Australian direct mark filed before 1996, a withdrawn Singapore direct mark filed before 15 January 1999, and a refused Madrid designation with no international registration date read
supported: falsewithreason: "requires_office_date"on compute and inderived, whileunsupported_marksleft them out. They now readsupported: truewith no deadlines, like other abandoned, withdrawn, surrendered, invalidated or refused marks in a jurisdiction Signa models. A mark in a jurisdiction Signa does not model still readsunsupported_jurisdiction, and a refused WIPO international registration record keeps its renewal deadline, because a provisional refusal does not end the international registration. -
POST /v1/reconcilenames declined rules. Withverdict_detail: true,computednow carriesunsupported_rules, in the same shape as onPOST /v1/deadlines/compute: the rules that apply to the record but were declined because it lacks the date the statute anchors them on. For example, a Philippine Madrid designation with no statement of grant of protection listsph_declaration_of_use_5yr_madridwithmissing_field: "protection_grant_date". Before,computedsaidsupported: truewith no trace of the declined rule, and a docketed deadline for it could not be told apart from one with no matching occurrence. The field is additive and is[]when nothing was declined. See Reconcile.
ruleset_version on derived changes once, so trademark detail and portfolio ETags change once. No watch alerts or webhooks fire.
October 4, 2026: portfolio events include status corrections
When Signa corrects a status it published for a mark in one of your portfolios (for example a renewed mark shown as expired, or office records that reached Signa late and show the mark lapsing or a dead mark returning), you now receive a directtrademark.corrected event. No configuration change is needed:
- Webhooks. Every endpoint subscribed to
trademark.status_changedalso receivestrademark.corrected. The envelopetypeistrademark.corrected, so you can tell a correction from news.trademark.correctedis also accepted inenabled_eventson its own (corrections only). Your storedenabled_eventsdoes not change. - Events feed.
GET /v1/eventsliststrademark.correctedevents by default, and, as on webhooks,event_type=trademark.status_changedincludes them.event_type=trademark.correctedreturns corrections only. - Payload.
datais thetrademark.status_changedbody pluscorrection: { kind }, wherekindisstatusorlate_office_record. Seetrademark.corrected. - Watches are unchanged. A watch still receives
trademark.correctedonly when itstrigger_eventslists it.
TrademarkCorrectedData, TrademarkCorrection and TrademarkCorrectedEvent, and 'trademark.corrected' to WebhookEventType. A receiver with an exhaustive switch on the envelope type sees a new value.
October 4, 2026: firm counts follow the firm of record
Firm counts now count a filing under its firm of record.trademark_count, active_count and the other trademark counts on /v1/firms and /v1/firms/{id} count a filing for the firm named on it, else for the attorney’s firm. The firm_id filter and /v1/firms/{id}/trademarks use the same rule, but only on search documents built since it was added. Until the next full search rebuild, a firm’s trademark list can include filings counted for another firm and miss some counted for it, so its total can differ from trademark_count. attorney_count still counts the firm’s own attorneys: a firm whose attorneys file only under other firms of record keeps its attorney_count, with trademark counts of 0. The new counts appear after the next nightly stats run.
October 4, 2026: a linked owner’s ticker and LEI come from its entity
GET /v1/owners/{id} now serves a linked owner’s company facts from its entity, the way GET /v1/entities/{id} returns them. Before, owner detail combined only the members’ company matches. An owner could show another LEI, no ticker or publicly_traded: false while its entity showed the entity’s own LEI, a listing ticker and publicly_traded: true.
publicly_tradedandhas_leiequal the entity’s.publicly_tradedis alsotruewhen the entity is itself listed or is a subsidiary of a listed company.tickeris the owner’s own first SEC ticker. When it has none, it is the entity’sticker, which can be a ticker inherited from a listed parent.leiis the owner’s own first GLEIF LEI. When it has none, it is the entity’slei: the entity’s own LEI when set, else the first member LEI.companies[]lists the same matches, the owner’s own first.- When the entity was merged into another, the facts are the surviving entity’s. When the entity is no longer served (
GET /v1/entities/{id}returns 404), the owner reports only its own matches andcompanies_sourceisdirect. GET /v1/owners/{id}/relatedwalks the oneleithe owner’s detail shows: its own first LEI, else its entity’s. An owner with several LEIs of its own used to walk all of them, and an owner with none walked nothing.- Owners not linked to an entity are unchanged. The MCP
get_ownerandget_owner_relatedtools return the same values. See Retrieve Owner.
companies[] change, for example when its entity’s listing changes. No fields are added or removed, and no webhooks or watch alerts fire.
October 4, 2026: status corrections arrive as trademark.corrected; status basis relabels raise no alert
trademark.corrected, an opt-in watch trigger event, used to fire only when a retracted record reappeared. It now also carries status corrections, so watches that did not opt in are not alerted about old news:
- A status Signa corrects. When Signa fixes a status it published wrongly, for example a mark shown as expired that the office records as renewed, the status change arrives as
trademark.correctedinstead oftrademark.status_changedortrademark.updated. - Late office records. When office records reach Signa late and show a mark lapsing, or a dead mark returning, the change arrives as
trademark.correctedtoo. - Other changes in a correction raise no alert. Any other change Signa stores while correcting statuses or catching up on late office records, including marks Signa first learns of from late records, updates the mark but raises no alert.
- Status basis relabels raise no alert. A change that only relabels where a status comes from (
status.basis, for exampleofficetocomputed) no longer raises atrademark.updatedalert. The mark shows the new basis. - MCP. The
signa_alerts_listtool’sevent_typefilter now acceptstrademark.retractedandtrademark.corrected, likeGET /v1/alerts.
trademark.corrected to a watch’s query.trigger_events. For portfolio marks, corrections now also arrive as direct trademark.corrected events (see the entry above). No request or response fields change.
October 4, 2026: derived.term and no projected term past a lapsed expiry
When the expiry an office states had passed its grace period (and restoration window) with no renewal on record, derived.expiry_date showed the next cycle ten years on, with a renewal “due” then. A UK mark surrendered in 2014 with a 2024 expiry showed 2034; a French mark whose 2026-02-05 term ended in August showed 2036. The term on record now ends where the office’s record ends it, and a new block says where it stands.
- New
derived.termon trademark detail, batch lookup, search results, portfolio rows, watch previews and the MCPget_trademarktool:state(in_term,in_grace,in_restoration,renewal_not_on_recordornot_applicable),grace_expiry_date,restoration_expiry_dateandrenewed(whether a renewal on record began the term). See The term on record. derived.expiry_datestays at the office-stated term end once it has passed, while the mark can be renewed late or restored and, withterm.state: "renewal_not_on_record", after that. While a restoration window is open it is that date (it wasnull). A renewal the office recorded (including one recorded after the grace period), or for a Madrid designation (a national office’s record, IP Australia’s for example, or WIPO’s own) an expiry WIPO published for the international registration in a later term, moves it forward to the next term, which readsin_term. The rows of that designation keep the office’s own dates as their trigger.- No renewal is computed past such a term end.
derived.deadlines.itemsandderived.next_deadlinedrop the projected later cycles and the restoration of a cycle that never began. The same applies toGET /v1/deadlines, portfolio deadlines and the iCal feed,POST /v1/deadlines/computeandPOST /v1/reconcile, whose computedexpiry_dateis now the lapsed term end. - An office that reports a mark expired the day after its term ends (the UK office does) reads
in_grace, thenin_restoration, until those windows close. statusand the top-levelexpiry_dateare the office’s and do not change. A schedule with no office-stated expiry (every USPTO record) keeps the statutory term end.
ruleset_version on derived changes once, and every detail and portfolio ETag changes once (the block has a new key). No watch alerts or webhooks fire.
October 3, 2026: China Madrid opposition windows from 2027; Philippine and Mexican office closures
- China, Madrid designations: two months from the WIPO publication from 2027. CNIPA published draft transitional measures for the revised Trademark Law for comment on 28 September 2026. They are not in force yet. Under the draft, an international registration whose WIPO Gazette date is on or after 1 January 2027 gets the revised two-month opposition period counted from the publication. The draft does not say whether the current start, the first day of the month after the Gazette, survives, so
cn_opposition_madridserves those registrations the window both readings allow: it opens on the first day of the following month and closes two months after the Gazette date. For a Gazette date of 15 January 2027 the window is now 1 February to 15 March 2027, where it was 1 February to 30 April. Registrations published before 2027 keep three months from the first day of the following month. The shorter window is served first because a close that turns out early costs an opponent nothing, while one that turns out late costs the right. If the final measures differ, the rule follows them. OnGET /v1/opposition-rulesthe rule now haswindow_change_date: "2027-01-01",window_months: 2,window_starts_on: "day_after"and the new fieldwindow_opens_on: "first_of_following_month"(nullon every other rule), and the earlier era moved towindow_months_before: 3andwindow_starts_on_before: "first_of_following_month". The draft measures and the consultation notice are among its sources. See opposition rules. - Philippines: IPOPHL closed on 16 to 18 November 2026. Proclamation No. 1447 declares those days non-working in Metro Manila, where IPOPHL has its office. A Philippine opposition window that closed on 14 to 18 November 2026 now closes on Thursday 19 November 2026, with
close_adjustment: "moved". - Mexico: four IMPI suspensions of time limits. IMPI suspended all its time limits on 8 and 9 August 2024, 18 May 2026, 23 September 2026 and 25 September 2026, by notices in the Diario Oficial de la Federación. Mexican opposition windows and renewal deadlines that fell on those days now move to the next working day.
GET /v1/deadline-ruleslists the four notices among the Mexican sources.
ruleset_version on derived changes once, so trademark detail and portfolio ETags change once. Opposition windows stored in search for Philippine and Mexican marks are recomputed after this release, so for a short time search results can still show the earlier close. No watch alerts or webhooks fire.
October 3, 2026: proceedings party owner and entity filters return linked proceedings
Proceeding parties are now linked to owners. A party is linked to an existing owner when the marks in the dispute show which owner it is and the names match with the same company suffix. This covers USPTO, CIPO and IP Australia proceedings, and new proceedings are linked daily.party_owner_id,party_entity_idandentity_idonGET /v1/proceedingsreturn results. They match proceedings where a party is linked to the owner, or to any member owner of the entity. Combined withqorparty_role, every filter still has to match the same party.- Parties without a link are not returned by these filters. They include most Canadian and Australian opponents (they are matched only against the owner of the mark under challenge), a name that matches only without its company suffix, and a recorded name that lists several parties. Search with
qto match by name or for complete coverage. See Search Proceedings. parties[].owner_idon proceedings now carries the linked owner, reported as its current owner record (the surviving owner if it has since been merged), and staysnullfor a party without a link.- Owner and entity analytics count challenger disputes.
litigation.as_challengeron owner and entity analytics counts the disputes where a linked party is the opponent or petitioner, so it is no longer always0.proceedings_totalchanges with it.
parties[].owner_id is not fixed once set. No webhooks or watch alerts fire for link changes.
October 2, 2026: USPTO post-registration office actions get their response deadline
When the USPTO mails a post-registration office action on a Section 8, Section 71 or combined Section 8 and 9 filing, the mark now carries a deadline to respond. Before, the filing closed its cycle and nothing replaced it, so a registration that will be cancelled without a response within weeks showed its next renewal, years away, asderived.next_deadline.
- New row type
post_registration_oa_response(rule_id: "uspto_post_registration_oa_response"), due six months after the action or at the end of the filing period the action examined, whichever is later, moved off weekends and federal holidays. It appears inderived.deadlinesandderived.next_deadlineon trademark detail, batch lookup, search results and portfolio rows, onGET /v1/deadlines(newtype=post_registration_oa_responsefilter value), on portfolio deadlines and the iCal feed, onPOST /v1/deadlines/computefor stored trademark ids, and on the MCPget_trademarktool.occurrence_keyisuspto_post_registration_oa_response:<action date>:<action code>. - New optional
notefield on deadline rows. Present only when the record adds something the dates do not say: the action a response row answers (PRA8 2026-04-19), a “no response required” notice, or a prosecution history that could not be read. - The row closes only on explicit evidence: a response naming the action’s section, the office’s acceptance of the examined filing, or a cancellation of it. A notice of incomplete response reopens every row it could concern. If the response date passes with nothing on record, the row stays as
missed; the examined declaration or renewal row is not changed. Whether the registration was lost is read from its USPTO status. - When the record cannot settle the date (the examined filing is not on record, a notice of incomplete response has no action on record, or the action predates 2015), the row stays open on the earliest date Signa can defend, with a
noteto check TSDR. A served date never moves later. - An action still open more than a year after its response date, on a registration whose current status is registered, is treated as resolved by the USPTO: no row.
- On
POST /v1/deadlines/computefor a stored id,prosecution_deadlinesnow dates this rule from the stored history, andsupportreports it ascomputedinstead offacts_required.due_dateis six months from the action, as on caller-supplied facts, andeffective_due_dateis the date the row serves. A closed one carriesclosed_by: "response", or the new valueclosed_by: "acceptance"when the office accepted the examined filing, withclosed_by_fact_id: null(the closing entry is named innotes). GET /v1/deadline-rulesand the MCPget_deadline_rulestool list the rule. See USPTO post-registration office actions.
ruleset_version on derived changes once, so trademark detail and portfolio ETags change once. SDK clients with an exhaustive switch on type see a new value. No watch alerts or webhooks fire.
October 1, 2026: records from offices that are not live yet are no longer served
Signa ingests some offices before they go live.GET /v1/offices already left those offices out, but their trademark records were still returned. They are now absent everywhere a customer reads trademarks, until the office goes live and appears on GET /v1/offices:
- Search and list.
GETandPOST /v1/trademarks, in both grouped and expanded views, leave these records out of rows,pagination.total_countand aggregations. The same applies toGET /v1/trademarks/suggest, screening, image search, the owner, attorney, firm and entity trademark lists, and the MCP search and list tools. An office number or atm_id inqdoes not return such a record. - Lookups by id.
GET /v1/trademarks/{id}and itsevents,proceedings,assignments,documents,citationsandcited-bysub-resources return404.POST /v1/trademarks/batchlists the id innot_found.GET /v1/deadlines?trademark_id=,POST /v1/deadlines/compute,POST /v1/compareand screening bytrademark_idtreat the record as not found. The MCPget_trademark,batch_get_trademarks,get_trademark_eventsandget_trademark_proceedingstools answer the same way. - International registrations stay. A WIPO international registration is a record of a live office, so it is still returned with all of its designations, including designations of a country whose national office is not live yet. The national office’s own record of that designation is not returned on its own. Image search matches images by their own record’s office, so an international registration whose only image sits on such a national record is not found by image search.
- Unchanged.
offices=andoffice_codefilters naming an office that is not live still return400withunknown_office_code.jurisdictions=with such a country still returns the rights of live offices that protect it, such as EU trade marks and Madrid designations. Marks already in a portfolio stay in it, are listed, and keep their portfolio deadlines.
October 1, 2026: proceedings q matches the party you filter by; party owner filters return no results (superseded October 3, 2026)
- Behavior change. On
GET /v1/proceedings,qandparty_rolenow have to match the same party.q=Acme&party_role=opponentreturns proceedings where a party named Acme is the opponent. Before, it also returned proceedings where Acme was the respondent and anyone else was an opponent, so the list could include cases from the wrong side.qcombined withparty_owner_idorparty_entity_idfollows the same rule.qalone andparty_rolealone are unchanged. party_owner_id,party_entity_idandentity_idreturn no results today. Proceeding parties keep the name the office recorded but are not yet linked to owner or entity records, so these filters match nothing. They stay accepted. Search by name withq, which matches a case-insensitive substring of the recorded party name; it does not add related companies or subsidiaries. Search Proceedings and the opposition guide now useqin their examples. Superseded October 3, 2026: these filters now return proceedings whose parties are linked; see that entry.- The
party_roleaggregation still counts every role on the matching proceedings, soq=Acme&party_role=respondentcan show anopponentbucket: it counts the cases that had an opponent.
October 1, 2026: Australia, Norway, Sweden and Singapore show as covered on /v1/jurisdictions
GET /v1/jurisdictions, GET /v1/jurisdictions/{code} and the MCP list_jurisdictions and get_jurisdiction tools returned office_code: null and office_status: "not_covered" for AU, NO, SE and SG, although their offices are live on GET /v1/offices. They now return office_status: "live" with office_code AU, NO, SE and SG. ES now returns office_status: "roadmap", like the other offices that are planned. No other jurisdiction changed.
October 1, 2026: USPTO declarations and renewals on record close their deadlines
Deadlines for USPTO marks now read the Section 8, Section 15, Section 71 and Section 8 and 9 filings in the mark’s prosecution history. Before, a declaration the USPTO had already accepted was still served asin_grace and then missed, a US designation under the Madrid Protocol with both Section 71 affidavits accepted showed both as missed, and a renewal filed on time showed as in_grace.
- A filing made inside its window (from the day the window opens to the end of the grace period) closes that cycle on
derived.deadlinesandderived.next_deadlineon trademark detail, batch lookup, search results and portfolio rows, onGET /v1/deadlines(includingurgency=missed), onPOST /v1/deadlines/computefor stored trademark ids, on portfolio deadlines and the portfolio iCal feed, onPOST /v1/reconcileand on the MCPget_trademarktool. - The combined Section 8 and 9 renewal closes only when both parts are on record.
derived.expiry_dateand the term endPOST /v1/reconcilecompares against move to the next term only when the USPTO accepts the renewal, not when it is filed.- A Section 15 declaration whose window has passed is no longer listed as missed (
urgency=missed,include_missed). Section 15 is optional and can be filed after any later five-year period of continuous use, so nothing is lost. An open Section 15 window is still served. - A US designation ingested from WIPO’s records is not covered yet. See USPTO filings already on record.
ruleset_version on derived changes once, so trademark detail and portfolio ETags change once. No watch alerts or webhooks fire.
October 1, 2026: offices declare proceedings support; proceedings come only from those offices
Every office onGET /v1/offices, GET /v1/offices/{code} and the MCP list_offices and get_office tools now carries capabilities.proceedings: available when Signa ingests and serves the office’s oppositions, cancellations and appeals, in_progress when a pipeline is being built, and not_available otherwise. See List Offices.
GET /v1/proceedingsand the MCPlist_proceedingstool with anoffice_codefor a live office whosecapabilities.proceedingsis notavailablereturn422 capability_not_available, withcapability,capability_stateandoffice_codein the error. No query runs and no credits are charged. Before, such a request could time out, or return an empty list that looked like “this office has no proceedings”.- A
proceeding_typethat no served office records (todaycourt_action), or that the requestedoffice_codedoes not record, returns an empty page and emptyaggregationsbuckets straight away, charged as a normal page. Search Proceedings lists the types each office records. - The proceedings endpoints return proceedings only for offices whose
capabilities.proceedingsisavailable: theGET /v1/proceedingslist,GET /v1/proceedings/{id}(a proceeding from any other office is404),GET /v1/trademarks/{id}/proceedings, theproceedings_counton a trademark’s detail, and the MCPget_proceeding,list_proceedingsandget_trademark_proceedingstools. Two signals catch up after this release:aggregationscounts onGET /v1/proceedingsmay still include proceedings held for offices that are not live yet, until a follow-up backfill completes. The listed proceedings never include them.- Search and screening signals that come from the search index (the
has_proceedingsfilter, the ranking boost for marks with proceedings, and screening’s prior-proceedings and litigious-owner signals) apply the same rule to each mark when it is next indexed. Until then, an international registration whose only proceedings sit on a designation in an office that is not live yet can still matchhas_proceedings=true.
- The
GET /v1/officesandGET /v1/offices/{code}ETags change once, because the body gained a field.
October 1, 2026: any API key can connect to MCP
The MCP server at/mcp (and /mcp2) now accepts every valid API key and OAuth token, whatever its scopes. Before, a key needed one of read, search, trademarks:read, billing:read, portfolios:manage or admin to connect at all, so a key with only events:read got 403 and could not call signa_events_list or get_account.
initializeandtools/listwork for every session.tools/listreturns every tool, including ones the session can’t call.get_accountandget_credit_pricingwork for every key.- A tool the key lacks a scope for returns the
forbiddenerror REST returns (status403, naming the scope) with the call’srequest_id, and is not charged. - An invalid, revoked or expired credential still gets
401. Rate limits and the batch cap are unchanged.
October 1, 2026: deadline corrections for lapsed marks and Swiss, Polish and Norwegian opposition windows
-
A lapsed mark is no longer served a renewal ten years out beside its restoration window. Some offices keep a mark at
registeredfor months after its stated term ended. When the office states a term end that has passed and a restoration window is on the schedule,derived.deadlineson trademark detail,GET /v1/deadlines,POST /v1/deadlines/computeandPOST /v1/reconcilenow serve the lapsed renewal while it is in grace and the restoration window, but no later renewal cycle. After the grace period, and while the restoration window is open,derived.expiry_dateis null. The office’sstatusandexpiry_dateare unchanged. A mark the office has renewed, or whose stated term end is still ahead, is not affected. See Restoration periods. -
Switzerland: no opposition window before the Trade Mark Protection Act. Opposition in Switzerland exists since the Act commenced on 1 April 1993 (MSchG art. 79). A Swiss publication dated before that day, national or Madrid, now has no window instead of a three-month one. A national mark filed before that day has none either, whatever its publication date (MSchG art. 76(2)(c)); this needs the filing date, which trademark detail uses and which
POST /v1/oppositions/computereads fromfiling_date. - Poland: no opposition window before pre-grant opposition existed. Pre-grant opposition in Poland began on 15 April 2016 (Dz.U. 2015 poz. 1615 art. 3). A national publication dated before that day, or a national application filed before it (art. 2 ust. 1 of the same Act), now has no window instead of a three-month one. Madrid designations of Poland were already gated at that date.
- Norway: two months for registrations published before 1 July 2010. The repealed 1961 Trademarks Act § 21 gave two months from publication, so the window for a registration published before 1 July 2010 now closes one month earlier and cites that Act. Every window in that group closed years ago.
-
New reason
before_commencementonPOST /v1/oppositions/compute. When an opposition rule exists for the office but the item was published, or filed, before the date the rule applies from, the item now returnsreason: "before_commencement"with the rule’srule_idandeffective_from. Before, it readunsupported_office, which suggested no rule existed for the office. The same applies to rules that already had a start date, such as Vietnam’s and Mexico’s.unsupported_officenow means only that no rule exists for the office and route. Trademark detail is unchanged:derived.opposition_window.reasonkeepsunsupported_officefor these records.
GET /v1/opposition-rules shows the new applicable_from_date and effective_from values on ch_opposition, ch_opposition_madrid and pl_opposition, the era fields on no_opposition, and the added sources. ruleset_version on derived changes once. Trademark detail and portfolio ETags change once. Opposition windows stored in search for Swiss, Polish and Norwegian marks are recomputed after this release, so for a short time search results for those marks can still show the earlier window. No watch alerts or webhooks fire.
October 1, 2026: MCP search tools take date ranges and field projection
search_trademarks and list_trademarks now accept every date filter that GET /v1/trademarks has, in the POST range shape: filing_date: {"gte": "2024-01-01", "lt": "2025-01-01"}, and likewise registration_date, expiry_date, renewal_due_date, publication_date, status_effective_date, priority_date, first_use_anywhere_date, first_use_in_commerce_date, termination_date, updated_at and family_updated_at. They also accept fields and include, which project rows as on REST; id and object are always kept. Validation is REST’s: conflicting bounds or an unknown field return validation_error, and the call is not charged. include: ["match_details"] on list_trademarks adds match.details, as it does on GET /v1/trademarks. See MCP tools.
One REST change comes with this. On POST /v1/trademarks, a date range with no bound, such as "filters": {"filing_date": {}}, is now ignored like an absent range. It used to reach the search as an empty filter, which forced one row per record (an expanded_fallback warning) or returned 400 when international_registrations was grouped. A cursor from such a request now returns cursor_invalid; restart from the first page.
October 1, 2026: documentation corrected against the API
No API behavior changed apart from theharmonised_only parameter description. These pages said more than the API does:
- Freshness. Trademark detail reads were described as strongly consistent. They carry
Cache-Control: private, max-age=300, so a cached detail read can trail a write by up to five minutes, and they may be served from a database read replica. See Data Freshness. - Search depth. Not every search stops at 10,000 rows: a grouped request without
qpages by key, with no fixed depth. A position walk can repeat or skip a row when records change between pages, so deduplicate onid. See Search depth. - Harmonised terms.
is_harmonised: truemarks a term from a harmonised list (the EUIPO Harmonised Database, or a TM5-harmonised USPTO ID Manual entry). It does not mean every TM5 office accepts the wording; readaccepted_offices. Theharmonised_onlydescription onGET /v1/goods-servicesand the MCP tool now says the same. - Entity portfolios.
GET /v1/entities/{id}/trademarksreturns the marks of owner records linked to the entity, andinclude_family=trueadds GLEIF-reported subsidiaries. Neither is a complete-portfolio guarantee. - Trademark events. USPTO timelines include the office’s e-mail notifications as their own
office_actionevents; EUIPO timelines are publication events, not a lifecycle history. See Trademark Events. - Restoration rules. The EU’s restitutio in integrum rule (
eu_restitutio) is one of the restoration rules inGET /v1/deadline-rules; the reference listed only the others. - Guides no longer state jurisdiction counts for deadline and opposition rules.
GET /v1/deadline-rulesandGET /v1/opposition-rulesare the current lists.
October 1, 2026: a TTAB interlocutory order is no longer a proceeding’s decision
On US proceedings, an interlocutory order of the Trademark Trial and Appeal Board, such as a ruling on a motion to compel, suspend or amend, no longer counts as the proceeding’s decision: it sets nodecision_date or decision_outcome and does not change status or outcome. Before, such an order could be stored as the decision, so a proceeding that was still running showed a decision_date and a duration_days. Only orders recognised as interlocutory change. Every other TTAB ruling, including a summary judgment that sustains an opposition and an order that vacates a decision, is handled as before. Affected proceedings are corrected in place and their ETags change once.
October 1, 2026: owner and entity names show accented characters
Some owner names came from office feeds with HTML character references still in them, soŠKODA INVESTMENT a.s. showed instead of ŠKODA INVESTMENT a.s.. The API, MCP tools and webhooks now decode these references when they return a name:
owners[].nameon trademark rows and trademark detail.name,name_original_scriptandaliases[].nameon owners, and the names on/v1/owners/{id}/related.- Entity names, member names and family names.
- Attorney client names, proceeding
parties[].nameand assignmentparties[].name. trademark.owner_nameon alerts andalert.createdwebhooks, andsubject.nameon party analytics.
canonical_name is unchanged. trademark.status_changed event payloads keep owner_name as it was recorded. Stored records are not rewritten, so no webhooks or watch alerts fire.
owner_name filters, on search and on watches, find a record by its decoded name as well as by the name the office sent, including names where only some characters were escaped. Names escaped with other named references, such as ' or , may still need the name as the office sent it. owner_id stays the exact way to filter by owner.
ETags on trademark, portfolio, owner, attorney, firm, entity, proceeding and assignment detail change once, so a cached body revalidates to the decoded name.
October 1, 2026: MCP errors match REST; proceedings cursors are bound to their query
MCP tool errors now carry the same JSON error body as the REST API, plus the call’srequest_id. See MCP errors.
- A database statement timeout is
timeout(504, retryable). It used to read “invalid or malformed ID”. - A lost database connection, failover, or overloaded search cluster is
service_unavailable(503, retryable). - Any other server failure is
internal_errorwith areference_id. Database and search-engine messages no longer appear in tool results. - Invalid arguments and unknown tool names return
validation_errorandnot_foundbodies instead of plain text.errors[]names each field. - A
preview_watchthat runs out of time returnspreview_timeout(504), asPOST /v1/watches/previewdoes. get_accountworks for any key that can connect to MCP, not only keys withbilling:read. Withoutbilling:readit returns identity withplan: null.list_trademarksandlist_proceedingswith only blank filters (""," ",[]) returnvalidation_errorwithout running or charging.search_trademarks,list_trademarksand the party trademark tools reject an unknownstatus,status_stageor jurisdiction code instead of matching nothing.- A JSON-RPC batch of more than 10 messages in one POST is rejected with JSON-RPC error
-32600. - A body that is not valid JSON or not a JSON-RPC message, or a request with malformed method parameters, returns a fixed JSON-RPC error with
error.data.request_id, instead of the parser’s error text.
GET /v1/proceedings and list_proceedings cursors now carry the filters and sort that produced them. Reusing a cursor with a different filter or sort returns cursor_invalid, and an empty cursor returns cursor_expired. A cursor issued before this change is rejected with cursor_invalid; start the list again.
October 1, 2026: Benelux, Malta and OAPI member states resolve on /v1/jurisdictions
GET /v1/jurisdictions/NL and the MCP get_jurisdiction tool returned 404 for member states that jurisdictions= already accepts as a search filter. NL, BE, LU, MT and the 17 OAPI member states now resolve and appear in GET /v1/jurisdictions. Each has scope_type: "national", madrid_member: false and office_status: "not_covered": BOIP (BX) and OAPI (OA) are the register and the Madrid party for their members, and Signa does not connect to Malta’s register yet. See Retrieve Jurisdiction for how jurisdictions=NL and jurisdictions=BX differ on search.
October 1, 2026: opposition, proceeding status and owner corrections
Three data corrections. Records ingested from now on carry the corrected values; stored records are corrected by a backfill that follows this release. The backfill fires no watch alerts. A small number of records whose stored data we cannot fully verify may produce one update event on their next update from the office.- A mark in its opposition window is no longer reported as opposed. USPTO marks with status code
686(published for opposition), EUIPO marks withAPPLICATION_PUBLISHEDorSTART_OF_OPPOSITION_PERIOD, and INPI France marks inopposition_periodno longer carryopposition_pendinginstatus.challenges. An opposition that was actually filed still does (USPTO774and801, EUIPOOPPOSITION_PENDING). A USPTO request for an extension of time to oppose (802) is nowother_pending.status.stageis unchanged:pending_oppositionmeans published for opposition or opposed, and the stage alone does not tell you which. Checkstatus.challenges. - Proceeding
statusis no longer inferred where the office did not report it. For EUIPO, CIPO and IP Australia,statusis now an exact mapping of the office’s own label, still returned unchanged instatus_raw.- EUIPO:
CLOSEDisother, notdecided_rejected: the office reports that the case is closed but not who prevailed. Cases still running (RECEIVED,ADMISSIBILITY_CHECK,COOLING_OFF_PERIOD, and pending Board of Appeal or General Court cases) arepending.decision_datestays null for EUIPO proceedings. - CIPO:
Active,Pending,Awaiting Decisionand the appeal states arepending;Deemed Abandonedisdecided_granted;Closedisother.proceeding_numberis the office’s per-record sequence identifier (1, 2, …), not a Board docket number, and the API reference now says so. - IP Australia:
Consent court orderissettled, andExtension of time grantedisotherrather thandecided_granted. status.challengesfollows: a CIPO or IP Australia mark whose opposition or cancellation is nowpendingcarries the matching challenge, and one whose proceeding is no longerpendingdrops it.
- EUIPO:
- A live mark no longer loses its owners. An office update that arrived without owner data used to retire the current owners of a registered or pending mark, so it was served with no owner. A live mark now keeps its current owners in that case, and marks already affected get their owners back where our stored office data shows who the current owner is.
September 30, 2026: TTAB filing dates backfilled
filed_date is now set on about 99% of US oppositions and cancellations, historical dockets included, loaded from the USPTO TTAB bulk feed. filed_date_gte, filed_date_lt, sort=filed_date and the filed_year aggregation now count those TTAB dockets. Ex parte appeals do not carry a filing date yet, and decision_date is still set on only a small share of US rows; the proceedings pages say so.
September 30, 2026: party detail ETags change once
/v1/attorneys/{id}, /v1/owners/{id}, /v1/firms/{id} and
/v1/entities/{id} ETags change once. Stored attorney rows got their
country_code without a change to the row, so a client revalidating a cached
attorney body gets one 200 with the current country_code, then 304s
again.
September 30, 2026: a trademark number in q returns that record
Searching /v1/trademarks with a trademark number in q now returns the record the number names. Before, a US designation of an international registration (a 79-series serial such as q=79412883) returned no rows, and its US registration number returned the international registration’s family row instead of the US record.
- A number in
qreturns one row per record, each shown as on its detail page, with anidentifier_lookupwarning insearch_meta.warnings. - A labelled international registration number, such as
IR 1939139, returns one row for the international registration and its designations. - A bare number returns the records it names. Records whose own number is the searched number come first, such as an international registration and any national record with that number. Designations that only carry the international registration number follow.
- A
tm_ID of a designation returns the designation, not its family. - Text searches are unchanged.
- A pagination cursor issued before this change for a number in
qis rejected withcursor_invalid. Start the search again.
September 30, 2026: USPTO assignments February to April 2026 complete
USPTO assignments recorded February to April 2026 are now complete (about 19,000 recordations reloaded). They are available on/v1/assignments and
/v1/trademarks/{id}/assignments. The USPTO’s 6 to 10 week recordation lag
still applies to the most recent two months.
September 30, 2026: USPTO attorneys of record are representative
USPTO attorneys of record now carry role: "representative" in
attorneys[].role, the value every other office uses for the attorney of
record. They were correspondent. Stored rows were relabelled in place. The
first time we re-observe each USPTO mark after the change, that mark emits one
trademark.updated webhook and watches see an attorney change; this happens
once per mark. If you filter USPTO attorneys by correspondent, filter by
representative instead.
September 29, 2026: firms on Madrid families
- Grouped
firm_idsearch matches every designation’s firm. When one attorney appears on several designations of an international registration under different firms, a grouped search filtered byfirm_idnow matches the family for any of those firms, not only the first, as expanded search already did. Existing families pick this up when they are next re-indexed. - IR detail attorney order follows designation sequence. On an international registration with several designations,
attorneys[]in trademark detail is ordered by the designation’s attorney sequence, not by designation office, so it matches the search index. Multi-designation IR details may list attorneys in a new order. - Detail
firm_nameuses the firm’s display name. When the filing gives no firm name of its own,attorneys[].firm_namein trademark detail is now the firm’s display name (for exampleSmith & Jones, L.L.P.) instead of its upper-case matching key.
September 29, 2026: the primary image is always an image
primary_image_url and media[].is_primary now only ever point at an image
file, never a document, audio or video file. A mark whose only media are
office documents (for example USPTO office actions) or sound, video or 3D files
has primary_image_url: null and no primary item; those files stay listed in
media[]. Previously such a mark could point primary_image_url at a PDF.
Trademark detail now lists the primary item first in media[]; the other
items keep their order. Trademark detail applies this now; search results and
portfolio rows pick it up as marks are re-indexed, and fully with the next
index rebuild. has_media is unchanged.
September 29, 2026: one search request model: q, similarity, text filters and exclusions (breaking)
Search on GET and POST /v1/trademarks, the owner, attorney, firm and entity
/trademarks lists, similarity watches and the MCP search_trademarks tool
now share one request model. q always ranks, similarity picks the channels
it runs, the mark_text_* filters decide which marks qualify, and exclusions
leave marks out. The old parameters keep working until December 28, 2026. The
migration guide maps each one.
New parameters
similaritypicks the channelsqruns:identical,fuzzy,embedded,phoneticandlookalike. The default isidentical,fuzzy,embedded,lookalike, andidenticalis always on. See Similarity.- Text filters
mark_text_is,mark_text_word,mark_text_starts_with,mark_text_ends_with,mark_text_containsandmark_text_patterntest the mark text. OnGET, repeat the key for several values; commas are never split. OnPOST, send them underfilters.mark_text. Alone they list marks in text order; withqthey narrow the ranked results. See Text filters. - Exclusions:
mark_text_not_*for every text filter, plusowner_id_not,entity_id_not,entity_group_notandtrademark_ids_not. OnPOST, send them underexclude. allow_partial(options.allow_partialonPOST) returns the rows found so far when a search times out, withsearch_meta.complete: false.include=match_detailsaddsmatch.detailswith the matching methods that fired and the ranking factors applied.
matchon every hit of a request withqor a text filter:{ tier, via, terms }.tierisidentical,near_identical,similarorrelated, a retrieval category rather than an edit distance.vialists the channels that found the hit.termslists the text filter values it satisfied. See Match tiers.search_metagainssimilarity_applied,order(relevance,mark_text_fit,filing_dateor yoursort),complete,incomplete_reason,identifier,ranking_versionanddeprecations.
q. An application, registration or international
registration number pasted into q (97134218, US 97134218,
EUTM 018123456, IR 1939139, TMA911339, a tm_ ID) is looked up in
addition to the text search. Its records lead the page under any sort,
labelled via: ["identifier"], and search_meta.identifier shows how q was
read. A bare international registration number now returns the WIPO record.
See Search Trademarks.
Behavior changes
- Default recall is wider. A
qwithoutsimilaritynow also finds marks with a different first letter, look-alike characters and prefix phrases.embeddedfinds the term as a word, a phrase or the start of a word in a longer mark; a term in the middle of a word is not matched yet. Abbreviation matching and owner-name matching are removed from search; use Search Owners for owner names.search_meta.ranking_versionisv12. - Every search cursor restarts. Cursors issued before this release return
400 cursor_invalid. Cursors are now bound to the translated request, so an old-style request and its new-style equivalent share cursors. - Scores survive
sort. Withq,relevance_scoreandmatchare on every hit whatever thesort. Under asortthe score keeps the status factor and drops the length factor. - Text filters list in text order. Without
q, a text filter orders marks equal to the value first, then marks starting with it, then shorter marks, then newer filings. The oldmatchmodes returned the newest filings first. - A search that times out is a
503. A search that hits its time limit or loses a shard returns a retryable503unlessallow_partial=true. Sorted searches too; they returned400. Thepartial_resultswarning is removed. - No quiet downgrades. A query too expensive to run returns
400 validation_errorwitherrors[].code: too_complex, namingqor the text filter with the most values. It used to be retried with fewer strategies. Thestrategies_reducedwarning is removed. - New limits.
qtakes at most 22 words.contains,ends_withand wildcard-leadingpatternvalues need 3 characters after folding, and one request takes at most 4 of them (400 too_big). Each such value takes one slot of the search concurrency budget. mark_text_not_containsignores punctuation and spacing, like the other text filters, and takes repeated keys onGET.- Explicit
international_registrations=groupedon a request the grouped view can’t serve returns400 unsupported_on_grouped. Leaving it unset keeps the expanded fallback and its warning. - Skip warnings are per channel:
<channel>_skippedwith achannelfield.
- Similarity watches take
version: "v3",q,similarityandmin_tier(identical,near_identical,similarorrelated; defaultrelated). Existing watches keep alerting exactly as before until their query is changed. See Watches. - New watch queries use the new matching (added later on September 29).
Create, bulk create, preview and an update that changes the query store it
as
version: "v3"whateverversionyou send: a plain{ "version": "v2", "q": "acme" }gets the default channels andmin_tier: "related". Only a query withstrategiesormin_match_tieris kept as a legacy watch. An update that sends the stored query back unchanged still changes nothing. - Alerts gain
match.tier, on REST and in webhooks.match.scoreis still the engine score for the watch query, not the 0 to 100relevance_score. - Watch preview and diagnostics report
similarity_appliedandmin_tier.
strategies, match,
ranking_profile, a list in q, POST query and POST top-level
mark_text_not_contains are translated and listed in
search_meta.deprecations. A translated request never returns fewer marks
than before. On watches, strategies and min_match_tier are not translated:
a watch written with them is kept as a legacy watch until it is re-saved
without them, and they are listed in the response’s deprecations. From
December 28, 2026, each returns
400 unknown_parameter naming its replacement. The response fields
match_explanation, matched_terms, search_meta.strategies_used and
search_meta.match are filled from the new data until the same date.
TypeScript SDK 0.17.0 takes the new keys on trademarks.list(),
trademarks.search(), the party trademarks() methods and watches, removes
the old keys from the types, sends text filters as repeated keys, and exports
Presets.knockout and Presets.clearance.
September 28, 2026: party counts agree, Madrid designations show their serials, USPTO address and date fixes
Fixes from a customer’s attorney-onboarding test. Nothing here removes or renames a field.- List and detail counts agree.
GET /v1/attorneys,/v1/ownersand/v1/firmslist rows now readtrademark_countandactive_countfrom the same stats rows as the detail endpoints, not from the search index document. The monthly stats recompute now refreshes the search index for every party whose counts changed, and a repair pass is re-syncing attorney, firm and owner search documents (some attorneys and firms were missing fromqsearch). - Party detail ETags follow the stats.
/v1/attorneys/{id},/v1/owners/{id}and/v1/firms/{id}ETags change when the stats are recomputed;/v1/entities/{id}folds its live counts in. A client revalidating a cached body gets200with current counts instead of304. - Counting grain is in the spec. Every party stats field now says what it counts:
trademark_countandactive_countcount marks (a Madrid IR and its designations once);registered_count,pending_count,expired_count,cancelled_count,abandoned_count, the rates andavg_prosecution_dayscount office records, so the status counts can sum to more thantrademark_count.jurisdiction_countcounts offices. - Madrid designations carry their own numbers.
coverage.territories[]on grouped IR rows (search, party trademark lists, Retrieve Trademark, Batch Trademarks) adds the designation record’soffice_code,application_numberandregistration_number, so a US designation shows its 79-series serial on the grouped row. Passinternational_registrations=expandedfor one row per designation; the party trademark list pages now document it. - IR detail lists its designations’ attorneys. Retrieve Trademark for a Madrid IR (
grain: mark) now rolls upattorneys[]from its designations, as it already did for owners and classifications. Each attorney on such a row carriesterritory_codes, the designations whose record names them. IR-parent ETags change once. - Attorneys show their office. Attorney list and detail rows carry
source_office_code. Attorney records are per office: the same person appears once per office they file at. firm_idmatches the firm of record. Thefirm_idfilter and facet on trademark lists match the firm of record on the filing when known, else the attorney’s current firm, the same firm detail rows show. Index documents built before this change pick it up on the next index rebuild. USPTO filings stored before April 2026 are getting their firm of record from the correspondence address line.- USPTO addresses. USPTO attorney addresses are parsed into
lines,city,region,postal_codeandcountry_code(a trailing “United States” line no longer lands inlines), and USPTO attorneys getcountry_code: "US", soGET /v1/attorneys?country_code=USreturns them. Rows whose office gave no country staynulland are excluded from acountry_codefilter. USPTO owners now carry their street lines inaddress.lines. New and updated marks get these from this release; stored rows are repaired in place without webhooks or alerts. - TTAB filing dates. US proceedings now take
filed_datefrom the USPTO TTAB feed; before, only about 2% had one, sofiled_date_*filters,sort=filed_dateandfiled_yearundercounted. Historical rows are being backfilled; until the warning on the proceedings pages is removed, do not rely on TTAB date filters. - Assignments. The assignment pages state their scope: USPTO only, refreshed daily, with the USPTO’s 6 to 10 week recordation lag. Assignments recorded February to April 2026 are being reloaded.
- USPTO event codes in the catalogue.
GET /v1/event-types?office_code=USlists about 1,000 USPTO prosecution history codes with theevent_typeeach maps to.SUNA(notice of acceptance of a statement of use) is now alwaysapproval; the mailed form was typedresponse_filed. - Clearer
office_codeerror.office_codeonGET /v1/trademarksstill returns400; the message now namesoffices(one or more codes) andoffice(one code). - Docs. Per-tier
includevalues (full_goods_serviceson lists,office_extensionson detail and batch), webhook examples onpayload_version: 2with real status values, a portfolios walkthrough for status-change notifications, current plan limits, andETag/If-None-Matchchange detection on List Deadline Rules.
September 28, 2026: OpenAPI nullability checked against live responses
No request or response changes. The September 27 nullability fix is now enforced by a test that validates real API responses against the published OpenAPI document, so a field the API returns asnull cannot again be
published as non-nullable. A nullable field that references a
shared schema is declared as anyOf: [{$ref}, {type: "null"}].
September 28, 2026: one primary media item; document fields on media
media[].is_primarymarks exactly one item wheneverprimary_image_urlis set: the item that URL points at. A detail with several images and no office-flagged primary used to show every item asis_primary: falsewhileprimary_image_urlstill pointed at one of them; the two now come from one rule. Whenprimary_image_urlis null, no item is primary.media[].document_kind,media[].official_date,media[].page_countare added (additive, nullable) for a document item:document_kindis the same kindGET /v1/trademarks/{id}/documentsserves for that document (Signa’s classification of the office’s document type), andofficial_dateandpage_countare the office’s document date and page count, null when the office published none. All three are null for images. TypeScript SDK types regenerated.
September 28, 2026: Madrid family status.challenges is the union across designations
On an international registration whose designations disagree, status.challenges
used to read ["mixed"]. It now lists the real challenges: the de-duplicated
union across the designations, in a fixed order (for example
["opposition_pending"] when one designation is opposed), and [] when no
designation is challenged. status.primary and status.stage still read
mixed on such a family; mixed is never a challenge value. The same value
appears on the trademark detail, search hits, portfolio rows and watch
previews. No request or response field is added or removed.
September 28, 2026: Entity trademarks list scopes like the entity_id filter
GET /v1/entities/{id}/trademarks now returns every mark whose owner is
linked to the entity, read from the same resolved entity ids as the
entity_id filter on GET /v1/trademarks. The two return the same set for
the same entity.
- No member-owner cap. The endpoint no longer answers
422 entity_too_largewithreason: member_owners_too_largefor an entity with more than 10,000 member owners; it lists. The only remaining422isfamily_graph_too_largefrominclude_family=true. - Resource semantics are unchanged. A missing entity is still
404, a merged one410, andinclude_family=truestill walks the entity’s own subtree. The MCP toolget_entity_trademarksfollows the same scope.
September 28, 2026: filter-only order on expanded rows, mixed on the record grain
- Filter-only requests served one row per record are newest first. A
request without
qorsortthat is answered with expanded rows (international_registrations=expanded, or a grouped fallback such as aggregations or an unsupported sort) now returns the newest filings first (-filing_date), as documented and as the grouped view already did. Cursors minted by such requests before this release may no longer continue; start the walk again. status_primary=mixedandstatus_stage=mixedare grouped-view filters. A request served one row per record that carries them is now a400 validation_error(unsupported_on_record_grain, naming what forced the record grain) instead of an empty page.debug_timingis no longer documented onGET /v1/trademarks. It never changed a response; it is still accepted and ignored.- TypeScript SDK 0.16.0 drops
ranking_profileandoptions.include_profilefrom the search types.
September 28, 2026: q takes a list of exact terms; q_any is replaced (breaking)
Search has one text field again. q on GET and POST /v1/trademarks
takes either one term, as before, or a list of exact terms. q_any is
replaced by the list form.
- The list form. On
GET, write the whole value as a JSON array of strings:q=["limber","bimber"]. OnPOST, send an array inqueryorq:{"query": ["limber", "bimber"]}. The response is the same asq_anygave: every mark that is an exact match for any term, each hit carryingmatched_terms, andsearch_meta.matchreadsexact. See Several exact terms. - One term is unchanged. A string
qworks exactly as before. It is always literal text: no operators, no comma splitting. Only a value that parses in full as a JSON array of strings is a list, so[RE]BUILDand[1,2]are still searched as written. - A list runs
match=exact. It is the default for a list, and sending it is allowed. Any othermatch, orstrategies, with a list is a400 validation_error. - 100 terms per list (
q_anytook 200), each up to 200 characters. Long lists go byPOST: aGETquery string over 2 KB is rejected before it reaches the API. q_anyis replaced. A request that sendsq_anygets a400 validation_errorwhose message names the list form; move the terms intoqunchanged. The request is not billed and never runs as a filter-only search. Cursors minted byq_anyrequests may no longer continue; start the walk again.- Pricing is unchanged. One page of a list search costs the same as one page of any search, regardless of how many terms it carries.
- TypeScript SDK 0.15.0 types
qasstring | string[]ontrademarks.list()andtrademarks.search()and removesq_any. SDK 0.14.0 sendsq_any, so upgrade before relying on the list form.
September 28, 2026: mixed_script search warning
match=exact, starts_with, ends_with, contains and q_any compare
letters as written, so a look-alike spelling such as τιmbεr (Greek letters
among Latin ones) finds only marks spelled with those exact characters. When a
term mixes Latin with Greek or Cyrillic letters, search_meta.warnings now
includes mixed_script (severity: info, affected_filter: q or q_any)
naming the spelling. Results are unchanged. Ranked search with
strategies=exact folds look-alike letters and carries no warning.
September 27, 2026: Provenance release follow-ups
- CIPO status labels. Signa used to join CIPO’s status and its internal
description into one
status.raw.label(for exampleRegistration published - Registered). The label is now CIPO’s internal description alone (Registered), the same text a record without a status code carries.status.raw.codeis unchanged, and List Status Codes still servesnulllabels for CIPO. - EUIPO event labels. On EUIPO trademark events whose text Signa composed
from several fields (bulletin publications, oppositions, cancellations,
appeals, seniorities, decisions),
rawisnulland the text stays indescription. EUIPO’s own recordal kinds, such asProprietor - Total transfers, are still served asraw.label. - IPOS event labels. The filing and registration events Signa adds to IPOS
trademarks (
Application filed,Registration procedure completed) use Signa’s wording, sorawisnulland the text stays indescription. IPOS’s own event entries are unchanged. - INPI event codes. Signa used to join INPI fields into one event code,
such as
Inscription: Changement d'adresseorTransaction: Correction.rawnow carries the fields alone: a recordal is{"code": "Inscription", "label": "Changement d'adresse"}and a weekly transaction is{"code": null, "label": "Correction"}. Events from INPI’s status history are unchanged. - OpenAPI nullability. Enums documented as nullable now list
nullamong their values, andderived.next_deadlineis declared as aDeadlineRowornull. Responses are unchanged; a strict OpenAPI validator now accepts thenullvalues the API already returned. - Event types. List Event Types
catalogues IP Australia (
AU) and WIPO (WO) codes today. Other offices return an empty list.
September 27, 2026: The provenance release (breaking)
This is one breaking release, announced ahead of time to beta accounts. After it, every value says whether the office published it or Signa computed it, in one vocabulary, and a search hit is the same row as the detail. Update your integration and the TypeScript SDK (0.14.0) together. The headline: top-level dates are the office’s own.expiry_date and
renewal_due_date are null when the office published none. The USPTO
publishes no expiry date, so expiry_date is null on every USPTO record; the
rulebook’s term end is derived.expiry_date. Filters and sorts on
expiry_date and renewal_due_date follow the office values too.
Trademark rows (search, lists, portfolios, screening, batch, detail)
- Status.
status.sourceis nowstatus.basis(office,event_derived,dispatch_derived,computed).status.raw_codeandstatus.raw_labelare nowstatus.raw: {code, label}(ornull). The label is the office’s verbatim text only:nullwhen the office publishes none, or when the stored text was the code itself or wording Signa wrote. Decode codes with the new List Status Codes. - Dates.
expiry_date_basisandrenewal_due_date_basisare removed; top-level dates are office-published only. Newlast_renewal_date, the last renewal the office recorded (USPTO, CIPO and OEPM today). In every jurisdiction the rulebook treats the renewal cycle it paid, and every earlier cycle, as paid, so an early-renewed registration no longer lists the paid cycle as due.last_renewal_dateon aPOST /v1/deadlines/computeitem works the same way (it used to be read for Canada only). A paid cycle is not a missed one either:urgency=missedonGET /v1/deadlinesand portfolio deadlines, andinclude_missed: trueonPOST /v1/deadlines/compute, no longer list a cycle before the office-stated expiry, the cycle a recorded renewal paid, or the restoration window such a cycle would open.include_missedused to return that paid history. - An IR’s
expiry_dateis the expiry WIPO published on its designations. Known limitation: the search index does not hold it on the IR’s own record yet, soexpiry_date_*does not match the IR’s own record andsort=expiry_dateorders it with rows that have no office expiry. The next index rebuild fixes this. Also known: a renewal WIPO publishes on the designations moves the IR’sexpiry_datewithout raising atrademark.updatedevent or alert for the IR’s own id (Watches). derivedon every row, search hits included:ruleset_version(anrs_content hash, was a date),as_of_date,expiry_date,deadlines {supported, reason, unsupported_rules, items[]},next_deadlineandopposition_window. The detail’sdeadlines_supported,deadlines_unsupported_reasonanddeadlines_unsupported_rulesmove intoderived.deadlines, and the deadline array intoderived.deadlines.items.- Opposition window. The top-level
opposition_windowon search rows is removed.derived.opposition_windowis always present and two-state:{supported: true, rule_id, trigger_event, publication_date, window_opens, window_closes, close_adjustment, office_time_zone, common_extension}or{supported: false, reason, rule_id}with no null date keys.rule_versionis removed. - Deadline rows, everywhere a deadline appears (the
derivedblock,GET /v1/deadlines, portfolio deadlines,POST /v1/deadlines/compute):grace_expiryisgrace_expiry_date,recurringandoptionalareis_recurringandis_optional,nameanddescriptionare removed, and newoccurrence_key,due_date_adjustment,grace_expiry_adjustment,holiday_calendarandconsequence_if_missedappear on every row.occurrence_keyidentifies one occurrence within one trademark across reads:rule_id:<cycle>, orrule_id:t<term>-<n>when the record has no statutory anchor date or the row is anchored on an office-stated expiry. The calendar event UID namespaces it by trademark:tm_<uuid>:<occurrence_key>@signa.so. Madrid rules reportjurisdiction_code: "WO", and aPOST /v1/deadlines/computeitem sent asWIPOechoesWO. - Office record.
source_primary_idis replaced byoffice_record_id(the office’s own id;nullonly when Signa composed the key: an IR’s own record and its WIPO-feed, Finnish and Polish designation records; other national-office records of a designation keep the office’s id) andoffice_url. - IR numbers lose Signa’s
WOprefix inregistration_number("WO921642"is now"921642"), and theregistration_numberfilter matches the unprefixed number. - Owners.
owners[].entity_idis the resolved entity ornull;owners[].entity_id_typeis removed;owners[].entity_typeis nowowners[].legal_form. Detail owners gainis_current. - Attorneys (detail):
attorneys[].firm_idandfirm_nameare the firm of record on the filing, falling back to the attorney’s current firm (they used to be the current firm). Thefirm_idfilter and facet still match the attorney’s current firm, so about 5% of records can be returned for a different firm than their detail shows, until the next index rebuild. - Addresses have one shape everywhere (owners, attorneys, assignment
parties):
{lines[], city, region, postal_code, country_code, formatted}.stateisregion, lines are verbatim, and components appear only when the office supplied them. - Register. The detail’s
us_registeris replaced byregister {type, acquired_distinctiveness, is_incontestable, standard_characters_claimed}(ornull), on every row and for every office that states one. - Grain. New
grain: "mark" | "record".coverage,source_recordsandowners_mixedappear only on Madrid IR family rows (they werenullon others). Coverage territories are{territory_code, status {primary, stage}, trademark {id, href}, office_url, ...}(they wereterritory,primary,stageandtrademark_id), and the IR’s ownWOrecord is no longer listed as a territory. - The row-level
office_updated_atis removed (the detail keeps it underprovenance, which gainssnapshot_date). territory_matches[].basisismatched_via_kind.classifications[].class_status_rawisclassifications[].status_raw {code, label}.design_codes[]are{system, code, edition}(werecode_system,code_value), withsystemone ofvienna,us_design_search,other.filing_bases[].nice_class_numberisfiling_bases[].nice_class.classifications[].scope(as_filed) appears only on IR family rows.classifications[].nice_classcan benull(a class the office stated without a Nice number).- The detail’s
jurisdiction_codecan benull, as on the row.
Search and filters
- Removed filters (now a
400):renewal_due_before(userenewal_due_date_lt),us_register_type(useregister_type, which works for any office register),opposition_closes_beforeandopposition_closes_after(useopposition_closes_lteandopposition_closes_gte). This applies toGETandPOST /v1/trademarksand to the owner, attorney, firm and entity trademark lists. - Grouped per-leg filters. On the default grouped view, the office, route,
filing, registration and expiry date and registration number filters stay
grouped, alone or together: they must hold on the same record, and they
match the leg shown in
coverage.territories[]for each territory. When a territory has both a WIPO-feed and a national-feed record, the one Signa does not show (listed insource_records) does not match. search_meta.fallback_reasonis removed. A grouped request served one row per record now carries anexpanded_fallbackentry insearch_meta.warnings[]withaffected_filtersoraffected_option.search_meta.index_generationis new. Cursors are bound to the index generation, so a cursor minted before this release is rejected with400 cursor_invalid: restart pagination. The same applies after any future index rebuild.- New
result_window_reachedwarning (severity: info) insearch_meta.warnings[]: the last page of a relevance-ranked or sorted walk that the 10,000-row window ended while more rows match. A walk that ran out of matches never carries it. entity_idandentity_groupwith an owner id in entity form (ent_<owner-uuid>) return an empty page. Filter a single owner withowner_id.entity_idandentity_groupon trademark search no longer return422 entity_too_largefor an entity with more than 10,000 member owners; they match the entity directly.entity_groupkeeps its family-walk bound, and the other entity surfaces keep the member cap (errors).opposition_statusandopposition_closes_*match only while the mark is at a stage it can be opposed at (the gate behindstage_not_opposable); they used to match at any stage.- If Signa cannot load a result page’s stored data (owner entity links, record
facts, IR family facts), a trademark search or list request now fails with a
retryable
503 service_unavailableandRetry-After: 5instead of serving a degraded page. An owner-lookup failure used to serveowners[].entity_id: nulland show owners that are normally hidden.
Other endpoints
- Batch (
POST /v1/trademarks/batch): identifiers name their office withoffice_code(officeis now a400).dataanswers every submitted item in input order, and a repeated id repeats. - Events (
GET /v1/trademarks/{id}/events): rows areobject: "trademark_event"with their ownhst_ids (wereeventandevt_);raw_codeandraw_labelareraw {code, label};nice_class_numberisnice_class;sequence_noissequence_number;descriptionisnullunless it adds office text toraw.label. The org feedGET /v1/eventskeepsobject: "event". - USPTO event types. A USPTO notice of suit (
NOSU) isevent_type: "litigation"(wasoffice_action), so it no longer matchesevent_type=office_actionand no longer raisesoffice_action.issued. Attorney and domestic-representative appointments, revocations and withdrawals arerepresentative_changed(wereaddress_change); a representative’s own address change staysaddress_change. Labels naming the USPTO’s examining attorney, which the old rule also filed asaddress_change, take the type their label maps to (for exampleotherorcorrection). Stored history is retyped after the release, with no webhook or alert. - Entities.
entity_id_typeis removed. Entities are materialized entities only:GET /v1/entities/{id}(and/trademarks,/family) with an owner id in entity form is a404, linked owner or not; a merged entity stays410.GET /v1/entitiesno longer lists unlinked owners, andmembers[].linkis nevernull. - Owners, attorneys, firms. Owner
entity_id(list and detail) is the linked entity ornull, andentity_id_typeis removed. Statsearliest_filingandlatest_filingareearliest_filing_dateandlatest_filing_date(sort values are unchanged).aliases[].source_officeissource_office_code.addressis the one address shape. legal_formon every party.entity_typeislegal_formon owners (list and detail), attorney clients (GET /v1/attorneys/{id}/clients), entities (list and detail) and entitymembers[], as on trademarkowners[]. TheGET /v1/ownersandGET /v1/entitiesfilterentity_typeislegal_form(the old name is a400that names it).- Proceedings (
GET /v1/proceedings/{id}):trademark.serial_numberandtrademarks[].serial_numberareapplication_number. - Event types (
GET /v1/event-types):raw_codeandraw_labelareraw {code, label}, as on a trademark event. The label follows the verbatim-label rule, so WIPO rows (whose catalogue labels are Signa’s descriptions) havelabel: null. Theofficefilter isoffice_code, as onGET /v1/status-codes;officeand any other unknown parameter are a400. - Assignments.
reel_no,frame_no,release_of_reel_noandrelease_of_frame_noend in_number; newoffice_code. Parties:nationalityiscountry_code(ISO alpha-2,nullwhen the office named no country) andaddressis the one address shape. Properties:serial_no,registration_no,intl_reg_noandmark_nameareapplication_number,registration_number,ir_numberandmark_text. - Deadlines.
unsupported_marks[].unsupported_reasonisreasononGET /v1/deadlinesand portfolio deadlines. Compute items:unsupported_reasonisreason. Opposition compute items foldunsupported_reasonintoreason. Reconcilecomputed.unsupported_reasoniscomputed.reason.GET /v1/deadline-rulesreports Madrid rules asjurisdiction_code: "WO"(wasWIPO); itsjurisdictionfilter still acceptsWIPOas an alias. - Calendar (
GET /v1/portfolios/{id}/deadlines.ics): event UIDs aretm_<id>:<occurrence_key>@signa.so. A file downloaded after the release adds every event again beside the ones imported earlier (delete those once); afterwards, re-importing updates an event whose due date was corrected instead of duplicating it. - Offices (
GET /v1/offices,/v1/offices/{code}):coverageandcoverage_computed_ataredata_completenessanddata_completeness_computed_at.data_completeness.expiry_datecounts office-stated expiries only. - Citations:
disposition_as_ofisdisposition_at. - Goods and services suggest:
accepted_terms[].harmonisedisis_harmonised. - Office analytics:
earliest_filingandlatest_filingareearliest_filing_dateandlatest_filing_date. - Screening:
screening_idvalues change once (the receipt now binds the served index generation) and again after each index rebuild. - ETags change format. Every cached validator gets one
200, then304s resume. - Watches: a watch filtering on
expiryDateorrenewalDueDatenow matches office-published values, like the search filters. New watches cannot target an owner id in entity form; usefilters.ownerId. Existing watches that did are migrated tofilters.ownerId, or to the entity the owner has since been linked into, and keep evaluating the same marks. - New: List Status Codes
(
GET /v1/status-codes?office_code=US; unknown query parameters are a400).
Webhooks and GET /v1/events (payload_version 2)
New events are payload_version: 2 from September 27, 2026. Every event keeps
the version it was stored with: automatic retries, /redeliver and
GET /v1/events/{id} of an event recorded before then stay v1, so handle both
for the 30-day replay window. See Webhooks.
office_action.issuedv2 replaces the flatevent_date,event_code,event_label,scope,status_after_event,nice_class_number,description,source_identifierandsequence_nowithtrademark_event, the same rowGET /v1/trademarks/{id}/eventsreturns.- Change field names in v2 (
trademark.status_changedchanged_fieldsandchanges,alert.createdalert.event.diff[].path, and REST alertevent.diff[].path):source_primary_idisoffice_record_id,status_sourceisstatus_basis, andexpiry_date_basisandrenewal_due_date_basisare no longer published. - Change values in v2 follow the row:
status_basisuses thestatus.basisvocabulary; anexpiry_dateorrenewal_due_dateside that is not office-stated isnull, and a change between two computed values is omitted;status_raw_labelfollows the verbatim-label rule;registration_numberhas noWOprefix. - No alert is raised for a change whose every changed field is one the row does not publish (a Signa-computed date moving, or a basis change that stays non-office), so an alert never arrives with an empty diff.
- Both versions: on events emitted from the release on,
data.occurred_atis ISO 8601 UTC with milliseconds (2026-09-26T22:23:21.191Z), asGET /v1/eventsserves it. It used to carry Postgres text (2026-09-26 22:23:21.191924+00), which strict ISO parsers rejected. Retries and redeliveries of events emitted before the release keep the old text.
MCP
get_trademark_events returns the trademark_event rows;
get_entity, get_entity_trademarks and get_entity_family treat an owner id
in entity form as not found; batch_get_trademarks answers in input order;
search_trademarks and the party trademark tools take register_type,
opposition_status and opposition_closes_gte/_lte; list_offices and
get_office carry data_completeness; get_trademark,
get_trademark_events and the new list_status_codes declare an output
schema. list_event_types returns raw {code, label} rows, pages with the
REST cursor and takes office_code (was office). list_owners and list_entities take legal_form (was
entity_type). get_deadline_rules reports Madrid rules as
jurisdiction_code: "WO" (was WIPO). Every tool rejects an argument it does
not declare (a retired filter name or a typo) with an input validation error
instead of ignoring it. A tool result that fails its declared output schema is
an unbilled tool error (it used to be charged, then rejected by the client).
A tool that fails with an API error (for example not found or a validation error) returns
the typed JSON error body REST returns ({"error": {"type", "status", "title", "detail", ...}}, including errors[].code) instead of a
Failed to get X: ... message.
Upgrading
- Read expiry as
expiry_date ?? derived.expiry_date, and deadlines fromderived.deadlines.items. - Rename the filters above, and batch
officetooffice_code. - Treat
owners[].entity_idas nullable, and useowner_idfor unlinked owners. - Restart any paginated walk that spans the release.
- Branch webhook handlers on
payload_version. - Upgrade to
@signa-so/sdk0.14.0 (TypeScript SDK). Its types follow every change above. The old filter names are not translated: the API answers them with a400naming the replacement, andlist()’s POST fallback throws aSignaErrorthat names it.toArray()never returns a short array silently: it throwsSignaTruncatedErrorpast its 10,000-item default cap, and also when the API ended a relevance-ranked or sorted search at its 10,000-row window while more rows match (the last page’sresult_window_reachedwarning).
September 24, 2026: Declined deadline rules and uncomputed marks are now listed
When a deadline rule applies to a mark but the record lacks the date the law runs it from, Signa declines to guess and computes no row for it. Until now that rule simply did not appear. Three surfaces now name it. All changes are additive.POST /v1/deadlines/compute: every item carriesunsupported_rules, an array of{ rule_id, reason, missing_field, consequence_if_missed }. It is[]when nothing was declined, and[]whensupportedisfalse, becauseunsupported_reasonalready covers every rule.GET /v1/trademarks/{id},POST /v1/trademarks/batchand the MCPget_trademarktool: thederivedblock carriesdeadlines_unsupported_rulesin the same shape, next todeadlines_supportedanddeadlines_unsupported_reason.GET /v1/deadlinesandGET /v1/portfolios/{id}/deadlines: the list envelope carriesunsupported_marks, one entry per mark in the requested portfolio or trademark that was not computed at all (supported: false) or was computed only in part (supported: truewithunsupported_rules). Marks with a status that ends every obligation, such asabandonedorwithdrawn, are not listed. Entries use the samesupported,unsupported_reasonandunsupported_rulesfields as a compute item. The list covers the whole scope, not just the page, ignores thetype,urgencyanddue_beforefilters, and is sorted bytrademark_id. It is reported on the first page (a request withoutcursor) and isnullon continuation pages.
ph_declaration_of_use_5yr_madrid) runs from the statement of grant of
protection (IPOPHL MC 17-011 Rule 20(2)); send protection_grant_date on a
compute item and the row is computed. When every rule a mark owes is declined
this way, the whole mark declines with supported: false and
unsupported_reason: "requires_office_date", for example a Swedish mark
registered on or after 2019-01-01 with no filing date, or a registered US mark
with no registration date. Such a mark was previously reported as supported
with no deadlines. Whole-mark declines in unsupported_marks also cover the
existing unsupported_reason cohorts, such as Australian direct marks filed before 1996, Singapore direct
marks filed before 15 January 1999, Madrid designations without an
international registration date, and jurisdictions Signa does not model.
The portfolio calendar download (deadlines.ics) cannot carry this list,
since a calendar file holds only dated events. Read unsupported_marks from
the JSON list to see which marks and rules are missing from it.
September 24, 2026: Older Nordic registrations without a filing date get deadlines
Swedish, Icelandic, Norwegian and Finnish direct (non-Madrid) records with no filing date and a registration date before the office’s renewal-anchor change (SE 2019-01-01, IS 2020-09-01, NO 2010-07-01, FI 2019-05-01) got no maintenance deadlines. They now compute from the registration date, which the transitional provisions key on for marks registered before the change (SE SFS 2018:1652 p. 4 a; IS L. 71/2020 39. gr. 3. mgr.; FI 544/2019 107 § 4 mom.; NO Varemerkeloven § 83 with § 22). A record registered on or after the change date with no filing date now declines withunsupported_reason: "requires_office_date", since its term runs from the filing date it lacks.
GET /v1/deadline-rules publishes the rule as trigger_before_proves_cohort,
true on the SE, NO, FI and IS rules. See
Nordic countries.
September 24, 2026: Monitoring and reconcile on every plan; internal actions leave Get Credit Pricing
Mark watch, Filing watch (similarity, owner and class watches) and marks
under management are available on every plan, Free included, and cost no
credits during the beta. Creating a similarity, owner or class watch on
Free no longer returns 403 plan_gated. The watch, portfolio and managed-mark
count limits for each plan are unchanged.
Reconcile is available on Free as well.
POST /v1/reconcile no longer returns 403 plan_gated on a Free key. It still
costs 1 credit per record, spent from your monthly pool.
Get Credit Pricing no
longer lists internal-only actions (screening, compare and listing check) for
any key, and status is now one of available, beta or planned. They were
never available to self-serve keys and have no published price yet. SDK users:
CreditPrice.status no longer includes 'internal', so code that compares
against it or switches exhaustively on status needs updating.
September 24, 2026: offices and filing_route keep Madrid results grouped
An offices or filing_route filter switched a default (grouped) search to
one row per Madrid designation: offices=WO returned several rows per IR, no
coverage, and a total_count that counted designations. Once the rebuilt
search index is live, offices, office and filing_route stay grouped when
they are the request’s only filters. An IR then appears once, with its
coverage, when its WIPO record or any record linked to it matches. Combined
with another filter (status_primary, jurisdictions, nice_classes, …) they
still fall back to expanded, because the grouped row cannot tell whether both
conditions hold on the same designation; search_meta.fallback_reason names
the pair, for example filter:offices+status_primary forced expanded.
owner_name stays grouped from the same point. The per-designation date
filters (filing_date_*, registration_date_*, expiry_date_*) still fall
back.
offices matches the office a record comes from. offices=CA returns CIPO
records, not the WIPO records of IRs designating Canada. To find every IR
designating Canada, use jurisdictions=CA, which stays grouped.
The search reference described
the fallback the wrong way round. A grouped request the grouped view can’t
serve falls back to expanded, never the reverse.
September 24, 2026: Canadian and Brazilian date rolls, six-month Madrid renewal windows, and new deadline fields
Some maintenance dates move. Maintenance deadlines are recomputed on every request (POST /v1/deadlines/compute, the trademark derived block,
GET /v1/deadlines), so these apply now, with no reindex.
- Canada:
grace_expiryrolls to the next day the office is open (Trademarks Act s. 66(1)), reported ingrace_expiry_adjustment.due_datenever rolls: it is the end of the term.window_openson the office-anchored ladder no longer falls before the registration date (Regulations s. 159(a)). - Brazil:
due_dateandgrace_expiryroll to the next business day (Lei 9.784/99 art. 66 § 1º, applied by art. 69), reported indue_date_adjustmentandgrace_expiry_adjustment. - Madrid designations in CH, FR, AU, FI, PL, BR, IN, KR and CN: the
renewal
window_opensis six months before the due date, the period the International Bureau accepts a renewal in (Common Regulations Rule 30(1)(b)). It was 12 months.due_dateandgrace_expirydo not change. - India: the 7-year or 10-year first term is chosen by the Indian filing date, not the convention priority date. A convention application filed on or after 15 September 2003 with an earlier priority date now gets the 10-year term (filed 1 October 2003, priority 1 May 2003: due 1 May 2013, was 1 May 2010). The priority date is still the date the term is counted from.
GET /v1/deadline-rules reflects the Canadian and Brazilian rolls:
ca_renewal has holiday_calendar: "cipo_canada", weekend_holiday_rule: true and grace_expiry_rolls_only: true; br_renewal has
holiday_calendar: "br_brazil" and weekend_holiday_rule: true.
Alerts say whether their deadline was checked against a holiday calendar.
An alert’s must_act_by is fixed when the alert is created. The new
deadline.must_act_by_adjustment (moved, unchanged, not_checked or
month_end_overflow) travels with it on GET /v1/alerts, the alert detail,
the signed webhook body and the MCP alert tools. not_checked means no office
calendar was consulted, so the date may be early but never late: act on it,
but confirm it before you record it as final. The field is null on alerts
created before this release and on alerts with no opposition window; null
means no marker was recorded, not that the date was verified.
Watch diagnostics publish both opposition close dates. The opposition
block of GET /v1/watches/{id}/diagnostics now carries recomputed_close,
the close computed at request time, next to must_act_by, the alert’s fixed
date. The two can differ, for example after an office publishes a closure
notice. close_adjustment now always describes the date in must_act_by.
GET /v1/opposition-rules gains three fields.
window_change_comparison_field (publication_date, filing_date or null)
names the date compared against window_change_date; tr_opposition compares
the filing date. extension_change_date and common_extension_before give the
common extension that applied before a change, which the catalog did not
publish: CIPO went from 4 months to 2 on 2023-12-01, and IPOPHL from three
30-day extensions to one 45-day extension on 2022-06-30.
POST /v1/oppositions/compute already used the earlier figure for an earlier
close.
office_code on GET /v1/opposition-rules is filled in for every office.
It was null for offices Signa has rules for but no register from (JP,
IN, TR, KR, CN, BX, DK, FI, PL, TH, VN, PH, IS), so
joining it to POST /v1/oppositions/compute found nothing for them. ?office=
now accepts those codes; it returned 400 before.
September 24, 2026: q_any checks up to 200 exact terms in one request
GET and POST /v1/trademarks accept q_any: a list of up to 200 terms,
each at most 200 characters. It returns every mark that is an exact match for
any term, under the same rules as match=exact (case, accents, punctuation
and spacing), and each hit carries matched_terms, the terms it matched as
you spelled them. A clearance check over every one-letter variant of a word
becomes one request instead of hundreds. One page costs the same as any
search page.
Mind the request size: the API rejects a GET query string over 2 KB (403)
and a POST body over 8 KB (413) before your request reaches it. Send more
than a few short terms with POST, and split very large batches. The
TypeScript SDK keeps 700 bytes free for the page cursor: trademarks.list()
runs the walk by POST once the GET query string passes about 1.3 KB, and
trademarks.search() refuses a body over about 7.3 KB. See
Several exact terms.
September 24, 2026: One-character searches on owner, attorney and firm trademark lists
GET /v1/owners/{id}/trademarks, /v1/attorneys/{id}/trademarks,
/v1/firms/{id}/trademarks and /v1/entities/{id}/trademarks accepted a
one-character q but always returned an empty page. They now return that
party’s marks whose whole text is that character (ignoring case, accents and
punctuation), and
search_meta.warnings lists the strategies that cannot run on one character
(for example fuzzy_skipped). GET /v1/trademarks still requires at least two
characters for match=similar, except a single Chinese, Japanese or Korean
character.
September 24, 2026: Watches accept one- and two-character CJK keywords
A watch or watch preview whoseq contained a Chinese, Japanese or Korean word
of one or two characters (愛, 東京) was rejected with
400 validation_error (“Keyword too short”), although search accepts it.
Such words now pass; the 3-character minimum still applies to every other
keyword.
September 24, 2026: Mixed-alphabet and accented queries match like the index
Exact matching and the normalized search lanes folded some queries differently from the index, so they missed marks or matched the wrong ones. A mixed-script query such asτιmbεr was reduced to mbr and returned MBR marks, and
MÜLLER lost its Ü and missed MÜLLER. Greek and Cyrillic accents
(άλφα, Й) were stripped although the index keeps them, and full-width
characters (A) were not folded. Queries now fold exactly as the index does,
so these match the marks you would expect.
September 24, 2026: Screening and compare no longer reject brackets and parentheses
GET /v1/screening rejected any q containing [ ] ( ) { } | \ or a regex
pattern such as .* with 400 validation_error, and so did
GET /v1/screening?trademark_id=… whenever the register mark itself contained
them, which no caller could work around. Screening and /v1/compare now
remove these characters before the search runs, the same way trademark search
does. The identical registered mark is still found under sensitivity=strict:
the exact-match check compares the text as sent. A screening q or a compare
mark with nothing left afterwards still returns 400; a trademark whose mark
text has nothing searchable returns 422 not_screenable. Listing checks are
unchanged.
September 23, 2026: Long name searches return 400, not 503
A search query that is too long to run now fails fast with a 400 you can fix, instead of a 503 that invited retries. A longq, such as a full legal
line pasted from a filing, could exceed the search engine’s limit on how many
clauses one query may contain. We answered that with a retryable 503, so
clients retried a request that could never succeed.
On very long name searches for entities, owners, attorneys, and firms,
typo-tolerant matching now uses only the leading terms of q. Exact
whole-name matching still uses the full text.
If a query still exceeds the search engine’s limit, the API returns
400 validation_error with retryable: false instead of a retryable 503.
When the request has a q, the errors[] array names it:
{ "field": "q", "code": "too_complex" }. Shorten q and send it again. A 503
now means only that search is temporarily unavailable. Trademark search first
retries once with the cheap strategies you requested (exact, prefix) and
reports that in search_meta.strategies_used; if you requested neither, or
used a match mode or q_any, it returns the same 400.
September 23, 2026: Abandoned searches stop, and partial pages say so
When a client disconnects fromGET or POST /v1/trademarks or
POST /v1/watches/preview, the search it started is now cancelled instead of
running to completion. Other endpoints (owners, attorneys, firms, entities,
suggest, screening, image search) are not covered yet. Searches on the request
path no longer retry a timed-out query at the transport level, and a trademark
search stops within about 20 seconds with a retryable 503 rather than
stacking retries. A page whose search hit its time limit or lost a shard now
carries a partial_results entry in search_meta.warnings.
September 23, 2026: Relevance search pages to 10,000 rows on both views
A relevance search (q, no sort) now pages to 10,000 rows on both the
default grouped view and the expanded per-designation view. The expanded view
(used for international_registrations=expanded, aggregations, or a filter
the grouped view does not support) used to stop after 400 rows with
400 cursor_window_exceeded. The grouped view used to switch to a different
ordering after row 400, so a long walk could repeat or skip marks. Now every
page on either view runs the same query, the walk has no gaps or repeats, and
the last page inside 10,000 is served in full or in part and ends with
has_more: false.
Restart long grouped walks. A grouped relevance cursor minted before this
release for a page past row 400 now fails with 400 cursor_window_exceeded,
and its detail says the cursor is from an older release: restart from the
first page. Cursors for the first 400 rows, and expanded-view cursors, keep
working. See Pagination windows.
September 23, 2026: entity_count and owner_count aggregations
Trademark search accepts two new count aggregations, each returning
{ "value": n } for the result set. entity_count counts distinct parties
across offices (resolved entities; an owner not resolved to an entity yet
counts once per office record) and is the one to use for “how many owners
hold this phrase”.
owner_count counts distinct owner records, which are per office, so one
company filing in four offices counts four times. The owner_id aggregation
lists only the top 50 owners, so it could not answer either question. Both
counts are close to exact up to 40,000 and approximate above that.
September 23, 2026: match=exact ignores punctuation and spacing
match=exact compared punctuation literally: LET'S GO found the marks
written LET'S GO but LETS GO found nothing, and text normalized with
apostrophes turned into spaces (I DON T) never matched I DON'T. Exact
matching now folds case, accents, punctuation and spacing, so those spellings
all find the same marks. As a consequence, KIT KAT and KITKAT are also an
exact match for each other. q_any follows the same rules, so a batch of
terms finds every mark the matching single-term requests would. starts_with,
ends_with and contains are unchanged.
September 23, 2026: Single CJK characters are valid search queries
The defaultmatch=similar mode required q to be at least 2 characters,
which rejected single-character Chinese, Japanese and Korean marks such as
愛 or 馬 with 400 validation_error. A single CJK ideograph, Hangul
syllable or Kana character is now accepted and searched. Other one-character
queries still need a deterministic match mode.
September 23, 2026: Brackets and parentheses in q no longer return 400
GET and POST /v1/trademarks (default match=similar) and
GET /v1/trademarks/suggest used to reject any q containing
[ ] ( ) { } | \ or a regex pattern such as .* with 400 validation_error.
That also rejected real mark text such as EAT. SLEEP. FIGHT. (REPEAT) and
DON'T SCARE ME [I POOP EASILY]. These characters are now removed before the
search runs. A q with nothing left afterwards, such as .*, still returns
400. The deterministic match modes (exact, starts_with, ends_with,
contains) do not remove them. Screening and compare followed on
September 24 (see above); listing checks still reject these characters per
candidate with a 400.
Watch queries follow the same rule. A watch q with these characters is
accepted and stored exactly as sent; searches ignore the characters, and an
exact-tier watch still matches a mark written with them. Watches that were
previously skipped because their stored q contained such characters are now
evaluated and may start alerting.
September 23, 2026: Watch preview evaluates the watch query
Fixed:POST /v1/watches/preview ignored q on large scopes. When the
changes in the trial window exceeded an internal cap (common for a similarity
watch over US or EU), the preview returned the number of changed marks, for
example 659,662, as estimated_match_count, and results held marks that did
not match q. min_match_tier and trigger_events did not change the
number, and some queries hit 504 preview_timeout after 10 to 15 seconds.
A watch with a text query is now evaluated query first: the preview searches
for q with your strategies and filters, applies min_match_tier, keeps
the marks that changed in the window with a matching trigger_events type,
and returns those. results are ordered by relevance. When the count cannot
be exact, estimate_basis says which way it can be off: query_upper_bound
(can only be too high) or lower_bound (can only be too low). For a watch
with a text query, a timeout returns 200 with partial: true and the
verified count instead of a 504, and an unavailable search returns a
retryable 503. See Preview Watch.
September 23, 2026: strategies now runs only the strategies you pass
Fixed: strategies=exact also ran a synonym lane. A request such as
q=OUTER BANKS&strategies=exact returned OUTER BANKS BIKE WEEK and HIDDEN
GUARDIANS OF THE OUTER BANKS with strategies_matched: ["synonym"], while
search_meta.strategies_used reported ["exact"]. Synonym matching is part of
the fuzzy strategy and now runs only when fuzzy is requested (it is in the
default exact,fuzzy set). Serial and registration number lookups now belong
to exact. Every strategies_matched label now belongs to a strategy in
strategies_used.
The same applies when OpenSearch rejects a query as too expensive: the
single retry runs only the cheap strategies among those you asked for
(exact, prefix; exact for the default set), and
search_meta.strategies_used reports what was served, and a
strategies_reduced warning lists the dropped_strategies. If you asked for
neither, for example strategies=phonetic, the response is
400 validation_error with { "field": "q", "code": "too_complex" } when the
query was too large (shorten q or add exact/prefix; retrying does not
help), or a retryable
503 service_unavailable with Retry-After when the cluster was overloaded.
The default grouped view now follows the same rule; before, such a failure
there was a 500.
Watches are unchanged: live watches and watch previews keep the lanes they
had before this change, so no stored watch starts or stops alerting.
September 23, 2026: Aggregation counts now respect your filters
Fixed:aggregations on GET and POST /v1/trademarks ignored every filter.
Bucket counts were computed on q alone, so offices, nice_classes,
status_primary, date ranges and the other filters narrowed the results but
not the counts. A search filtered to offices=US,EM,WO still returned
office_code buckets for GB, FR and CA, and the buckets could add up to
several times total_count. aggregations_only=true had the same problem.
Aggregations now count the same set as the results: q, the match mode and
every filter. For single-valued fields such as office_code and
status_stage, the buckets add up to total_count. If you cached counts from
an aggregation request, refresh them.
For a drill-down sidebar, pass aggregation_mode=exclude_own_filter
(options.aggregation_mode on POST). This is not the old behavior, which
ignored every filter.
Each aggregation then applies every filter except its own, so the
office_code buckets ignore offices but still respect nice_classes and
status_primary. See
Statistics view.
September 23, 2026: pre-reform Nordic records without a registration date are declined
Swedish, Icelandic, Norwegian and Finnish direct (non-Madrid) records filed before the office’s renewal-anchor change date (SE 2019-01-01, IS 2020-09-01, NO 2010-07-01, FI 2019-05-01) that carry no registration date now decline withsupported: false and unsupported_reason: "requires_office_date", unless the mark is finally dead. Previously SE and IS served a filing-anchored renewal date, which could be years late after its first cycle, and NO and FI returned an empty schedule reported as supported. Madrid designations are unaffected (they renew on the international registration date), and an office-stated expiry_date, or a renewal_due_date with basis reported, still anchors and computes the schedule. See Nordic countries.
September 23, 2026: close_adjustment gains month_end_overflow
opposition_window.close_adjustment can now be month_end_overflow. It
was moved, unchanged or not_checked; there is a fourth value, and it
appears only on Mexican windows. Reglamento LPI art. 4o, párrafo segundo sends
a period whose day number does not exist in the target month into the
following calendar month, «el plazo concluirá el primer día hábil del
siguiente mes de calendario», so a Mexican application published 31 May 2026
closes on 1 July 2026, not 30 June. The field reported unchanged for that,
which reads as “a calendar was consulted and this date was already a business
day” about a date that had just been moved a month.
Read it exactly as you read moved: the close was checked against the office’s
calendar, and something moved it. The maintenance engine’s
due_date_adjustment and grace_expiry_adjustment have carried this value
since 3 September; the opposition field is now the same four-value set.
not_checked still wins where the calendar could not be consulted. The
overflow’s “following month” half is arithmetic and always applies; its “first
business day” half needs the office calendar. A Mexican close past the last
pinned IMPI acuerdo therefore stays not_checked rather than claiming an
overflow was resolved to a business day. The 20 day indeterminate band is
keyed on that same check, so it is unaffected. Maintenance rows follow the same
precedence: a Mexican due_date_adjustment or grace_expiry_adjustment past the
last pinned acuerdo now reports not_checked where it reported
month_end_overflow, and the date still carries the overflow.
Reindex required. close_adjustment is baked into search documents at
index time, so Mexican records whose window closes on a month-end overflow
carry unchanged in search until a full reindex runs. No DATE moves: this is
a marker correction only.
September 23, 2026: an absolute statutory ceiling is never rolled past
A prosecution due date clamped to a statutory ceiling is served on the ceiling, closed day or not. When an office states a response deadline later than its own statutory maximum, Signa emits the maximum instead. That date was then put through the weekend and holiday roll, which could walk it PAST the wall: a §66(a) provisional refusal issued 28 May 2026 has a six-month ceiling of Saturday 28 November 2026 under 37 CFR 2.62(a)(1)(ii), andPOST /v1/deadlines/compute returned Monday 30 November, a day on which the
response is already untimely. It now returns 28 November. The same guard
already applied to the extended due date; it applies to the base date now too,
which is the served date for any rule with no extension ladder.
due_date_adjustment reports not_checked when the roll result was
discarded. A date served on the ceiling did not take the roll, so reporting
moved (or unchanged) claimed a business-day finding that was never made.
This affects the statement-of-use chain, where the ladder lands exactly on the
36 month wall: a notice of allowance issued 10 January 2023 with all five
extensions still has an effective due date of Saturday 10 January 2026, and now
reports not_checked rather than moved.
September 23, 2026: the Australian Christmas close-down is no longer projected
IP Australia’s Christmas close-down is declared one year at a time, and Signa now treats it that way. The Canberra office’s excluded days come from the Director General’s annual declaration under Trade Marks Act 1995 s 223A, the Office Manual Part 2.1 defines them as exactly that. Signa held one such declaration, for 2026, and was computing its 25 December to 1 January close-down for every year through 2101. Dates in a year with no pinned declaration move EARLIER. Only the days a declaration actually names are closed now; the ACT public holidays this calendar computes from the law (New Year, Australia Day, Canberra Day, Easter, ANZAC, Reconciliation Day, King’s Birthday, Labour Day, Christmas and Boxing Day with their in-lieu Mondays) are unaffected and still roll. A renewal grace expiry on 24 December 2027, for example, is served on Wednesday 29 December 2027 rather than on 3 January 2028.due_date_adjustment, grace_expiry_adjustment and close_adjustment
report not_checked for Australian dates outside 2026. That is the honest
answer: the deterministic roll still applies and can only be early, but no
declaration has been read for that year. Australian renewal DUE dates are
unaffected either way, they never roll.
Reindex required. One opposition window in our frozen sample of real
Australian oppositions moves (publication 29 October 2024, close 2 January 2025
to 30 December 2024). Opposition windows are baked into search documents at
index time, so Australian marks published in late October to December carry the
old close in search until a full reindex runs.
September 23, 2026: EUIPO closure days are pinned back to 2023
Signa now holds the EUIPO Executive Director’s non-working-day decision for every year from 2023. Decision EX-22-10 of 20 December 2022 (for 2023) and EX-23-11 of 20 November 2023 (for 2024) join EX-24-9 and EX-25-16 in the evidence pack, so theeuipo_alicante calendar covers 2023 to 2026 instead of
2025 to 2026.
EU dates in 2023 and 2024 now roll against the decision that governs them.
Until today those years sat outside the calendar’s pinned coverage and took the
deterministic roll, weekends only, reported not_checked. They are verified
now, and due_date_adjustment / close_adjustment report moved or
unchanged for them. Dates move LATER where a decision closes the office:
Article 1 lists 1 April 2024 (Easter Monday), 11 April 2024 (Santa Faz),
23 to 31 December 2024 and 25 to 29 December 2023, none of which the weekend
rule sees. Later is the correct direction here, the Office states it was shut,
so the earlier answer named a day on which nothing could be filed. In our
frozen sample of 8,000 real EU oppositions, 358 window closes move (all later,
by 1 to 11 days) and 81 oppositions that had been scored as filed after the
close are now correctly inside it.
Reindex required. Opposition windows are computed at index time and baked
into search documents, so EU marks published in 2023 and 2024 carry the old
close date in search until a full reindex runs.
POST /v1/oppositions/compute and POST /v1/deadlines/compute are recomputed
per request and are correct immediately.
Nothing outside 2023 and 2024 changes: the 2025 and 2026 lists are untouched,
and 2027 onward still has no pinned decision and still takes the deterministic
roll. No rule_id changed.
September 23, 2026: dates outside a calendar’s pinned coverage are rolled again
A deadline that falls outside an office calendar’s pinned coverage is no longer served on a Saturday. Bounding the annual-notice calendars to the instruments actually pinned (Mexico through 30 November 2026, Denmark and France through 31 December 2026, EUIPO to its two Executive Director decisions, WIPO to Information Notice 40/2025) was right about the data and wrong about the answer: every engine read “outside coverage” as “do not roll at all”. A Mexican renewal reached from an ordinary 2025 filing came back due on Saturday 16 June 2035. Those dates now take a deterministic roll: weekends, plus the fixed holidays the calendar computes from the law rather than from a yearly notice. An annual notice or acuerdo can only ever ADD closure days, so the office’s true reopening is at or after the deterministic answer, which means this can be early and never late. The Mexican renewal above is now due Monday 18 June 2035.due_date_adjustment and close_adjustment still report not_checked for
these dates, and that is the point: the date is the best safe date, the marker
says nobody verified the year’s closure list. Nothing changes inside a
calendar’s pinned coverage, where the answer is still moved or unchanged.
Opposition windows: an unverified close inside the 20 day rollover band is
indeterminate, however it got there. A close date that sits inside coverage
but whose rollover walk runs past the end of the pinned data is now treated
exactly like one outside coverage: within 20 days of an unverified close,
POST /v1/oppositions/compute reports the window open under
serve_not_checked and raises the coverage error otherwise. Before this, a
EUIPO window published 30 September 2026 read closed on 31 December while the
same document was bucketed open in search.
Denmark and France gained a coverage FLOOR. Their closure lists are pinned
for 2026 only and neither is computable from the statutory holidays, so 2024 and
2025 dates now report not_checked (and take the deterministic roll) instead of
claiming a verified unchanged on days those offices were in fact shut.
The legacy US office-action rule cites a point-in-time URL.
uspto_domestic_oa_response@legacy and
uspto_domestic_suspension_inquiry_response@legacy quote the 2015 text of 37
CFR 2.62(a), the six month period. Their url pointed at the current eCFR
section, which reads three months and contradicted the quote beside it. It is
now the immutable govinfo 2015 annual edition, which is the document the
evidence pack actually pins.
September 21, 2026: Proceedings now link both sides, with trademark_role (breaking)
An opposer’s own marks now list the oppositions that opposer filed. Until
now a TTAB proceeding was attached only to the mark it was filed against, so
GET /v1/trademarks/{id}/proceedings on a prior registrant’s mark returned
nothing about the cases that registrant brought. The USPTO’s TTAB feed names
the marks on both sides, and we now link all of them.
Every proceeding row carries a new required field, trademark_role:
contested: the proceeding targets this mark (the opposed application, the registration under cancellation, the appealed application).asserted: the opposer or petitioner pleaded this mark as a prior right.
GET /v1/proceedings items, GET /v1/proceedings/{id}, and
GET /v1/trademarks/{id}/proceedings items, and all three accept a
trademark_role filter. GET /v1/proceedings also takes trademark_role as
an aggregation. GET /v1/proceedings/{id} gains trademarks[], every mark in
the case with its role, so the opposed application and the pleaded
registrations come back in one call. The trademark stub on that response
carries trademark_role too. The MCP tools get_trademark_proceedings and
list_proceedings take the same filter.
Two consequences to plan for. A mark’s proceedings list now includes cases
where the mark was asserted, not only cases against it; pass
trademark_role=contested for the filed-against view. And one proceeding
returns one item per linked mark, so a search by proceeding_number can
return several rows that differ only in trademark_id and trademark_role.
On the trademark detail, proceedings_count is now an object with the same
split, { "contested": 1, "asserted": 40 }, instead of a single integer. Both
keys are always present. A single total would have hidden which side a mark
is on, which is the question a clearance memo is asking.
trademark_role is distinct from parties[].role and the party_role
filter, which describe the named parties (opponent, petitioner, respondent),
not the marks. Existing rows read as contested. The asserted side is
populated for USPTO from the TTAB bulk feed; other offices link the opposed
mark only.
September 21, 2026: One row per TTAB opposition on US marks
A US mark opposed or petitioned for cancellation no longer shows two rows for the same proceeding. The USPTO bulk feed carries only a flag for a pending opposition or cancellation, and we stored it as a numberlesspending row.
When the TTAB docket for the same mark arrived with its proceeding number and
parties, both rows stayed. GET /v1/trademarks/{id}/proceedings and
GET /v1/proceedings?trademark_id= returned the pair, and
proceedings_count on the detail counted both.
The flag row is now dropped as soon as a numbered proceeding of the same type
exists on the record, and it is not written again while the flag stays set. A
mark whose docket we have not matched yet still shows the flag row, since it is
the only signal until then. The existing pairs in production are removed in
the same release.
September 18, 2026: TTAB proceedings, and how to read them
Trademark Trial and Appeal Board proceedings have been in the API since March. Oppositions, cancellations, ex parte appeals, concurrent-use cases and extensions of time to oppose are ingested daily from the USPTO’s TTAB bulk feed, with rendered decisions from the TTAB Reading Room and per-proceeding detail from TTABVUE. Today that is about 85,000 US proceeding rows on 69,000 marks, refreshed every morning, alongside opposition records from EUIPO, CIPO, IP Australia, IPOS and the Spanish office. This entry exists because the feature shipped without one. Three endpoints serve it, all ontrademarks:read:
GET /v1/trademarks/{id}/proceedingslists the proceedings a mark is party to, each withparties[].GET /v1/proceedingssearches across marks. One filter is required:trademark_id,proceeding_type,status,q(a party name),party_owner_id,party_entity_id,party_role,office_code,contested_classor afiled_date/decision_daterange. Aggregations coveroutcome,party_role,nice_class,office_codeandfiled_year.GET /v1/proceedings/{id}returns one proceeding with its parties and the mark it belongs to.
proceeding_type, proceeding_number (the TTAB case
number, for example 91278456), status, outcome, filed_date,
decision_date, decision_outcome (the Board’s own wording) and
duration_days. On the trademark detail, proceedings_count says how many
there are on each side, and has_proceedings=true narrows a search or list to
marks with at least one. The opposition tracking
guide walks through a monitoring
setup.
Four limits to know before you build on it:
- A proceeding is attached to the mark it was filed against. An opposer’s
own marks do not list the oppositions that opposer filed. To profile an
opposer, search by party instead:
GET /v1/proceedings?q=<name>orparty_owner_id=<own_…>(correction, October 1, 2026:party_owner_idreturns no results until parties are linked to owners; useq). Decided cases from the Reading Room are attached to every party’s marks. - Many
filed_datevalues are null. We trust only the filing date TTABVUE states for the proceeding; the bulk feed’s dates proved unreliable, so rows we have not yet confirmed carry no date and noduration_days. The default sort is-filed_date, so those rows come last. - Parties are names.
parties[].nameis the name as filed, andowner_idis set only where it resolved to a known owner. - There is no filing-by-filing docket, and no events or webhooks fire on a
proceeding change. Poll the list, or watch the mark’s
status.challengesforopposition_pendingandcancellation_pending.
GET /v1/trademarks?application_number=90839902&offices=US, then call
its proceedings list. POST /v1/trademarks/batch accepts many serials at
once.
September 14, 2026: Consistent trademark detail validators
Trademark detail responses now label theirETag as weak (W/"…") on both
200 OK and 304 Not Modified. The validator tracks equivalent trademark
content; the per-request request_id means two otherwise unchanged responses
can contain different bytes. This also gives edge-compressed and identity
responses the same semantic validator without guessing the selected encoding.
Send the full returned value in If-None-Match. Previously issued strong
validators still match unchanged resources, and the response returns the weak
form. Projections, language, derived data and citation counts continue to
participate in cache invalidation. See Caching & ETags.
September 14, 2026: Renewed marks stop showing the paid renewal cycle on US §8/§9 and MX renewals
A registration whose register expiry has already moved to the next term no longer carries its previous renewal as a live deadline, on every rule that ends a term. The maintenance engine has always dropped a renewal cycle that the office’s own stated expiry says was paid, but it recognised only the plainrenewal and international_renewal rules. Two rules end a term under a
different name and were missed:
- US Section 8 plus Section 9 (
combined_renewal_and_use). A mark registered in 2016 and renewed through 2036 still listed the satisfied 2026 cycle, in grace and apparently actionable, for the six months after that date. - Mexico’s combined renewal and declaration of use (
mx_renewal, alsocombined_renewal_and_use, national route). A renewed Mexican registration lost its paid cycle the same way. Madrid designations of Mexico renew centrally at WIPO underrenewaland were never affected.
derived.deadlines on GET /v1/trademarks/{id}, from GET /v1/deadlines,
from the portfolio deadline list and its iCalendar view, and from
POST /v1/deadlines/compute. POST /v1/reconcile already scored the stated
cycle rather than the paid one, so the two now name the same occurrence instead
of disagreeing.
Rows typed renewal and international_renewal are unchanged. They were
already inside the suppression, and their output is byte for byte what it was.
Section 8 declarations on their own, Section 15 affidavits and every other
non-renewal row are untouched too, since they are filings inside a term rather
than the term end. A mark that has not been renewed still shows its open
cycle for the whole window and grace period, because the register expiry is
that cycle’s own due date and there is nothing to suppress. And
POST /v1/deadlines/compute with include_missed: true still returns the full
history, including the paid cycle, which is what a docket audit needs.
One thing to check in your integration. Every deadline surface computes
over a finite horizon: ten years for derived.deadlines on trademark detail,
five for GET /v1/deadlines, for the portfolio deadline list and for its
iCalendar feed, and whatever you ask for on POST /v1/deadlines/compute. For a
mark renewed within the last few months, the paid cycle is now gone and the next
term end can sit beyond that horizon, so any of those can come back empty where
they previously held one row. A mark registered 1996-06-01 and renewed through
2036-06-01, read on 2026-05-01, is the shape: the paid 2026 cycle is suppressed,
and the 2036 cycle falls on 2036-06-02 after the weekend roll, thirty two days
past the ten year horizon, and roughly five years past the five year one. It is
a well formed empty array, not a missing field, and the mark’s own expiry_date
still carries the register’s stated term end. Read the array rather than
assuming it has at least one entry.
A register value we cannot place on the statutory ladder no longer suppresses
a US or Mexican combined cycle. A stated expiry has to fall within about a
month of a real cycle on the rule’s ladder for us to treat it as evidence that
the cycle before it was paid. On combined_renewal_and_use (US Section 8 plus
Section 9, and the Mexican renewal), that recognition is the whole test: a
register carrying a term end the rules cannot produce, for example fifteen years
after registration on a ten year ladder, used to delete the mark’s real, live
obligation from the schedule, and now leaves it alone. Those marks show the
cycle actually in force, and POST /v1/reconcile reports the register value as
differing from the computed one.
Rows typed renewal and international_renewal behave differently here, and
deliberately so. For that family an office-stated renewal date is
authoritative, so the engine rebuilds the rule’s cycle series through it rather
than measuring it against the statutory ladder: an Indian mark whose priority
date no register field carries legitimately sits months off that ladder. Taking
the office at its word means every cycle before the stated date is still treated
as paid, whether or not the date lands near a computed cycle. A register value
far enough out that the schedule cannot reach it therefore yields an empty
forward schedule on those rules, and POST /v1/reconcile reports the renewal
field with a computed_value of null and a computed_unavailable_reason of
insufficient_data, rather than a disagreement. The verdict on that field is
then scored against the register alone: agrees when your docketed date
matches the register, caller_differs when it does not. (insufficient_data
is the verdict itself only when the register carries no date either.) That is
unchanged from before this release.
September 14, 2026: Docs and spec alignment: rule catalogs join Filing & docketing, alpha labels, monitoring status reference
The rule catalogs now live next to the endpoints that use them.GET /v1/deadline-rules is tagged Deadlines and GET /v1/opposition-rules
is tagged Oppositions in the OpenAPI spec, both inside the Filing & docketing
tag group, and their reference pages sit under Filing & docketing, Deadlines,
after the compute pages. Nothing about the endpoints changed: same paths, same
responses, same free reference pool. Only the grouping moved, so a client
generated from the spec files the catalogs with the deadline and opposition
workflows instead of a separate Reference Data section. If your generator
names client classes after tags (openapi-generator, NSwag), the two catalog
operations move from the Reference Data class to the Deadlines and Oppositions
classes; regenerate and update those two call sites.
GET /v1/monitoring/status has a reference page. The endpoint had a guide
but no API-reference entry. The new page, under Monitoring, Watches, documents
the two halves of the response: watches is your organization’s rollup by
health state, and offices[] is Signa’s global per-office ingestion freshness,
identical for every organization. It also states plainly that slo_hours is
Signa’s internal freshness target for computing pipeline_status, not a
published SLA.
Screening, compare, listing checks and image search are labelled alpha.
These endpoints run on internal and design-partner keys during internal
testing and their request and response shapes can still change. The docs
pages and spec descriptions now say alpha rather than beta. Email
support@signa.so to join the early access list.
Analytics navigation is simpler. Market, office and classification
analytics are grouped under one Filing Analytics heading; party analytics stay
their own group. The rate-limits page inventory lists only published
endpoints.
September 11, 2026: Reconcile becomes a docket audit (verdict_detail)
POST /v1/reconcile gains an opt-in three-source verdict. Send
verdict_detail: true and every found item adds field_verdicts[] (your
value vs the register vs the rulebook-computed schedule, with a seven-value
verdict and full rule provenance), a computed context block and a lookup
identifier echo. A new your_fields.docketed_deadlines[] input lets you audit
the maintenance deadlines you have on docket against the computed schedule.
See Three-source verdicts.
Entirely additive and off by default: without the flag, responses are
byte-identical to before, and with the flag, fields[], result and
mismatch_count keep their exact v1 values. Billing is unchanged either way
(1 unit per item). One error-path nuance: sending docketed_deadlines without
the flag is a 400 validation_error whose message now names the flag
requirement instead of the generic unknown-key rejection.
September 11, 2026: Fee endpoints accept platform office codes
GET /v1/fees and POST /v1/fees/estimate now take the office spellings the
rest of the API takes. office, and each entry in designations[], used to
accept only the WIPO ST.3 codes WO, US, EM and GB, plus WIPO as an
alias for WO. They now also accept the platform office codes USPTO, EUIPO
and UKIPO, and the permanent EU alias for EM, in any case, exactly as
GET /v1/trademarks?offices= does. A request that used to come back with an
empty catalog or an unsupported_office line only because of how the office was
spelled is now priced.
The change is additive, and it is resolution only. Responses echo the canonical
ST.3 code, so {"office": "USPTO"} returns "office": "US". No amount,
currency or catalog row changes for any request that was already priced, and an
office with no verified schedule still returns an empty catalog or an explicit
unsupported_office line rather than a guessed amount. Two spellings of one
designated office now collapse to one code before the uniqueness check, so
designations: ["EM", "EU"] is rejected as a duplicate instead of being counted
twice.
dataset_version on POST /v1/fees/estimate changes with this release because
it covers estimator semantics as well as the fee rows. The rows themselves are
untouched.
September 6, 2026: Portfolios are public
Portfolios are now a documented resource family. The nine portfolio operations (create, list, retrieve, update, delete, add and remove trademarks, and the JSON and iCalendar deadline views) appear inGET /v1/openapi.json
under a Portfolios tag, grouped under “Filing & docketing”, with
reference pages and a
portfolios guide. Nothing about the endpoints themselves
changed: same paths, same portfolios:manage scope, same read metering
(1 unit per request, including writes and calendar downloads), same plan gating.
The catalog operations GET /v1/classifications,
GET /v1/classifications/{classNumber} and GET /v1/goods-services also move
from the Reference Data tag to Classification, which is where the rest of
the classification surface already lives. Tags are documentation grouping only;
no path, parameter or response shape changed.
Three error types that portfolios return are now in the
error reference: 409 resource_quota_exceeded,
409 portfolio_in_use and 422 portfolio_too_large.
The TypeScript SDK’s generated types caught up with the published spec.
@signa-so/sdk 0.12.0 regenerates api-types from the same spec build the
published document uses. That adds 37 operations and 21 schemas, and removes
nothing. Nine operations and two schemas are the portfolios surface. The other
28 operations and 19 schemas (watches, alerts, webhooks, events, monitoring
status) were already published in GET /v1/openapi.json but were missing from
the generated types, because SDK codegen ran against a narrower build of the
spec than the one we publish. No existing operation or type changed, so the
update is additive for every consumer.
September 5, 2026: Auth hardening, plan_gated, prefixed watch filters
Three visible changes from the auth and tenancy hardening pass (the first and
third have been live since 2 September; the watch-filter change lands today).
None of them alter a successful response.
403 plan_gated replaces a misleading 429. Calling a capability that is
not on your plan at all (for example image search on free) used to return
429 rate_limited with retry_after: 0, which sent SDK retry loops spinning.
It now returns 403 plan_gated with endpoint_type naming the capability and
retryable: false. See the error reference.
Watch filters echo prefixed IDs. query.filters.trademarkIds, ownerId,
attorneyId and firmId on every watch response (REST and MCP) now come back
as tm_* / own_* / att_* / firm_*, whichever form you sent. Input still
accepts both, so nothing you send changes.
Stricter bearer parsing, clearer outages. Authorization is single-valued
(RFC 7235): a comma-joined pair of credentials is a 400. The scheme is
case-insensitive. A missing header gets a bare WWW-Authenticate: Bearer
challenge with no error code (RFC 6750 §3.1). When Signa’s own token verifier
or JWKS is unreachable, MCP requests get a retryable 503 service_unavailable
instead of being told the token is invalid.
September 4, 2026: nine deadline rules relabelled, and consequence_if_missed is an open string
Nine maintenance rules changed the consequence_if_missed string they
serve. No due date moved, no window opened or closed differently, and no rule
was added or removed. Only the label changed: each of these now names the
mechanism the office’s own pinned provision prescribes. The rules are
bx_renewal and mx_declaration_of_use_3yr (irrevocable_loss to
expiration), ch_renewal (irrevocable_loss to removal_from_register),
de_renewal, dk_renewal and eu_renewal (cancellation to
removal_from_register), fr_renewal and pl_renewal (cancellation to
expiration), and th_renewal (removal_from_register to expiration).
This shipped with no deprecation window, deliberately. consequence_if_missed
is an open string and not an enum: the documented vocabulary is the set of
values in use today, and Signa edits a rule’s wording whenever a better reading
of the primary source arrives. Branch on rule_id, which is stable and
permanent, or on the structured fields that carry the arithmetic, and treat this
field as display text. The full before-and-after table is in the
deadline rules guide.
September 3, 2026: prosecution deadlines are served outside calendar coverage
A prosecution deadline is no longer withheld because its office calendar cannot check the date. Boundingeuipo_alicante to the two Executive
Director decisions actually pinned (2025 and 2026) had a consequence we did
not intend: every EU office action mailed before 2025, and every one mailed
from 1 November 2026 onward (a two-month period lands in 2027), came back
insufficient_facts with reason holiday_calendar_out_of_coverage and no
date at all. The same held for US office actions before 1985. Silence on a
deadline whose miss abandons the application is the worst possible answer.
Those cases now return outcome: "computed" with the raw statutory
anniversary. An office action mailed 10 January 2024 at the EUIPO reports
due_date: "2024-03-10"; one mailed 1 November 2026 reports
"2027-01-01". This matches what the renewal engine
(due_date_adjustment) and the opposition engine (close_adjustment) have
always done. An un-rolled date is never LATER than the true deadline, so it
can be early but cannot cause a missed one.
New field: due_date_adjustment on every prosecution deadline. It tells
you which kind of date you are holding, using the same vocabulary as the
renewal rows:
moved: the office calendar was consulted and rolled the date forward off a day the office is shut.unchanged: the calendar was consulted and the date was already an open day.not_checked: no calendar verdict stands behind the date. Either the date falls outside the calendar’s pinned coverage, the rule ships without a roll rule, or the office stated the date itself (a stated deadline is published exactly as stated and never rolled). Treat it as the raw statutory anniversary and confirm before relying on the exact day.null: no date was produced at all.
holiday_calendar_out_of_coverage remains in the reason vocabulary but is now
a backstop for a calendar-integrity failure rather than the ordinary
out-of-coverage answer. No shipped rule reaches it today.
close_adjustment on a trademark summary row is no longer nullable. The
same marker was declared nullable on the summary row’s opposition_window and
non-nullable on the detail tier’s derived.opposition_window. It can never be
absent while its parent object exists, so the two now agree and the
nullability sits where it belongs, on opposition_window itself. If you
null-checked the field, that check is now dead code; nothing you were reading
changes value.
Search and opposition-compute deliberately disagree for 20 days after an
un-rolled close. Where close_adjustment is not_checked and the close is
within the last 20 days, search buckets the mark as open (a rollover could
only have pushed the close later) while POST /v1/oppositions/compute reports
closed against the un-rolled date. Search’s reading is the safe one. Search
documents in that band also now carry the un-rolled close rather than no
opposition window at all; a full reindex populates them.
September 3, 2026: France, Finland and Poland Madrid designations get opposition windows
Three new rules. An international registration designating France, Finland or Poland had no opposition window at all:POST /v1/oppositions/compute, the
derived block, GET /v1/opposition-rules and watch diagnostics all returned
nothing for those rows. fr_opposition_madrid, fi_opposition_madrid and
pl_opposition_madrid now answer.
France, two months from the WIPO Gazette. CPI art. R. 717-1 applies the
whole domestic opposition procedure to an international registration extended
to France, and art. R. 717-5 names the publication the art. L. 712-4 two
months run from: WIPO’s Gazette, not any INPI republication. There is no
first-of-the-following-month offset, unlike Switzerland and Germany. INPI’s own
directives work the case: an IR published in Gazette 2019/23 of 20 June 2019
has an opposition period expiring 20 August 2019. Every other mechanic is the
domestic one by statute rather than by copy, including the art. R. 718-2
same-numbered-day arithmetic, the roll off weekends, jours fériés and INPI
closure days, and the extra month for the exposé des moyens.
One documented limit, and it is a hard gate. The rule reports
effective_from: "2009-01-01" and applicable_from_date: "2009-01-01". The
version of art. R. 717-5 in force before that date ran the period from the
first day of the month after INPI received the Gazette, an internal office
event that no register record carries. We decline that era rather than guess
it, so a French designation published before 2009 comes back
supported: false with unsupported_reason: "unsupported_office" and the
rule identity intact, effective_from naming the boundary.
Finland, two months from PRH’s own publication. Tavaramerkkilaki 544/2019
92 § 5 mom. has PRH publish the international registration in the same words
24 § uses for a national one, and 88 § 2 mom. applies the Act to an IR except
where the Madrid chapter says otherwise, which it does not for opposition. So
32 §‘s two months from the publication day carry over, with the 150/1930
month-end clamp and the roll off a pyhäpäivä or a working Saturday. PRH’s own
gazette confirms it: record W202600336 is an international registration with
oppositionPeriodStartDate equal to its publication date.
Poland, three months from the BUP announcement. PWP art. 152^1a ust. 1 has
UPRP announce a designation of Poland in the Biuletyn Urzędu Patentowego
without delay, and art. 152^6a ust. 1 gives an earlier-right holder three
months from that announcement, non-restorable. The Biuletyn states the same
sentence for both routes. The window opens the day after publication and closes
on the same-numbered day three months later under KPA art. 57 § 3, rolling off
statutory non-working days and Saturdays under § 4. The rule reports
effective_from: "2016-04-15", the commencement of art. 152^6a: before that
date there was no pre-grant opposition against a designation of Poland at all.
Which publication your date is. All three rules declare it, so the
publication_date_kind guard applies. FR needs wipo_gazette; FI and PL need
office_journal. Send the other one and the response is status: "unknown"
with null dates and the rule’s identity intact, rather than a date you should
not act on. Omit the field and nothing changes.
Reindex required after the backfill. These windows appear on documents that
carry none today, and opposition_window_opens / opposition_window_closes
are baked into search documents at index time. Request-time surfaces
(POST /v1/oppositions/compute, the derived block, the SDK) are correct the
moment this deploys. The opposition_status and opposition_closes_after
filters will not see the new windows until French, Finnish and Polish Madrid
designations carry an office publication date from the designation-publication
backfill and are reindexed. No window we already serve MOVES: no publication
date is reinterpreted and no existing pair of dates changes.
One thing that does change shape: opposition_window stops being null for
WIPO-feed legs. A designation leg that reaches us through the WIPO feed
carries office_code = "wipo" with the designated country in
jurisdiction_code, which never matched a rule keyed on the designated
office’s code. Those legs now resolve by jurisdiction, so for EVERY Madrid
jurisdiction we model (not only the three new ones), derived.opposition_window
turns from null into an object. Until the leg carries an office publication
date the object’s dates are all null and status is "unknown", and
opposition_rule_version in search documents becomes non-null after the next
reindex where it was null before. If your integration reads
opposition_window === null as “Signa does not model opposition for this
mark”, that inference no longer holds: check status and window_closes
instead. A null opposition_window now means only that no rule matched the
office, route and publication era at all.
No United Kingdom rule yet. A UK Madrid designation still returns no
window. UKIPO runs its three months from the UK Trade Marks Journal, and the
current Journal source is not available to us to pin, so the rule is held
rather than written from an unverifiable source.
September 3, 2026: holiday calendars now stop where their evidence stops
Some deadline dates move EARLIER, and more of them reportnot_checked. Every office holiday calendar Signa ships now advertises
coverage only as far as the instruments actually pinned behind it. Eight of
them are built from a document the office issues once a year: a decision, a
notice, an acuerdo, a proclamation, an office memorandum. Those now stop
at the last one pinned instead of projecting forward:
Beyond those horizons nothing is guessed. A renewal or grace date comes back
UNROLLED with
due_date_adjustment / grace_expiry_adjustment set to
"not_checked", and an opposition window is served with its close on the
exact statutory day. Unrolled is never LATER than the true date, so a date we
serve can be early but cannot cause a missed deadline. The calendars that are
genuinely rule-computed (US, Canada, Germany, Australia, Brazil, Benelux,
Switzerland, Finland, UK, Iceland, Norway, Poland, Sweden) still run to 2100,
and the lunar ones (Singapore, Thailand, Vietnam, Japan, Korea, Türkiye) to
2030, unchanged.
EU: the invented years are gone, and EU dates in 2024 and earlier are no
longer rolled. Superseded September 23, 2026: 2023 and 2024 now roll against the EUIPO decisions for those years. euipo_alicante carried closure days for 2024 and for
2027-2030 that no Executive Director decision states. The 2027-2030 entries
were labelled “estimate” and moved deadlines LATER: a day after Ascension,
in-lieu Mondays, 4 January 2027, 6 December in four different years, and the
two decisions that ARE pinned falsify the pattern they were derived from
(EX-24-9 closes for Ascension, Schuman Day and the Assumption; EX-25-16 closes
for none of the three and adds Santa Faz, 12 October and 2 November). The 2024
block said “per prior EX decision” and no such decision exists in our evidence.
All of it is deleted. Consequences, both directions:
- EU opposition closes for 2027 and later are no longer rolled. A window whose close lands on a weekend or a 2027 Spanish feast is now served on the raw statutory date. Example: an EU application published 30 November 2026 closes 28 February 2027 rather than 1 March 2027.
- EU dates before 2025 are outside the calendar. An EU office-action
response deadline computed from a 2024 mailing is no longer rolled against
the unpinned 2024 block. Superseded the same day: this originally returned
insufficient_factswith reasonholiday_calendar_out_of_coverage. It now returns the un-rolled statutory date withdue_date_adjustment: "not_checked". See the entry above.
mx_mexico therefore stops on 30 November 2026. Before this change, an MX
opposition window closing 22 December 2026 was served as a working day and
reported closed on 24 December, while IMPI was in fact shut. It now reports
window_not_computable until the acuerdo covering December 2026 is published.
A roll can no longer walk off the end of a calendar. The coverage check ran
only on the date being rolled, not on the days the roll walked through. A
deadline on a listed year-end closure could therefore step into the following,
uncovered year, where every day looks open, and stop on the first of January.
WIPO 31 December 2026 reported 1 January 2027 as moved; DKPTO 28 December
2026 reported 4 January 2027. Both now report not_checked and serve the
unrolled date.
Mexico closes on 25 December. mx_mexico was missing Christmas Day from
its recurring días inhábiles, although the one pinned acuerdo that lists a
whole year without folding December into a closure block (DOF 5580658) ends
«DICIEMBRE Viernes 25». MX deadlines falling on 25 December now roll to the
next working day, LATER by one to four days, in every covered year.
Iceland: no change, and now only one story about why. 24 and 31 December
stay closed on is_iceland, on Hugverkastofan’s own December 2020 notice that
the office is shut all day and that deadlines falling there move to the next
opening day. Five documents still described these as open days under a
superseded reading; they now all state the ruling that shipped. Þorláksmessa
(23 December) is declared year by year and stays OPEN. No date moves.
Reindex needed for EU and MX opposition windows. Opposition windows are
baked into search documents at index time. EU documents whose window closes in
2027 or later, and MX documents whose window closes in December 2026, carry the
old rolled close until the affected records are reindexed. Request-time
surfaces (/v1/oppositions/compute, /v1/deadlines/compute, the derived
block) are correct on deploy. DK, FR, PH and IN opposition windows move only
for close dates past their horizons; reindex those offices with the same pass.
September 3, 2026: close_adjustment on every opposition window
New field: was this close date checked against a holiday calendar?
close_adjustment now appears on POST /v1/oppositions/compute, on the
derived.opposition_window block of a trademark, on the opposition_window
of every trademark summary row and on the opposition block of
GET /v1/watches/{id}/diagnostics. It reads moved (the close fell on a day
the office is shut and was rolled forward), unchanged (the calendar was
consulted and the close was already a business day) or not_checked, meaning no
calendar stands behind this date.
not_checked is not new behaviour, only newly visible. Several office
calendars are built from an annual notice (China’s State Council holiday
notice, India’s DoPT memorandum, the Philippine proclamations, Mexico’s IMPI
acuerdos, WIPO’s non-working-days notice), so a window closing in a year whose
notice is not yet published has always been served with raw statutory
arithmetic. A rollover can only move a close later, so an un-rolled close
is correct-or-early: safe to act on, never a reason to file late. Until today
nothing on the wire told the two apart.
The opposition_status search filter now treats an un-rolled close as
indeterminate. For the 20 days after a not_checked close date, a row
counts as open and is excluded from closed, because the rollover that
could not be applied may still be holding the window open. not_started and
unknown are unchanged, because the opening date is never rolled.
Reindex required to populate. The marker is baked into the search index at
index time (opposition_close_adjustment, an additive keyword field, so no
alias swap, no new index generation). Documents indexed before this release
carry no value and are bucketed by their dates alone, exactly as they were
before; the indeterminate band applies to them only after a reindex. Every
request-time surface (/v1/oppositions/compute, the derived block, watch
diagnostics) recomputes and is correct immediately.
Also: POST /v1/oppositions/compute declines with
window_not_computable in fewer cases. A close falling exactly ON the date
you compute as of is now published un-rolled instead of declined: a rollover
can only push it later, so the window is open either way. The narrow band that
still declines is a close strictly 1–20 days before the as-of date.
September 3, 2026: opposition rule catalog reports both eras
Five new fields onGET /v1/opposition-rules (and the MCP
get_opposition_rules): window_change_date, window_starts_on_before,
window_months_before, window_days_before and window_ends_on_before. An
opposition rule models a regime change inside itself, and the catalog used to
serve only the current era, so a client reproducing a close date for a
publication before the pivot got the wrong length, the wrong start convention,
or both, with nothing on the wire to say so. A publication strictly before
window_change_date is governed by the _before fields. All five are null
on a rule that has never changed. (A previous entry said era behaviour was
already reported through window_starts_on / window_ends_on. It was not;
this is the change that makes it true.)
One existing value changes: window_ends_on is now era-scoped.
bx_opposition opens on the first of the following month only in its
pre-1 October 2013 era, so its corresponding_day_of_start describes THAT
era. It now reads window_ends_on: null with
window_ends_on_before: "corresponding_day_of_start" instead of claiming the
current era ends that way. The current BX era anchors the close on the
publication day-number and never reads the field. BX is the only affected
rule; no computed date moved.
September 3, 2026: rule corrections (CN, PH, CH, CA, DE, MX)
China: the 2027 straddle is served the SHORTER window. The 2026 revision of the Trademark Law cuts the opposition period from three months to two on 1 January 2027 and carries no transitional provision for a period still running on that day: art. 87(2) speaks only of registered marks. The two readings differ by up to a month, so Signa serves the shorter one to the straddling cohort: every CN publication from 1 October 2026 (the first whose three months would still be open at commencement) is now given two months. A mark published 31 December 2026 closes 28 February 2027, not 31 March 2027. A close published too early costs a would-be opponent nothing they can lose by relying on it; one published too late costs the right itself. The call is reversible and will flip the day a transitional notice or the revised Implementing Regulations settles the question. (This supersedes the “Applications published in November and December 2026 keep three months” sentence in the CNIPA entry below.) Reindex: CN opposition windows are index-baked, but CNIPA is a planned office with no indexed records, so there is nothing stale. Philippines: the advisory extension is era-aware. IPOPHL MC 2022-013 introduced the once-only 45-day extension on 30 June 2022. A window that closed BEFORE that date is now served the earlier regime instead: three 30-day extensions on motion, capped at 120 days from publication (MC 16-007 § 12). Display-only:common_extension never affects window_closes.
Switzerland (Madrid): the served citation is the operative one. A CH
Madrid window used to cite MSchG art. 31(2), whose words run the period “after
the publication of the registration”, the national trigger, which this rule
never uses. It now cites MSchV art. 50(1), the provision that actually fixes
day zero at the first of the month following the WIPO Gazette issue. No date
moved; source on the response and sources[0] in the catalog change.
Version stamps. ca_opposition, bx_opposition, ch_opposition_madrid
and ph_opposition report a new last_verified / rule_version of
2026-09-03. BX and CH had moved served values in an earlier release without
moving the stamp. Canada’s two common_extension notes also now name the
CIPO practice notice section in full (“section X.1, Extensions of time -
benchmarks”) instead of an abbreviation that read as an unfilled placeholder.
No computed date moved for CA, CH, BX or DE.
September 3, 2026: maintenance deadline corrections (EU, MX, NO, CA)
Five corrections toPOST /v1/deadlines/compute, the derived block on a
trademark, and portfolio deadline rows. Maintenance deadlines are computed at
request time, so every change below is live the moment it deploys, so no
reindex is needed and no stored date changes.
A missed EU renewal’s restitutio date moves earlier, by up to two weeks.
EUTMR Article 104(2) admits an application for re-establishment “within the
year immediately following the expiry of the unobserved time limit”, less the
Article 53(3) further six months, so the long stop is the renewal expiry plus
twelve months. Signa counted those months from the grace expiry as served,
which had already absorbed one Article 69(1) working-day extension, and then
extended the sum again. A EUTM filed 21 December 2014 was told its restitutio
window ran to 5 January 2026; it runs to 22 December 2025. EUIPO Guidelines
Part E §7.4.2 states the rule the fix implements: the extension “applies only
once and to the end of the basic period”. The window still OPENS on the grace
expiry as served. The same single-extension arithmetic now applies to every
restoration window (EU, GB, IN, IS, JP, SG); where the grace expiry did not
move, nothing changes.
A Mexican Madrid designation now renews on WIPO’s calendar. The renewal of
an international registration designating Mexico is paid to WIPO’s
International Bureau under Madrid Protocol Article 7 (IMPI never receives it),
so Reglamento LPI art. 4o does not reach it. An IR registered 29 February 2004
was given a Mexican due date of 1 March 2014 under art. 4o’s month-end
overflow, one day after the international registration had actually lapsed;
it is now due 28 February 2014, exactly matching the WIPO row for the
same registration, with holiday_calendar: "wipo_geneva". Mexico’s three-year
declaration of use is a Mexican filing on IMPI’s own grant date and is
unaffected.
Norwegian renewal due dates are no longer rolled. Betalingsforskriften § 6
extends a frist, and the § 33 renewal request period is one, so its late end,
the grace expiry, still rolls to the next virkedag. The due date is not a
frist: it is the end of the registration period, and varemerkeloven § 33 første
ledd tredje punktum charges the tilleggsavgift for a request delivered “etter
utløpet av registreringsperioden”. A due date served on the Monday would have
advertised a surcharge-free filing day after the period had already ended. A
Norwegian mark filed 1 May 2016 is due 1 May 2026, not 4 May, and its
due_date_adjustment reads not_checked. Grace expiries are unchanged. This
is the same treatment Australia has had since the s 223A(1) wiring, and
GET /v1/deadline-rules now says so explicitly (below).
An office-stated 29 February expiry no longer returns an empty schedule. A
mark whose office-reported expiry fell on a leap day could return zero
deadlines: a live EUTM two months from expiry, with nothing to file against.
Three separate pieces of leap-day arithmetic compounded; all three are fixed,
and such a record now returns its renewal row on the office’s own date.
Canada: last_renewal_date is a new optional field on compute. Trademarks
Regulations s. 159 opens the first post-17-June-2019 renewal window at the
period start, and it keys on the renewal, not on the cycle’s due date. A
registration whose term ended shortly before that day but whose fee was paid in
the grace period on or after it is the s. 159 renewal; the one after it is an
ordinary s. 76 renewal. Send last_renewal_date on a compute item and Canada
uses it. Omit it and the previous due-date behaviour is unchanged.
GET /v1/deadline-rules and the get_deadline_rules MCP tool gain
grace_expiry_rolls_only. A boolean, present on every row. When true, the
jurisdiction rolls its grace expiry but never its renewal due date, which is
what Australia and Norway do. weekend_holiday_rule: true alone could not
express that, so a docketing system reading the catalog had no way to tell a
scoped roll from a full one. Additive: no existing field changed.
September 3, 2026: China (CNIPA) deadlines and opposition windows
New jurisdiction.POST /v1/deadlines/compute, POST /v1/oppositions/compute,
the derived block on a trademark, GET /v1/deadline-rules and
GET /v1/opposition-rules now answer for Chinese marks. Three rules ship:
cn_renewal, cn_opposition and cn_opposition_madrid. office: "CN" is
accepted on the oppositions endpoint and comes back as CN.
A Chinese term counts its first day. Under Implementing Regulations
art. 12(2) a registration’s ten years run from the day the office approves it
and INCLUDE that day, so the term ends the day BEFORE the anniversary: a mark
registered 7 March 2016 expires 6 March 2026, not 7 March. The 12-month
renewal window and the 6-month grace period are measured from that expiry.
Where the anniversary day does not exist in the target month, the expiry is
the last day of that month instead: a mark registered 29 February 2020
expires 28 February 2030.
Opposition: three months now, two from 1 January 2027. Trademark Law
art. 33 gives three months from the preliminary-approval publication
(初步审定公告, not the registration publication), counted from the day after
and ending on the same day-of-month three months later. The 2026 revision of
the Trademark Law cuts that to two months in its renumbered art. 36 and enters
into force on 1 January 2027 (art. 87). Both eras are modelled now, selected
by the publication date, and each window is served the article that states its
own length. Applications published in November and December 2026 keep three
months: the revision carries no transitional provision, and that is the
non-retroactive reading.
Madrid designations of China use a different anchor. CNIPA does not
republish an international registration, so the window runs off the WIPO
Gazette: Implementing Regulations art. 45(1) opens it on the FIRST DAY OF THE
MONTH FOLLOWING the Gazette issue and runs three months to the last day of the
third month, which is CNIPA’s own worked example (Gazette 16 January 2012 →
1 February to 30 April 2012). Supply the Gazette issue date as the publication
date for these rows.
Holiday calendar, and where it stops. Chinese deadlines roll to the first
working day when they fall on a statutory holiday, and the calendar is built
from the State Council’s annual holiday notice, including the make-up working
weekends (调休), where a Saturday or Sunday is declared a working day. A
renewal due on Friday 2 January 2026 is due on Sunday 4 January 2026, the
first working day, not Monday the 5th. Because each year’s notice is published
only the preceding November, coverage runs 2024–2026: dates beyond it are
reported unrolled rather than rolled against a guess: renewals with
due_date_adjustment: "not_checked", and an opposition window with its close
on the exact statutory day. Unrolled means EARLIER than the true date, never
later. The one exception is a window that closed within the last 20 days
beyond coverage, where a roll could still be holding it open: there the window
is returned unsupported_reason: "window_not_computable" with its rule
identity intact rather than risk labelling a live window closed. Coverage
extends when the 2027 notice is published.
Reindex: none needed today. Opposition windows are baked into search
documents at index time, so a new rule normally reaches already-indexed
documents only after a reindex. Here there is nothing to reindex: CNIPA is a
planned office and Signa holds no Chinese records in the search index yet, so
no stored value changes and no document can be stale. Request-time surfaces
(/v1/deadlines/compute, /v1/oppositions/compute, the derived block, the
rule catalogs) answer for China on deploy, and the index-time path will pick
the rules up with the first CNIPA ingestion. Should any Chinese records be
indexed before then, they would need a reindex to gain
opposition_window_opens / opposition_window_closes; nothing they carry
would be wrong.
September 3, 2026: Benelux opposition windows before 1 October 2013 corrected
Historical dates change forbx_opposition. The two-month Benelux
opposition period has not always run from the publication day. Until
30 September 2013 BVIE art. 2.14(1) counted it “te rekenen vanaf de eerste dag
van de maand volgende op de publicatie van het depot”, from the first day of
the month FOLLOWING publication. The Protocol of 22 July 2010 (art. I.D)
replaced those words with “te rekenen vanaf de publicatie”, and it entered
into force on 1 October 2013 (Trb. 2013, 135).
Signa was applying the current text to every publication, however old. A
Benelux application published on 12 June 2013 was reported as open from
12 June to 12 August 2013 when the window the law gave ran from 1 July to
1 September 2013, a close up to 30 days EARLY. Only publications before
1 October 2013 are affected, every one of those windows is long closed, and no
status changes; what changes is the pair of dates we report about them,
which matters wherever a historical window is cited in a dispute or an audit
trail. The rule carries both the superseded article text and the amending
Protocol as pinned, era-bounded citations, so a pre-2013 window is served the
text that actually governed it. (This entry originally said
GET /v1/opposition-rules reported the era behaviour through
window_starts_on / window_ends_on. It did not; those fields describe the
current era only. The era fields shipped on 3 September 2026; see the entry at
the top of this changelog. BX now reports window_change_date: "2013-10-01",
window_starts_on_before: "first_of_following_month" and
window_ends_on_before: "corresponding_day_of_start", with
window_ends_on: null.)
Era selection keys on the publication date, which is the only date either text
can be read on. Neither Protocol carries a transitional provision. One
documented limit follows: for a mark published between 1 August and
30 September 2013 the old text’s window was still running when the new text
took effect, and no source says which governs. We serve the old rule, and
therefore the later close, which is the conservative direction for anyone
deciding whether they may still oppose.
Reindex. Opposition windows are baked into search documents at index time,
so pre-2013 Benelux documents keep the old opposition_window_opens /
opposition_window_closes values until BOIP records are reindexed. Every
affected window is closed and none of them can change opposition_status, so
this is low priority and belongs with the next natural BX reindex rather than
with a dedicated run. Request-time surfaces are correct on deploy.
September 3, 2026: German Madrid designations get an opposition window
New rulede_opposition_madrid. An international registration designating
Germany had no opposition window at all: POST /v1/oppositions/compute, the
derived block, GET /v1/opposition-rules and watch diagnostics all returned
nothing for a DPMA Madrid row. That was honest, because the rule could not
be expressed, but silent, and the deadline it hides is a hard statutory bar.
MarkenG § 114(1) puts the WIPO gazette in the place of the Markenblatt
publication of a national registration, and § 114(2) starts the § 42(1) three
months on the first day of the month following the gazette’s issue month.
Because that start is the beginning of a day, BGB § 187(2) counts it and
§ 188(2) Alt. 2 ends the period the day before the corresponding day: the
last day of the third month. A gazette issued in March 2026 opens the window
on 1 April 2026 and closes it on 30 June 2026; an issue in November 2026 runs
1 December 2026 to 28 February 2027, which is a Sunday, so BGB § 193 and
DPMAV § 18a roll it to 1 March. The fee (250 EUR, plus 50 per further sign)
falls due inside the same period, and the window is not extendable.
MarkenG § 91(1) sentence 2 bars even Wiedereinsetzung.
Worth noting next to the Swiss correction in this same release: Germany and
Switzerland start their Madrid windows on the same day and close them one day
apart. MSchV art. 2 ends a Swiss period on the corresponding day, BGB § 188(2)
Alt. 2 ends a German one the day before. window_ends_on on
GET /v1/opposition-rules reports which reading each rule applies. No German
source gives a worked example of the end day, so it is derived from the two
BGB provisions and cross-checked against the DPMA’s own Richtlinie W 7736,
which states the start in the office’s voice; the derivation is recorded in
the evidence pack rather than asserted.
Reindex. Opposition windows are baked into search documents at index time,
and DE Madrid documents currently carry null windows, so the
opposition_status and opposition_closes_before / opposition_closes_after
filters will not see this rule until German Madrid designations are reindexed.
Request-time surfaces are correct on deploy. As for Switzerland, the reindex
only becomes meaningful once designation records carry the WIPO gazette
publication date the rule anchors on.
September 3, 2026: Swiss Madrid opposition windows close up to 30 days earlier
Computed dates change forch_opposition_madrid, in the safe direction.
The opposition window against an international registration designating
Switzerland does not run from the day the WIPO Gazette published the
designation. MSchV art. 50(1) starts it on the first day of the month
following the Gazette month, and MSchV art. 2 ends a month period on the
same-numbered day, so the window closes on the 1st of the fourth month. The
IGE publishes the worked example: a Gazette of 19 July 2022 opens the window
on 1 August 2022 and closes it on 1 November 2022.
Signa was computing “Gazette day plus one month” to “Gazette day plus four
months” instead. That is the same answer only when the Gazette date is itself
the 1st; for every other issue the close we published was up to 30 days
later than the law allows. A Gazette of 15 January 2026 was served a close
of 15 May 2026 where the true, non-extendable deadline is 1 May 2026. Later
than the truth is the dangerous direction on an opposition bar, so this is a
correction customers should re-docket: every Swiss Madrid close moves earlier
by nought to thirty days, and every open moves to the 1st of the month.
GET /v1/opposition-rules now reports window_starts_on: "first_of_following_month" and window_ends_on: "corresponding_day_of_start"
for this rule, and window_starts_offset_months is null. Both enums are new
and additive; no existing value changed meaning. Trademark responses, the
oppositions compute endpoint, the derived block and watch evaluation
recompute the window per request, so they are correct as soon as this deploys.
Reindex. Opposition windows are baked into search documents at index time,
so opposition_status and the opposition_closes_before /
opposition_closes_after filters carry the old arithmetic until Swiss Madrid
documents are reindexed. In practice there is nothing to correct yet: a
designation is indexed as part of its international-registration family, and
IR-family documents carry null opposition windows today, while the Madrid
source we ingest publishes no per-designation publication date for the rule to
anchor on. The reindex therefore belongs with the work that starts storing the
WIPO Gazette publication date for designations, not with this change.
September 3, 2026: Norway Madrid opposition, and a publication-date guard for every Madrid rule
New rule.no_opposition_madrid covers an international registration
designating Norway. Patentstyret publishes in Norsk varemerketidende that the
IR has effect in Norway (varemerkeloven § 70 annet ledd, varemerkeforskriften
§ 32), and § 71 første ledd gives anyone three months from THAT
kunngjøringsdag to oppose, applying § 26 correspondingly. So every mechanic of
the Norwegian domestic rule carries over by statute rather than by copy: the
count starts on the publication day itself, the three-month period ends on the
corresponding day-number, it rolls off 24 and 31 December, Saturdays,
helligdager and likestilte dager under betalingsforskriften § 6, and it cannot
be extended. There is no WIPO offset: § 71 runs straight from Patentstyret’s
own publication, unlike EUIPO’s Madrid-EU rule. The 18-month Madrid refusal
limit is an obligation the office owes WIPO and never changes the three months
the parties get. GET /v1/opposition-rules, POST /v1/oppositions/compute
(office NO, filing route madrid) and the derived block on a Norwegian
Madrid designation now answer instead of returning nothing.
One documented limit. The rule reports effective_from: "2010-07-01" and
applicable_from_date: "2010-07-01", the day varemerkeloven (the Act § 71
belongs to) entered into force (res. 25. juni 2010 nr. 936). Before it the
repealed 1961 Act § 21 gave TWO months from the kunngjøringsdag, an era we do
not model on the Madrid route, and serving the modern three months to it would
report a close date a month LATER than the law gave. A Norwegian designation
published before 1 July 2010 therefore comes back supported: false rather
than with a window.
No reindex required. This adds a window where there was none; it changes
no existing window. Baked opposition_window_opens / opposition_window_closes
values in the search index are all still correct. Norwegian Madrid
designations pick their new window up at their next natural reindex.
A guard against the wrong publication. A Madrid designation has two
publications that can fill one date field (WIPO’s Gazette of the
international registration, and the designated office’s own journal
republication), and different offices run their clock from different ones.
Feeding a rule the other one silently produces a plausible-looking, wrong
statutory bar. Each Madrid rule now declares which publication it needs, and
POST /v1/oppositions/compute accepts an optional publication_date_kind
(office_journal, wipo_gazette, office_register, unknown) saying which
one your date is. When the two disagree the response is status: "unknown"
with null dates and the rule’s identity intact, rather than a date you should
not act on. A new nullable reason field on each
POST /v1/oppositions/compute item and on the trademark
derived.opposition_window block says WHY it is unknown
("publication_date_kind_mismatch" today, null otherwise), so you can tell a
contradicted publication kind from a mark that simply has no publication date
yet; the field is additive and null on every response that had no reason to
carry it. Omit the field and nothing changes. Today EVERY Madrid rule
declares its publication: ch, de and fr run from the WIPO Gazette; no,
fi, pl, sg, us, ca, au, eu, jp, kr, in and tr run from
the designated office’s own journal.
Declaring it is not optional in practice. A WIPO-feed leg is resolved by
jurisdiction, and the date it carries is the Gazette’s, so a rule that has
NOT adjudicated which publication it runs from is refused on that path
outright rather than dated on a publication nobody established it uses. The
four Asian Madrid rules (jp, kr, in, tr) were adjudicated for this
release; each of their statutes names the office’s own gazette and says the
WIPO Gazette is not the trigger.
September 3, 2026: EU restitutio, Canada’s transitional renewal window, India’s priority-dated term, and WIPO closure days
Four deadline corrections, all computed at request time. Nothing is baked into the search index, so every one of them is live the moment this deploys and no reindex is involved. The EU now has a restoration deadline.POST /v1/deadlines/compute,
GET /v1/deadline-rules and the derived block on an EU trademark return a
new restoration row once a renewal has passed its due date, under one new
rule_id: eu_restitutio. It runs from the end of the six-month grace period
to twelve months after the registration expired, which is what Article 104(2)
EUTMR leaves after deducting the further six months of Article 53(3) from the
year following the missed time limit, and what the EUIPO Guidelines state in
one sentence: the one-year period “starts on the day on which the protection
ends and not on the expiry of the further 6-month grace period”. Read the row
as an outer date, not as a promise. Restitutio is discretionary: it is granted
only where all due care required by the circumstances was taken, it carries a
fee, and it must also be requested within two months of the removal of the
obstacle, a date no register publishes. No existing EU date moves.
Canada’s first renewal after 17 June 2019 opens far earlier than we said.
For a trademark that was on the register before that day, Trademarks
Regulations s. 159 lets the renewal fee for the FIRST renewal falling due on or
after it be paid from the start of the period being renewed, with no six-month
early limit, and CIPO says so directly: “there is no restriction on how early
the renewal fee for the first renewal after June 17, 2019 may be submitted.”
The engine used to report that window opening six months before the due date.
window_opens on the affected cycle now moves back to the day of registration
or of last renewal, which can be fifteen years earlier. Only that one cycle is
affected; the due date, the grace expiry and every later cycle are unchanged,
and the window can only widen, so nothing that was filable becomes unfilable.
An Indian trademark with a convention priority claim expires earlier than its
filing date implies. Trade Marks Act 1999 s. 154(2) registers a Paris or WTO
convention application as of the date the application was made in the
convention country, and s. 23(1) is expressly subject to it, so the ten-year
term of s. 25(1) runs from the priority date, up to six months before the
Indian filing. POST /v1/deadlines/compute accepts a new optional
priority_date on each item; send it for an IN item and the renewal is
computed from it, with trigger_field reading priority_date so the answer
says which date it used. Omit it and India falls back to the filing date
exactly as before. The field is inert for every other jurisdiction: no other
pinned term provision runs from a priority date. Note the current limit: our
own stored trademarks carry priority claims in a separate record, so the
derived block, portfolio deadline lists and the iCal feed do not yet pass one
and still serve the filing-date answer for that cohort, which is the later
date. Where the office states an expiry, that expiry already anchors the
schedule and the question does not arise.
WIPO renewal dates now move off days the International Bureau is closed.
Rule 4(4) of the Regulations under the Madrid Protocol extends a period that
expires on a day the IB is not open to the public to the first subsequent day
it is, and a renewal payment is a communication the IB must receive. WIPO rows
now report holiday_calendar wipo_geneva, and a due date or grace expiry
that falls on a weekend or on one of the eight days WIPO published for 2026
(1 January, 3 and 6 April, 14 and 25 May, 31 July, 25 and 31 December) is
served on the next open day with the adjustment field reading moved. An
international registration dated 13 June 2016, for example, was renewable
“by 13 June 2026”, a Saturday; the answer is now Monday 15 June 2026. The
International Bureau publishes its closure list one year at a time, so the
calendar covers 2026 only: dates in any other year are emitted exactly as the
Rule 4(1) and 4(2) arithmetic produced them and report not_checked rather
than a business-day guarantee we cannot make. Filing-window opening dates are
never rolled, on any office.
Every value above cites the instrument it comes from, with a verbatim quote and
a hash-pinned snapshot, on GET /v1/deadline-rules and on each compute
response.
September 3, 2026: Mexican OPPOSITION windows follow the same month-overflow rule, and the overflow is now reported
Opposition close dates change for MX (IMPI). Reindex MX. Earlier today Signa applied Reglamento de la Ley de la Propiedad Industrial art. 4o, párrafo segundo to the Mexican maintenance ladders: a period counted in months that ends on a day the target month does not have runs into the following calendar month and ends on its first business day, rather than clamping to the short month’s last day. The opposition engine kept the clamp, which was stated as a limit in that release. It no longer does. Art. 4o computes «los plazos establecidos en meses o años a que se refiere el artículo 184 de la Ley», and art. 184 LPI (re-enacted word for word as LFPPI art. 21) is the Law’s general period-computation article, not a maintenance-only provision. The one-month opposition period of LFPPI art. 221 is a period fixed in months by the Law, so it is inside art. 4o. An application published on 31 March 2026 now closes for opposition on Monday 4 May 2026, not 30 April: April has no 31st, so the period runs into May, and May 1 is Día del Trabajo with the weekend behind it. A publication on 31 August 2026 closes 1 October instead of 30 September. Publications whose day number exists in the next month are untouched. Every corrected date is LATER than the one Signa served before, so nobody who relied on the old date filed late.GET /v1/opposition-rules gains month_end_overflow on every rule, so a
client that recomputes a window from the rule can reproduce the close date.
It reads last_day everywhere except mx_opposition.
The overflow move is now reported. due_date_adjustment and
grace_expiry_adjustment on POST /v1/deadlines/compute gain a fourth value,
month_end_overflow. Before this, an overflow that landed on an open day was
indistinguishable from a date nothing had happened to: the fields described the
weekend and holiday roll only, so they read unchanged. The new value
subsumes the roll on such a date, because art. 4o para. 2 names the first
BUSINESS day of the following month, so the move into the next month and the
roll that completes it are one statutory step. The addition is additive: no
existing value was renamed or removed.
Opposition windows are baked into the search index at index time, so the
materialised opposition_status and
opposition_closes_before/opposition_closes_after filters on MX documents
are corrected only after MX is reindexed. POST /v1/oppositions/compute
and the trademark response recompute per request and are correct as soon as
this deploys.
September 3, 2026: Mexican deadlines now roll, month-overflow ends in the next month, and Madrid designations renew on the international registration
Computed dates change for MX (IMPI), on both engines. Reindex MX. Mexican maintenance dates were published raw: a renewal that fell on a Sunday or on a day IMPI declares inhábil was served on that day. Reglamento de la Ley de la Propiedad Industrial art. 4o, the 1994 regulation the LFPPI keeps in force, says otherwise in its third paragraph, and Signa now applies it. A renewal due date, grace end or 3-year declaration-of-use window end that lands on a weekend, on a fixed Mexican holiday or on a día inhábil IMPI has published moves to the next working day,holiday_calendar reads mx_mexico, and the
two adjustment fields read moved or unchanged. Filing windows never move:
a window that opens on a closed day cannot be filed that day, and moving it
would shorten the statutory six months.
The same article’s second paragraph fixes a subtler error. When a period
counted in months or years ends on a day the target month does not have: a
six-month grace counted from a 31st, landing on “31 February”. Mexico does not
clamp to the 28th the way most offices do. The period ends on the first
business day of the following calendar month. A grace period that used to
read 28 February 2033 now reads 1 March; in a leap year, 29 February 2036
becomes Monday 2 March 2036. This is the first office in the corpus to depart
from the month-end clamp, and it is behind a per-office flag, so no other
jurisdiction’s dates move.
The IMPI holiday calendar was rebuilt from the Diario Oficial. It carried a
flat “IMPI closes 16 to 31 December, every year” block that no published
acuerdo supports. IMPI sets its year-end closure annually: 18 December to
2 January for 2024, 19 December to 3 January for 2025, 22 December to 6 January
for 2026. So the old calendar closed four days IMPI works and opened five days
it does not, in both directions. It also omitted 5 May and 1 September, which
four published acuerdos name. The calendar is now eleven recurring days plus
exactly what each pinned acuerdo states, including the one-off closures of
1 October 2024, 12 December 2025, 23 February 2026 and 30 June 2026.
Madrid designations of Mexico now renew on the right date. A designation
has no independent Mexican term: it expires with the international
registration and is renewed centrally at WIPO. The rule that served it was
Mexico’s national “renewal plus declaration of use”, which the engine anchored
on IMPI’s grant date, and for a designation granted years after the international
registration, that is a renewal date up to a decade too late. There is now a
separate rule, mx_renewal_madrid, anchored on the international registration
date, and a designation whose international registration date is unknown and
whose office expiry is not on the record DECLINES with
requires_office_date instead of publishing a guess. The declaration of use
that follows a Madrid renewal runs three months from the International
Bureau’s notice, a date no record carries, so Signa deliberately publishes
nothing for it rather than a wrong date.
Every Mexican value is now cited to the Diario Oficial de la Federación itself
(the primary publication) with a verbatim quote and a pinned snapshot, with
the consolidated ordenjuridico.gob.mx copies kept alongside. That includes the
eight IMPI acuerdos behind the calendar.
Three limits are stated rather than hidden. IMPI publishes each December’s
closure in the preceding autumn, so a year with no published acuerdo has no
closure in Signa: a date in late December 2026 or later is served un-rolled,
which is earlier than the true date, never later. The opposition engine still
applies the ordinary month-end clamp rather than art. 4o’s overflow rule, again
in the earlier direction. And the overflow move itself is not reported in the
adjustment fields, which describe the weekend and holiday roll only.
Trademark responses and POST /v1/deadlines/compute recompute per request, so
they are correct as soon as this deploys. Opposition windows are baked into the
search index at index time, so the materialised opposition_status and
opposition_closes_before/opposition_closes_after filters on MX documents
are corrected only after MX is reindexed.
September 3, 2026: Australian renewal grace periods roll onto the next open day
An Australian trade mark can still be renewed for six months after it expires (Trade Marks Act 1995 s 79). When the last day of that six-month period falls on a weekend, a Canberra public holiday or IP Australia’s standing Christmas close-down,POST /v1/deadlines/compute and the derived block on a trademark
now serve the next day the office is open, and say so in
grace_expiry_adjustment (moved) and holiday_calendar (au_australia).
Australian grace dates were previously served one to three days EARLY.
The renewal DUE date deliberately does NOT move, and this is the only office
where the two answers differ. s 223A(1) rolls “the last day of a period
provided by this Act (except this section) for doing an act”; the s 79 period
is one, reg 21.24A supplies the prescribed circumstance and reg 21.24C, the
exclusion list, does not reach a renewal request. The twelve-month renewal
REQUEST period is a different animal: it is prescribed by reg 7.3 rather than
by the Act, and Schedule 9 item 10 keys the $100-per-month surcharge on the
request being made “after the expiry date to which section 79 of the Act
refers”: the expiry day itself. Serving a later due date would tell you that
you may still renew fee-free on the Monday when the surcharge may already have
attached on the Saturday. So an Australian due_date stays on the statutory
expiry and reports due_date_adjustment: "not_checked" on every row, whatever
day of the week it lands on: no calendar was consulted for it, and unchanged
would claim a Saturday is a business day.
Nothing else about the Australian rule changed: same rule_id (au_renewal),
same ten-year term, same twelve-month window, same six-month grace, same
consequence. Three provisions are newly pinned and quoted verbatim next to the
field they move: s 223A(1), reg 21.24A, and reg 21.24C in full, so that the
absence of a renewal request from the exclusion list is verifiable rather than
asserted. Maintenance deadlines are computed per request, so this is live as
soon as it deploys and no reindex is required. It supersedes the “Australia is
deliberately NOT rolled” note in the entry below.
September 3, 2026: renewal dates roll on closed office days in Norway, France and Iceland, and on BOIP’s own closing days in the Benelux
Four offices join the maintenance rollover: a renewal due date or grace expiry that lands on a day the office is closed is now served on the next day it is open, instead of on the exact calendar date.POST /v1/deadlines/compute and
the derived block on a trademark answer with the moved date and say so in
due_date_adjustment / grace_expiry_adjustment (moved, unchanged or
not_checked) and holiday_calendar. Nothing about a rule id, a window
length or a consequence changed; only the served dates.
Each office rolls on the provision that governs its own renewal deadline, not
on a generic weekend rule. Norway: betalingsforskriften § 6 første ledd (24 and
31 December, Saturdays, helligdager and days the legislation treats as
equivalent), extended to varemerkeloven deadlines by § 6 tredje ledd. France:
CPI R. 718-2 al. 5, applied to the renewal declaration by INPI’s own renewal
directives, which work the example: a mark expiring Saturday 14 May 2022 could
be renewed on Monday 16 May with no late-renewal fee. Iceland: Stjórnsýslulög
nr. 37/1993 8. gr., which extends a period ending on a general public holiday
to the next day the authority is OPEN. Benelux: Uitvoeringsreglement regel 3.9,
lid 3. Every one is pinned and quoted verbatim next to the field it moves.
Two office calendars were corrected from primary sources in the same change,
and both corrections can move a date on their own.
The Benelux calendar is now BOIP’s own closing-day list, published as a Regel
van de Directeur-Generaal of 3 April 2019, rather than an assumed Dutch
national-holiday set. Ten days join it: 2 January, 1 May, Europe Day, the
Luxembourg and Belgian national days, Assumption, All Saints, All Souls,
Armistice Day and the Belgian King’s Day, and Good Friday LEAVES it, because
the rule names it on neither limb and BOIP is open that day. A Benelux deadline
falling on Good Friday is therefore due that day, not the following Tuesday.
Iceland’s 24 and 31 December STAY CLOSED, and no Icelandic date moves on that
account. An earlier draft of this release opened both days: they are public
holidays only FROM 13.00 under lög nr. 88/1971 6. gr. (24 December only from
18.00 as a church holiday, lög nr. 32/1997 2. gr.), so the statute alone gives
a half day, and no ISIPO closure notice had been found. One was then found:
Hugverkastofan’s own December 2020 notice, which says the office is closed on
Þorláksmessa, aðfangadagur and gamlársdagur and that every deadline falling in
that period moves to the next opening day. The office’s own statement settles
the office’s own opening days, so both remain closed, exactly as before this
release. See “Philippines, India and Iceland business-day calendars
re-sourced” below.
Benelux opposition windows DO move, because Good Friday left bx_benelux.
Opposition windows are materialised into search documents at index time, so
opposition_status and the opposition_closes_* filters carry the corrected
dates for BX records only after that office is reindexed. Every trademark
response recomputes the window per request and is correct as soon as this
deploys, and maintenance deadlines are computed per request throughout, so no
reindex is needed for them.
Australia was NOT rolled in this change, and the reason was documented rather
than hidden: Trade Marks Act 1995 s 223A(1) settles the six-month post-expiry
limb but not the due date, and the rollover was one switch that moved both
dates. SUPERSEDED the same day by the entry above, which gives the engine a
grace-only roll and turns it on for Australia.
Two accuracy limits are recorded with the same candour. INPI closure decisions
before 2026 were never fetched, so a French date that fell on a pre-2026 closure
day is served un-rolled. BOIP publishes any FURTHER closing day for a given year
on a page that is not reachable programmatically, so those ad-hoc days are not
modelled either. Both under-roll rather than over-roll.
September 3, 2026: EUIPO Article 2 days now extend time limits; consequence_if_missed vocabulary fixed
EU dates move later on four days a year. The euipo_alicante calendar
now carries BOTH lists of the Executive Director’s annual decision on
non-working days: the Article 1 days on which the Office is closed AND the
Article 2 days on which the Office is open but ordinary post is not received
(19 March, 23 June, 9 October, 8 December in EX-24-9 for 2025 and EX-25-16
for 2026). Article 69(1) EUTMDR extends a time limit expiring “on a day on
which the Office is not open for receipt of documents or on which … ordinary
post is not delivered in the locality in which the Office is located … until
the first day thereafter on which the Office is open for receipt of documents
and on which ordinary mail is delivered”, and the Office’s own decision reads
it the same way (EX-24-9 recital (1)(b)). Until now only Article 1 days
rolled, which served the earlier date; the served date is now the statutory
one. Affected: POST /v1/oppositions/compute and opposition_window for
EM marks whose window closes on one of those days (e.g. a Part A
publication on 9 July 2026 now closes 13 October 2026, not 9 October), the
EU office-action response deadlines, and the watch-evaluator’s opposition
windows. Opposition windows are baked into the search index at index time, so
indexed EM documents carry the corrected close only after the EU reindex
(scheduled with this release). The 2027-2030 Article 2
days are carried on the same estimate basis as the Article 1 days and are
replaced each December from the published decision.
EU RENEWAL dates move on the same days. An earlier draft of this entry said
they did not, on the ground that the EU maintenance config does not
business-day adjust. It does now: the same release turns on the roll for EU
renewals, so a eu_renewal due date or grace expiry landing on any day the
Alicante calendar carries, Article 1 closures and Article 2 ordinary-post days
alike, is served on the next open day instead. A mark filed 19 March 2016 was
served a renewal due 19 March 2026 and a grace expiry 19 September 2026; it is
now due 20 March 2026 with grace to 21 September 2026, because 19 March is San
José, an Article 2 day. The direction is later. For an Article 1 day that is
unambiguously the safe direction: the Office is shut on the original date, so
the served day is the first one on which you can actually file. For an
Article 2 day it is a judgement call, and this entry originally overstated
it, on 19 March the Office is open, and only ordinary post is not delivered
in Alicante. Signa rolls it on the reading of Article 69(1) EUTMDR that the
Office’s own decision states (EX-24-9 recital (1)(b)), which covers a day on
which “ordinary post is not delivered” as well as a closure. An e-filer can
nonetheless file on the original day, so if the Office ever reads Article 69(1)
as extending only for post-borne filings, the served date is a day LATER than
the true one. That is the unsafe direction, it is bounded at four days a year,
and it is now listed in
Accuracy limits. due_date_adjustment and
grace_expiry_adjustment read moved on those rows and unchanged on the
rest, so a row always says whether a calendar was consulted. Renewal dates are
not baked into the search index, so no reindex is needed for this half.
consequence_if_missed now means one thing per value. The value names
the mechanism the office’s pinned provision prescribes: expiration (the
right ends by operation of law), removal_from_register (the office strikes
the entry as the statutory consequence), cancellation (the office cancels a
still-running registration for a missed maintenance filing, US §8/§71),
and restorability is said only by the presence of a restoration rule. Nine
rules were relabelled to match their pinned text; no date moved:
pl_renewal cancellation → expiration (PWP art. 168 ust. 1 pkt 1
“wygasa”), fr_renewal cancellation → expiration (CPI L. 712-1),
de_renewal cancellation → removal_from_register (§ 47 Abs. 6 MarkenG
“gelöscht”), dk_renewal cancellation → removal_from_register
(varemærkeloven § 37 “udslettelse”), eu_renewal cancellation →
removal_from_register (Art 53(8) EUTMR “cancel the mark from the
register”), bx_renewal irrevocable_loss → expiration (BVIE art.
2.26(a)), ch_renewal irrevocable_loss → removal_from_register (MSchG
art. 35(b)), mx_declaration_of_use_3yr irrevocable_loss → expiration
(LFPPI art. 233 “caducará de pleno derecho”), th_renewal
removal_from_register → expiration (Trademark Act s. 56 deems the
registration revoked). irrevocable_loss is retired: no rule serves it. The
full vocabulary is in the deadline rules
guide. No wire-format change:
the field stays a string and no new value was added.
September 3, 2026: Philippines, India and Iceland business-day calendars re-sourced
Three office calendars used for business-day adjustment now rest on the primary instruments that actually set the closed days, and two of them change published dates. Philippines (ph_philippines, used by ph_opposition). The closed days
are now transcribed year by year from the presidential proclamations that
declare them, Proclamations 368 s. 2023, 453, 514, 579 and 665 s. 2024 for
2024; 727 and 729 s. 2024, 839, 878 and 911 s. 2025 for 2025; 1006 s. 2025,
1189 and 1264 s. 2026 for 2026, together with the statutory fixed days (RA 9492 s. 1,
RA 10966) computed for every year. Three curated days were wrong and move: Eid
al-Fitr 2025 is 1 April (not 31 March), Eid al-Adha 2025 is 6 June (not 7
June) and Eid al-Fitr 2026 is 20 March (not 21 March). Days the proclamations
make working days are now OPEN (25 February 2025 and 2026; 21 August 2024,
observed on 23 August), and days they add are closed (9 February 2024, 12 May
2025, 31 October 2025, 2 November 2026, every Christmas Eve). For 2027 onward,
until each year’s proclamation is pinned, only the statutory fixed days are
closed and the “Monday nearest” holidays are open: an opposition close on one
of those days is published un-rolled, which is never later than the true date.
The opposition extension note now cites IPOPHL Memorandum Circular 2022-013
itself: one 45-day extension, granted only once, on meritorious grounds,
reckoned from the original due date, in force 30 June 2022.
India (cgpdtm_india, new). Indian deadlines are now business-day
adjusted. The Trade Marks Registry observes the annual DoPT Office Memorandum
for central government offices; the 2024, 2025 and 2026 memoranda are pinned
and their 14 compulsory holidays per year make up the calendar. in_renewal,
in_restoration, in_opposition and in_opposition_madrid now report
holiday_calendar: "cgpdtm_india" and moved / unchanged for 2024–2026
dates: a renewal due on Sunday 15 June 2025 is served as Monday 16 June; an
opposition closing on Republic Day 2026 is served as 27 January. Dates after
2026 report not_checked until the 2027 memorandum is pinned. Three limits
are documented, all in the safe direction: the three branch-local optional
holidays (Mumbai, Delhi, Kolkata, Chennai and Ahmedabad differ), Ambedkar
Jayanti, and any moon-sighting shift of an Islamic day are not modelled, so a
deadline on one of them is published un-rolled.
Iceland (is_iceland). No date changes. 24 and 31 December stay closed,
now on the office’s own statement (Hugverkastofan’s December 2020 notice:
closed on both days, deadlines falling on them move to the next opening day)
and the statutes that make them half-day frídagar; 23 December stays open
because the office declares it year by year.
Trademark responses recompute opposition windows per request, so they are
correct as soon as this deploys. The materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters are baked
at index time: IN and PH search documents carry the rolled and corrected
closes only after those offices are reindexed. Maintenance rows are computed
per request and need no reindex.
September 3, 2026: Korea (KIPO) deadline and opposition rules
New jurisdiction.KR now has a maintenance config and two opposition rules,
so GET /v1/deadline-rules, GET /v1/opposition-rules,
POST /v1/deadlines/compute, POST /v1/oppositions/compute (office KR) and
the derived block on a trademark answer for Korean marks instead of
returning nothing. Three new rule_id values: kr_renewal, kr_opposition,
kr_opposition_madrid.
Renewal runs 10 years from the REGISTRATION date (상표법 제83조①), with a
12-month filing window before the term ends that closes on the expiry day and
a 6-month window after it at 330,000 KRW per class instead of 300,000
(제84조②, 제78조③). Korean law has no restoration of a missed renewal
application and no declaration of use, so neither is emitted: that absence is
the finding, not a gap. Opposition is 30 days from KIPO’s own 출원공고 for
applications published on or after 22 July 2025 (법률 제20697호), and 2 MONTHS
for publications before that day; an international registration designating
Korea is opposed on the identical window, running from KIPO’s publication
rather than the WIPO Gazette (제180조①). Every value cites the Act, the fee
rules or the KIPO publication it comes from, with a verbatim quote and a
pinned snapshot.
Two things about dates deserve a direct statement. First, the 22 July 2025
change is the first opposition pivot that switches UNITS (calendar months
before, a day count after), and the engine now resolves the era’s length with
its unit; nothing moves for any other office. Second, Korean deadlines are
business-day adjusted against the kipo_korea calendar, which this release
corrects from primary sources: 1 May (노동절) is now a closed day in every
year (상표법 제16조제4호 names it, and the shipped calendar had omitted it),
with a Saturday/Sunday substitute from 2026; 17 July (제헌절) is closed from
11 May 2026, when the amended 관공서의 공휴일에 관한 규정 made every 국경일 a
public holiday again; and 28 September 2026 is OPEN, because the regulation
substitutes a 설날/추석 day only when it falls on a Sunday and 26 September
2026 is a Saturday. A KIPO deadline that lands on one of those days moves
accordingly.
Four limits are documented rather than hidden. The renewal window_opens is
one day earlier than KIPO’s own count (KIPO opens the window the day AFTER
expiry minus one year); it is never rolled and never a deadline. Election days
and 임시공휴일 designated by government notice are not in the calendar until
the notice is pinned, so a deadline landing on one is published un-rolled:
earlier than the true date, never later. A renewal filed ON the expiry day is
modelled as surcharge-free, which is how KIPO’s example reads. And a Madrid
designation is computed only when its international registration date is
known: the KIPO connector must carry the IRN, and its publication date for a
designation must be KIPO’s own 출원공고일.
Trademark responses recompute opposition windows per request, so they are
correct as soon as this deploys. Only the materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters are baked
at index time, so KR search documents carry these values only after KR is
reindexed; no KR records are indexed today, so that reindex belongs with the
KIPO connector rather than with this change.
September 3, 2026: Türkiye dates now roll, pre-2018 renewal windows and the 2017 opposition straddle corrected
Computed dates change for TR (TÜRKPATENT), on both engines. Three of the limits documented when Türkiye landed on 2 September are closed. Business-day adjustment is now applied. A Turkish renewal due date, grace end or opposition close that falls on a Saturday, Sunday, one of the fixed holidays of Law 2429 (1 January, 23 April, 1 May, 19 May, 15 July, 30 August, 29 October) or a Ramazan or Kurban Bayramı day is served on the next working day, soholiday_calendar reads turkpatent_turkiye and the two adjustment
fields read moved or unchanged for dates in 2024 to 2030 (not_checked
outside that range, where the calendar is not curated). The bayram days come
from Diyanet İşleri Başkanlığı’s official tables for each year; the arefe half
days, the afternoon of 28 October and the Presidency’s ad-hoc administrative
leave days are working days and never move a date. This rests on a documented
convention rather than an office statement: no TÜRKPATENT source states how a
last day on a non-working day is treated before the office, and the roll
applies the rule the general procedural statutes give the courts (HMK 6100
m. 93/1, İYUK 2577 m. 8/2). Direction of the change: every affected date moves
LATER, by one to five days (for example, a renewal due on 1 May 2026, a Friday
holiday, is now served 4 May; an opposition closing on 27 May 2026, the first
day of Kurban Bayramı, is now served 1 June).
Renewal cycles whose anniversary fell before 10 January 2018 now show the
request window the repealed KHK 556 m. 41/3 gave them: window_opens and
due_date move to the last day of the anniversary’s month (up to 30 days
later than before), while grace_expiry stays on the exact anniversary plus
six months, because m. 41/5 anchors the lapse on the end of the term. Every
such cycle is historical (visible with include_missed); no current deadline
moves.
Opposition windows for applications filed before 10 January 2017 but
published on or after it now get the three months the KHK gave them (SMK
geçici m. 1/1 concludes an application under the law in force on its filing
date), one month later than before; the served citation follows. Windows for
applications filed on or after that date are unchanged. POST /v1/oppositions/compute accepts an optional filing_date per item for this;
omit it and the item falls back to the publication date, which yields the
shorter modern window. This filing-date key applies to national applications
(tr_opposition) only. Madrid designations (tr_opposition_madrid) stay keyed
on the publication date: a designation’s filing_date is the international
registration date, and a subsequent designation of Türkiye carries no date of
its own, so a filing-keyed pivot would have served a subsequent designation
made after 10 January 2017 on an older international registration three
months instead of the two SMK m. 18/1 gives it, one month too late. An
original designation on a pre-2017 international registration published on
or after 10 January 2017 is therefore served two months where the KHK
arguably gave it three; every such window closed in 2017.
Trademark responses and POST /v1/deadlines/compute recompute per request,
so they are correct as soon as this deploys. TR reindex required: the
materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters read
window dates baked at index time, so Turkish search documents carry the
rolled and filing-keyed close dates only after TR is reindexed.
September 3, 2026: Danish renewal dates on office closing days now roll
Computed dates change for DK (DKPTO). A Danish renewal due date or grace end that falls on a Saturday, Sunday, a Danish public holiday or one of DKPTO’s enumerated closing days is now served on the next working day, as the office’s own Varemærkehåndbog states (“Er sidste rettidige indbetalingsdato en dag, hvor Patent- og Varemærkestyrelsen ikke har åbnet … så er betaling førstkommende hverdag rettidig”) and as dkpto.dk/lukkedage confirms for the closing days (“På officielle lukkedage, vil alle frister automatisk blive forlænget til førstkommende hverdag”). Rows now readholiday_calendar: "dk_denmark" with moved or unchanged adjustments instead of
not_checked.
Direction of the change: dates move LATER only, by one to seven days (a mark
registered 10 January 2017 was due 10 January 2027, a Sunday, and is now due
11 January; a renewal due 28 December 2026 rolls through the 28 to 30
December closure, New Year’s Eve, New Year’s Day and the weekend to 4 January
2027). Marks whose dates already fall on a working day do not move. Computed
at request time; no reindex (maintenance deadlines are not indexed).
September 2, 2026: Philippines Renewal DAU window opens six months earlier
Computed dates change for PH (IPOPHL). Theph_declaration_of_use_renewal
rule (the Declaration of Actual Use due within one year of each renewal) used
to open its filing window at the renewal itself. IPOPHL’s Trademark
Regulations of 2023 (Memorandum Circular 2023-001, in force 14 February 2023)
say in Rule 206 that “The Renewal DAU may be filed within the six-month period
before the expiration of the registration”, so the window now opens six months
before expiry - together with the renewal window - for every renewal cycle
expiring on or after 14 February 2023. Cycles that expired before that day
keep the old window: the change is modelled as an era pivot inside the rule,
keyed on the cycle, not on today’s date, and a window for a cycle expiring
inside the first six months of the new regime opens on 14 February 2023
itself, because no filing could precede the Regulations that permit it.
Only window_opens moves. due_date and grace_expiry are unchanged (one
year after the renewal, no grace), and so is every other Philippine rule. The
customer-visible effect is an earlier window_open status: a mark registered
5 January 2020 now shows its first Renewal DAU window opening 5 July 2029
instead of 5 January 2030. Under the 2017 Regulations (MC 17-010) Rule 206 was
only a transitional trigger, which is why the earlier window is right for the
earlier cycles; both texts are pinned with verbatim quotes, and the in-force
date is pinned from WIPO Lex because the circular’s own Rule 1406 carries it
handwritten. Maintenance deadlines are computed per request, so no reindex is
involved.
September 2, 2026: Philippines Madrid designations get their own DAU anchors
Computed dates change for PH (IPOPHL) international registrations. Two newrule_id values, ph_declaration_of_use_3yr_madrid and
ph_declaration_of_use_5yr_madrid, serve marks on the madrid route. Under
IPOPHL’s Madrid Regulations (MC 17-011, Rule 20) the 3rd-year DAU of an
international registration designating the Philippines runs “within three
years from the date of the international registration” and the 5th-year DAU
“within one (1) year from the fifth anniversary of the date of statement of
grant of protection” - not from the national filing and registration dates the
ph_declaration_of_use_3yr and ph_declaration_of_use_5yr rules use. Those
two rules now apply to the national route only (applies_to: domestic); the
Madrid rules read applies_to: madrid_only, trigger on
intl_registration_date and protection_grant_date respectively, and are
absent when the record does not carry that date rather than guessed from
another one. A designation with no international registration date still
returns no schedule at all (requires_office_date), as before.
The Renewal DAU and Mid-Renewal DAU are unchanged for designations: Rule 20
runs them from the renewal of the registration, which for an international
registration is the WIPO renewal on the international registration date the
renewal row already uses. One limit is documented rather than hidden: a
SUBSEQUENT designation’s 3rd-year DAU legally runs from the recording of that
designation, and the engine anchors it on the international registration date
instead, which is never later. No reindex is involved.
September 2, 2026: Swedish publication and expiry dates corrected (PRV connector)
Two corrections to how we read PRV’s bulk feed. Neither changes a stored record until the PRV backfill and reindex have run, so existing responses are unchanged at deploy time; the dates below move once that maintenance completes.publication_date for national registrations since December 2022. PRV’s
feed dates the registration notice by gazette issue, one day (occasionally two
or three) after the registration decision. PRV counts the opposition period
from the kungörelsedag, which is the registration day itself, and its own
register shows the opposition period starting on that day. We now take the
registration day as publication_date for the registration notice; the
gazette issue date stays on publications[].publication_date. After the
backfill and reindex, publication_date on affected Swedish marks moves one
day earlier (to registration_date), and every Swedish opposition window
computed from it (derived.opposition_window, the opposition_status and
opposition_closes_* filters) moves one day earlier at both ends. Together
with the opening-day correction below, a mark registered on 1 April now
shows a window of 1 April to 1 July, matching PRV, instead of 3 April to 2
July. Marks registered before December 2022 already carried the registration
day and do not move. Madrid designations of Sweden are not touched by this
change.
expiry_date for registrations from 2019 on. PRV reports a ten-year
expiry for every registration, but our far-future date guard (built for a
handful of corrupt year-2077 and year-5014 owner dates) rejected any date more
than two years out, so Swedish registrations from 2019 on, and older marks
whose latest renewal runs past 2028, were served with no expiry_date and no
renewal_due_date. Both are now ingested as reported. Renewal deadlines for
these marks anchor on PRV’s own date once it is stored; where that differs
from the statutory computation we used before, PRV’s date wins.
September 2, 2026: Canada (CIPO) opposition extension benchmark before December 2023
No computed date moves.window_opens, window_closes and status for
Canadian marks are unchanged; this corrects the advisory common_extension
field only, and only for the direct (non-Madrid) route.
The Trademarks Opposition Board rewrote its “Practice in trademark opposition
proceedings” on 1 December 2023 and cut the benchmark first extension to file
a statement of opposition from 4 months (with a cooling-off extension of up to
9 months on consent) to 2 months (up to 7). The ca_opposition rule served the
post-2023 figure for every window. The office’s own transition rule keys on
when the extension request was received (“requests for extensions of time
received on or after December 1 will be subject to the revised extensions of
time”), and a non-retroactive s. 47(1) request is received no later than the
deadline it extends, so the rule now keys on the served close date:
derived.opposition_window.common_extensionfor a CA direct-route window that closes before 1 December 2023 now readsmonths: 4(was 2) with notes naming the 2019 notice and the 9-month cooling-off figure.- A window closing on or after 1 December 2023 keeps
months: 2; its notes are rewritten (they no longer claim the window is “otherwise non-extendable” - the 7-month cooling-off extension exists) and name the straddle: a window that opened before 1 December 2023 and closes on or after it may have been extended under either figure depending on when the request was received. GET /v1/opposition-rulescontinues to show the current (2-month) tier forca_opposition; the rule’s citations gain the superseded 2019 notice and CIPO’s own side-by-side changes page, both pinned from the Wayback Machine because the office has removed them.ca_opposition_madridis untouched: Trademarks Regulations s. 125 caps the Protocol-application extension at 4 months in every era.
common_extension, so no
reindex is needed.
September 2, 2026: MX oppositions before 30 August 2016 are no longer served
Computed dates change for MX (IMPI). Mexico had no pre-grant opposition procedure until the decree published in the Diario Oficial de la Federación on 1 June 2016, whose sole transitorio puts it in force “a los 90 días naturales siguientes a su publicación” - 1 June 2016 plus 90 calendar days, i.e. 30 August 2016. The same decree introduced the pre-grant publication of the application, so an MX record carrying a publication date before that day is showing a registration publication, which never opened an opposition period. Themx_opposition rule now declares applicable_from_date and
effective_from of 2016-08-30, and MX publications earlier than that return
no opposition window at all.
Direction of the change: windows are REMOVED, never added. Nothing about a
publication on or after 30 August 2016 moves - the one-month non-extendable
period, its day-after start and its rollover calendar are unchanged. If you
read an opposition window for an MX mark published before 30 August 2016, that
window was wrong and is now absent.
Trademark responses recompute the opposition window per request, so they are
correct as soon as this deploys. The opposition_status and
opposition_closes_before/opposition_closes_after search filters read
values materialised at index time, so until the MX index is rebuilt those
filters may still match Mexican marks published before 30 August 2016 even
though the returned record now carries no opposition window.
September 2, 2026: India (CGPDTM) deadline and opposition rules
New jurisdiction.IN now has a maintenance config and two opposition rules,
so GET /v1/deadline-rules, GET /v1/opposition-rules,
POST /v1/deadlines/compute and the derived block on a trademark answer for
Indian marks instead of returning nothing. Four new rule_id values:
in_renewal, in_restoration, in_opposition, in_opposition_madrid.
Renewal runs 10 years from the APPLICATION date, not the grant: s. 23(1) of the
Trade Marks Act 1999 registers a mark “as of the date of the making of the said
application”. The filing window opens a year before expiry (Rules 2017
r. 57(1)), a 6-month surcharge window follows expiry, and restoration is
available after 6 and within 12 months from the expiry itself. Marks registered
before the Act commenced on 15 September 2003 run 7-year periods until the
first period that starts on or after that date. Opposition is 4 months from
publication of the Trade Marks Journal issue that advertised the application,
counted from the day after (General Clauses Act 1897 s. 9(1)) and
non-extendable; it was 3 months for applications published before 8 July 2013.
An international registration designating India is opposed on the same 4-month
window, running from the INDIAN Journal republication rather than the WIPO
Gazette. Every value cites the statute, the Rules or the CGPDTM practice
document it comes from, with a verbatim quote and a pinned snapshot.
Six limits are documented rather than hidden. No closed-day roll is applied to
any Indian date: the law requires one but the Registry publishes no
consolidated holiday list, so holiday_calendar is null and every adjustment
reads not_checked rather than a guess. A mark claiming convention priority
expires on its PRIORITY date plus ten years, which the engine cannot compute
without an office-supplied expiry. A mark registered late may renew within six
months of its actual registration, so its real due date can be later than the
one published. A mark filed before 15 September 2003 but registered after it
takes a ten-year first term, where the schedule gives seven. And nothing in the
Act or Rules settles whether a renewal filed ON the expiry date avoids the
surcharge; the conservative reading is modelled. Lastly, the anchor of the
pre-2003 seven-year terms is not pinned to a quotable source: s. 159(6)
evidences the seven-year length but not the date it runs from, and India
Code’s scan of the 1958 Act carries no text layer to quote, so if the
filing-date anchor is wrong the direction of the error is unknown.
Trademark responses recompute opposition windows per request, so they are
correct as soon as this deploys. Only the materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters are baked
at index time, so IN search documents carry these values only after IN is
reindexed; no IN records are indexed today.
September 2, 2026: Türkiye (TÜRKPATENT) deadline and opposition rules
New jurisdiction.TR now has a maintenance config and two opposition rules, so
GET /v1/deadline-rules, GET /v1/opposition-rules,
POST /v1/deadlines/compute and the derived block on a trademark answer for
Turkish marks instead of returning nothing. Three new rule_id values:
tr_renewal, tr_opposition, tr_opposition_madrid.
Renewal runs 10 years from the FILING date, with a 6-month filing window before
the term ends and a 6-month window after it against an additional fee; missing
both ends the right. Turkish law has no restoration and no declaration of use,
so neither is emitted: that absence is the finding, not a gap. Opposition is 2
months from the publication of the APPLICATION in the Bülten, non-extendable,
and identical for Madrid designations (SMK m. 14/1 makes an international
application produce the same results as a direct one); publications before
2017-01-10 get the 3 months the repealed KHK 556 gave. Every value cites the
statute or the TÜRKPATENT publication it comes from, with a verbatim quote and a
pinned snapshot.
Five limits are documented rather than hidden. No business-day adjustment is
applied to any Turkish date: no Turkish source states that a deadline falling
on a non-working day extends before the office, and TÜRKPATENT’s own 2025-03-29
notice told users to file during an administrative holiday, so
holiday_calendar is null and both adjustments read not_checked on every
row. Renewal cycles whose anniversary falls before 2018-01-10 were governed by a
month-end-anchored request window that the engine does not yet express, so
their window_opens and due_date can be up to 30 days early; every such cycle
is in the past. (grace_expiry is not affected: the repealed KHK 556 anchored
the six-month lapse on the exact end of the term, which is what we publish.)
An application filed before 2017-01-10 but published after it legally had a
3-month opposition window while we publish 2: earlier than the true date,
never later. Applications published in Marka Bülteni 410 to 417, roughly
12 December 2022 to 27 March 2023, carry opposition end dates that
TÜRKPATENT’s 2023-04-14 notice fixed per bulletin once the periods suspended
after the February 2023 earthquakes restarted; a one-off table is not a rule,
so those office-fixed close dates are not modelled and the notice is pinned to
keep the limit auditable. And whether a renewal request filed ON the day the
term ends is still surcharge-free is stated by neither SMK m. 23/2 nor the
office, so the exact anniversary is kept as the due date.
Trademark responses recompute opposition windows per request, so they are
correct as soon as this deploys. Only the materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters are baked
at index time, so TR search documents carry these values only after TR is
reindexed; no TR records are indexed today, so that reindex belongs with the
TÜRKPATENT connector rather than with this change.
September 2, 2026: Japan (JPO) deadline and opposition rules
New jurisdiction.JP now has a maintenance config and two opposition rules,
so GET /v1/deadline-rules, GET /v1/opposition-rules,
POST /v1/deadlines/compute and the derived block on a trademark answer for
Japanese marks instead of returning nothing. Four new rule_id values:
jp_renewal, jp_restoration, jp_opposition, jp_opposition_madrid.
Renewal runs 10 years from the registration date, with a 6-month filing window
before expiry and a 6-month late window after it; missing both extinguishes the
registration retroactively, and a further 6-month restoration window follows.
Opposition is POST-registration: 2 months from the day after the 商標掲載公報
issue, non-extendable, with the same window for Madrid designations. Deadlines
falling on a JPO closed day roll to the next open day. Every value cites the
statute or the JPO practice document it comes from, with a verbatim quote and a
pinned snapshot.
Three limits are documented rather than hidden: the published window_opens can
be 1 to 3 days earlier than 商標法第20条第2項 allows, and grace_expiry can be
up to 7 days early when the expiry lands on a closed day. Madrid designations
are also served a jp_restoration row that Japanese law does not give them.
All three are fixed by engine changes that ship separately.
Trademark responses recompute opposition windows per request, so they are
correct as soon as this deploys. Only the materialised opposition_status and
opposition_closes_before/opposition_closes_after search filters are baked
at index time, so JP search documents carry these values only after JP is
reindexed; no JP records are indexed today.
September 2, 2026: opposition window opening day corrected (Benelux, Finland, Norway, Sweden)
Opposition windows for BOIP, PRH Finland, Patentstyret, and PRV Sweden now open on the publication day, one day earlier than before. Their closing dates are unchanged. The served oppositionrule_version moves to 2026-09-02.
derived.ruleset_version on trademark responses (backed by the internal
DEADLINE_RULESET_VERSION constant) also moves to 2026-09-02. It is one
global stamp (the maximum lastVerified across all maintenance configs), so
it moves for every record in every jurisdiction, including ones this release
did not touch; this release bumped that maximum.
The version move on its own does not imply that any computed date changed.
REINDEX required for these four offices. Trademark responses recompute
opposition windows per request, so they are correct as soon as this deploys.
Only the materialised opposition_status filter stays stale until those
offices are reindexed, because opposition_window_opens is baked into existing
search documents; the opposition_closes_before/opposition_closes_after
filters are unaffected, because no closing date moves.
Benelux, Finland and Norway can be reindexed now.
Sweden caveat. For marks registered since December 2022, the publication
date we stored for PRV came from the gazette issue, which runs one day after
the registration decision (40 of 40 records sampled per month). PRV counts the
opposition window from the registration day itself. The connector correction
is in the “Swedish publication and expiry dates corrected” entry above; Swedish
opposition windows stay one day late until the PRV backfill and reindex
described there have run. Sweden is reindexed after that backfill, not with
the other three offices.
September 2, 2026: German renewal dates corrected for applications pending on 14 January 2019
DE national marks filed before 14 January 2019 but registered on or after that date now expire on the exact filing anniversary. They were previously shown with a month-end deadline, which is later than the law allows (for example, 2028-10-31 instead of 2028-10-05). Marks already registered before the cutoff retain month-end expiry, and office-reported expiry dates still take priority. The correction is computed at request time; no reindex is required. Scope of the change: only DE national marks filed before 2019-01-14, registered on or after that date, and without an office-reported expiry date. Our deadline evaluation harness holds no DPMA samples, so 0 records in it move. The first renewals for this group fall in 2028 and 2029, so no affected deadline is currently past due.September 2, 2026: French renewal grace end corrected (moves later)
French renewal grace periods previously ended early, so customers had more time than Signa showed. They now run for six months from the day after the registration expires, matching CPI R. 712-24 and R. 718-2 exactly. Scope: no French renewal grace end moves earlier. Most move one day later. A grace period whose due date falls on a month end can move up to four days later, because the old and the new end clamp to different month ends: a due date of 2026-02-28 moves its grace end from 2026-08-28 to 2026-09-01, a due date of 2026-04-30 moves two days, and 2028-02-29 moves three. A few whose old and new ends both clamp to the same month end do not move at all. The correction is computed at request time, so no reindex is required (maintenance deadlines are not indexed).September 2, 2026: office calendar corrections
Deadline rollover calendars now match the 2026 audit of official office closures. No rule window or anchor changed. Trademark responses recompute opposition windows per request, so every office below is correct as soon as this deploys. Only the materialisedopposition_status and opposition_closes_before/opposition_closes_after
search filters stay stale until the offices named below are reindexed.
- EUIPO: 8 December 2025 and 2026 no longer roll; those are Article 2 ordinary-post-only days, not Article 1 office closures. Reindex EU opposition documents.
- CIPO: weekend substitutes for 24 June and 30 September now roll on the following Monday. Those two need no reindex before the first affected 2028 opposition cohort. Separately, the 17–19 September 2025 office closure now rolls through the weekend to 22 September, so CA documents published 17 to 19 July 2025 carry an opposition close date up to five days early until CA is reindexed. Opposition status is unaffected: those windows are already closed.
- IPOS: 11 August 2025 and 20 March 2026 no longer roll; the excluded days 1–16 May 2024 roll to 17 May, and 14 October 2025 rolls to 15 October. Reindex affected Singapore opposition documents.
- IP Australia: Canberra Day, Saturday and Sunday ANZAC Day substitutes, and the standing 25 December–1 January close-down now roll. For example, 9 March 2026 rolls to 10 March, 27 April to 28 April, and 29 December to 4 January 2027. Reindex Australian opposition documents.
- IPI: the conservative nationwide calendar now excludes canton-specific days, including 2 January, Good Friday, Easter Monday, Whit Monday, 1 May, 26 December. The governing party or representative canton is not available to the engine, so deadlines are never moved later based on the wrong canton. Reindex Swiss opposition documents.
- DKPTO: 15 May and 28–30 December 2026 now roll as enumerated office closures. Reindex is not currently needed because Signa has no DK office documents; revisit when DK ingestion lands.
- INPI France: 15 May 2026 now rolls to 18 May under the Director General’s closure decision. Reindex French opposition documents.
- DPMA: the one-off Berlin holiday on 8 May 2025 now rolls to 9 May. No reindex is required for the weekly weekday publication cohort.
September 2, 2026: Era-aware opposition citations
Thesource on a computed opposition window now cites the instrument that
states the window actually served. For rules whose opposition period changed
on a fixed date, a publication before the change cites the earlier statute and
a publication on or after it cites the amending law. This covers all seven
opposition rules that change their period on a date, so a pre-change
publication now cites the instrument that states the period it was given:
- Australia, direct and Madrid, published before 2013-04-15 (3 months): Trade Marks Regulations 1995 reg 22.9 item 2 for a direct application and the 2012 compilation’s reg 17A.29(2)(b)(i) for an international registration, in place of the current reg 5.6(1) / reg 17A.33(1) “2 months”.
- India, published before 2013-07-08 (3 months): Trade Marks Rules 2002 r. 47(1), in place of s. 21(1) “four months”.
- Thailand, published before 2016-07-28 (90 days): s. 35 paragraph 1 of the Trademark Act B.E. 2534 as in force before Act (No. 3) B.E. 2559, in place of the current s. 35 paragraph 1 “sixty days”.
- Türkiye, direct and Madrid, published before 2017-01-10 (3 months): the repealed Decree-Law 556 art. 35/1, and WIPO Information Notice No. 19/2014 for a designation, in place of SMK 6769 art. 18/1 “iki ay” for a direct application and the WIPO Madrid Member Profile (“two months from the date of publication of the international registration”) for a designation.
- Vietnam, published before 2026-04-01 (5 months): Law 07/2022/QH15, in place of Law 131/2025/QH15, which states only the three-month period.
source shape (citation, url) is unchanged, and
no reindex is required: the citation is computed at request time.
September 2, 2026: Vietnamese opposition windows corrected (3 months since 1 April 2026)
Vietnamese trademark applications published on or after 2026-04-01 now have a 3-month opposition window. These windows were previously shown 2 months too late. Trademark responses recompute opposition windows per request, so they are correct as soon as this deploys. Only the materialisedopposition_status and
opposition_closes_before/opposition_closes_after search filters stay stale
until VN documents published on or after 2026-04-01 are reindexed.
September 2, 2026: Brazilian and Mexican renewal deadlines
Renewal deadlines are now computed for Brazilian and Mexican registrations where none were computed before; the grant-date trigger was never fed from stored data. The affected cohort is BR and MX national-route registrations whose stored registration date feeds that trigger; records carrying an international registration number are excluded. The deadlines are computed at request time, so no reindex is required (maintenance deadlines are not indexed).September 2, 2026: Icelandic renewal dates corrected
IS renewal deadlines: applications filed before 2020-09-01 are now anchored on the registration date for every renewal, even when registration occurred after the reform. They were previously shown early from the filing-date anniversary. For every affected record that carries a registration date the renewal moves later; none moves earlier. Records with an office-reported expiry remain anchored on that expiry. There is a third outcome. A pre-2020 IS record that carries neither a registration date nor an office-reported expiry now returns no computed renewal at all, where it previously returned one anchored on the filing date. The filing date is the wrong anchor for that cohort, so the deadline is withheld rather than guessed; send the registration date, or the office’s expiry date, to get a schedule back. This matches how the other registration-anchored pivots (SE, FI and NO) already behave. Denmark is not in that set: its pivot is keyed on the registration date rather than the filing date, so a DK record with no registration date falls through to the modern filing anchor and is served a schedule. Renewal deadlines are computed at request time, so no reindex is required. IS opposition dates did not change either:opposition_window_opens,
opposition_window_closes and opposition_rule_version in the search index
are unaffected. The index stores no rule citations at all. GET /v1/deadline-rules and GET /v1/opposition-rules serve sources[] straight
from the deployed configuration, so the new IS primary-source citations take
effect with the deploy (within the 24-hour reference-cache window), and no
reindex is involved.
September 2, 2026: Office rule reference data provenance
Reference data: deadline and opposition rules for AU, BR, BX, CA, CH, DE, DK, EU, FI, FR, GB, MX, NO, PH, PL, SG, TH, US and WIPO now cite primary sources with verbatim quotes and pinned snapshots.sources[] on
GET /v1/deadline-rules and GET /v1/opposition-rules changed for those
offices: law-firm guides, publisher summaries and mirrors of primary text were
replaced by the statute, regulation or office publication they paraphrased.
Nothing else in those responses moved, and no computed date changed from the
re-citation alone. IN, JP and TR are new rule sets rather than re-citations,
and are announced separately above.
For DE (DPMA) the opposition rule’s five bare links to individual
gesetze-im-internet section pages are replaced by eleven pinned citations:
MarkenG §§ 41, 42 and 91, MarkenV § 27, BGB §§ 187, 188 and 193, DPMAV § 18a,
PatKostG § 6(1) with the opposition fee numbers, and the DPMA’s own opposition
guideline W 7736 (Markenblatt publication, the Ereignisfrist arithmetic, and
the rule that statutory periods cannot be extended). The German renewal config
additionally cites PatKostG §§ 3, 5 and 7, BGB §§ 187 and 188, and three DPMA
practice pages carrying the worked renewal example. No computed dates changed.
For FI (PRH) both configs move to primary Finnish law. The renewal config’s
two remaining links (an English PRH page and a law-firm alert) are replaced
by twelve citations: Tavaramerkkilaki 544/2019 §§ 16, 30, 106 and 107 (the ten
years from the application date, the one-year/six-month window, removal from
the register, and the 1 May 2019 commencement that pivots the anchor), the
repealed 7/1964 §§ 22 and 24 for marks applied for before it, the 1930 Act on
calculating time limits for the same-numbered-day arithmetic, and three Finnish
PRH pages. The opposition rule’s own statutory links are re-pinned (544/2019
§ 32 and the 1930 Act) and joined by 544/2019 §§ 24 and 33, 7/1964 § 20 and
four PRH pages. A citation to a Government Decree on Trademarks (1268/2018) was
removed: that statute number belongs to an unrelated act and no decree governs
the Finnish opposition period. No computed dates changed.
For FR (INPI) the opposition rule loses all four of its previous links and
gains thirteen pinned citations. Two of the four were wrong as well as
unverifiable: the Légifrance article id cited for CPI art. L. 712-4 does not
exist, and the one cited for Code de procédure civile arts. 641/642 identifies
neither article (they are LEGIARTI000006411002 and LEGIARTI000006411003). The
rule now cites CPI arts. L. 712-4 (both the in-force text and the pre-2019
text, with L. 712-3, showing the two months have not changed since 1992),
R. 712-8 for the BOPI publication that starts the period, R. 718-2 for
the same-numbered-day arithmetic and the weekend/holiday roll, R. 712-14 for
the one further month allowed for the exposé des moyens, R. 712-15 for the
inadmissibility of a late opposition and R. 712-12 for the absence of any
restoration of it, plus INPI’s opposition directives (July 2026) and its
current opposition page. The renewal config additionally cites CPI arts.
L. 712-1 and L. 714-5 and INPI’s nullity/revocation page. Statutory text is
quoted from the DILA open-data LEGI publication of each article version,
because legifrance.gouv.fr blocks automated retrieval. No computed dates
changed.
For MX (IMPI) both configs move to primary Mexican law. The renewal config’s
five previous citations - a WIPO Lex catalogue page and three law-firm guides,
plus WIPO Information Notice 13/2018 - become thirteen: LFPPI arts. 178, 21,
233, 237 and 238 and transitorios PRIMERO, DECIMO and DECIMO PRIMERO (the ten
years from grant, the six-month renewal window and six-month grace, the
declaration of use in the three months after the third year, and the
2018-08-10 and 2020-11-05 commencements), the abrogated Ley de la Propiedad
Industrial art. 95 for marks applied for before 5 November 2020, IMPI’s own
LFPPI seminar deck, and Information Notice 13/2018 promoted in place with its
quote. The opposition rule’s three links are replaced by seven citations:
LFPPI arts. 221, 21 and 18, Reglamento de la LPI arts. 4o and 59 TER, the
abrogated LPI art. 120 showing the one-month non-extendable period has not
changed since 2016, and the transitorio Único of the decree published in the
DOF on 1 June 2016, which is the text that dates the 2016-08-30 gate. All
three were unusable: every one of them pointed at diputados.gob.mx, which no
longer answers, and the Federal Code of Civil Procedure art. 286 is not the
instrument that governs IMPI time limits either.
Statutory text is quoted from the ordenjuridico.gob.mx consolidated PDFs. No
computed dates changed.
September 2, 2026: The events feed is documented (beta)
GET /v1/events and
GET /v1/events/{id} are now part
of the published API reference and the OpenAPI document, under Monitoring. They
were already live and callable with the events:read scope; what changed is
that they are documented and supported rather than undocumented.
The feed is your organization’s append-only event ledger, retained 30 days.
Every webhook you receive is also a row in it, addressable by the same id (the
webhook-id header IS the evt_* id), which makes it the recovery path for an
outage your webhook retries could not cover: persist the last id you processed,
then ask for ?sort=id&after=evt_…. A checkpoint older than the window returns
410 replay_window_expired; see
Replay from a checkpoint.
Beta means one specific thing here. The ledger, the evt_* ids, the filters
and the replay rail are stable enough to build on. The per-event data payloads
are versioned by payload_version and their shape is not yet promised. Pin
payload_version in your consumer and read this changelog before upgrading.
No behaviour changed: same rows, same filters, same scopes. The MCP surface adds
a matching read tool, signa_events_list.
September 2, 2026: Alert diffs use public field names (breaking, beta)
data.alert.event.diff[].path on alert.created webhooks and
GET /v1/alerts* now uses public trademark field names, the same ones
trademark.status_changed adopted. Effective on deploy; alerts are in beta and
this is the last chance to fix the vocabulary before it is frozen.
Fields Signa tracks but does not publish (
is_primary_source,
mark_feature_type_raw, mark_legal_category_raw, application_language) are
dropped rather than renamed, so a diff can be shorter than before, and
every path you now see is a field you can read back from
GET /v1/trademarks/{id}. event.summary is built from the same names, so the
headline reads "Status changed: pending → registered" where it used to read
"Status primary changed: …".
Redeliveries (POST /v1/webhooks/{id}/deliveries/{delivery_id}/redeliver) and
automatic retry attempts of alerts created BEFORE this change are re-emitted
with the new names too (event.summary included, since the headline is
re-derived from the translated diff), so your handler only ever has to
understand one vocabulary. GET /v1/events/{id} applies the same projection to
the stored alert.created body, so the pull rail and a redelivered push of the
same event agree. Nothing about which alerts fire, or when, changed.
September 2, 2026: Office dates and your docket reference on events
Three additive fields ontrademark.status_changed and office_action.issued,
on both the webhook body and GET /v1/events/{id}. Nothing was renamed, no
stored value changed, and payload_version stays 1.
source_date is the office’s date; occurred_at was always ours.
occurred_at is when Signa produced the event: ingestion time for
trademark.* and office_action.*, alert-creation time for alert.created.
That was already true, and it is now documented per family instead of implied.
The new source_date is the office-reported data date of the change as we
stored it (YYYY-MM-DD, or null when the feed reports none), equal to
event_date on office actions. The two differ by the office publication lag,
typically 1 to 14 days, so sort a docket by source_date (meaningful within
one office) and use occurred_at to answer “when did I learn this”. Its meaning
is honest rather than uniform: day precision, USPTO transaction date, WIPO
gazette date, snapshot offices the crawl date.
It is not a legal effective date; changes.status_effective_date is. We
deliberately do not fold the effective date into source_date, because an
office re-crawl can backdate it by years and your feed would travel backwards on
a mark that was merely re-read.
portfolios carries your external_ref, frozen at record time. Both
families now include the portfolios the mark was in when the event was recorded,
each with the reference you set on the membership:
GET /v1/events/{id} in agreement with
the body you verified the signature over. Empty array when the mark was in no
portfolio; null external_ref means unknown or unset, never “cleared”.
alert.created does not carry either field.
The SDK adds EventPortfolioRef and the new fields on
TrademarkStatusChangedData, OfficeActionIssuedData and the org-event detail
types.
September 2, 2026: Webhook subscriptions, portfolio scope, and diff field names
Three contract clarifications on the event surface, all landing together. Subscribing no longer depends on our rollout state.enabled_events accepts
alert.created, trademark.status_changed and office_action.issued at all
times. The last two are accepted for subscription but not yet emitted:
they begin delivering when the API events projector is enabled. Previously the
accepted set widened with our rollout, which meant the published OpenAPI
document described a different API depending on the environment you generated
your client against. Subscribe now and you receive them from the first delivery.
portfolio_id means one thing. An endpoint’s portfolio_id, and
GET /v1/events?portfolio_id=, now filter every event type against the
portfolio membership recorded when the event was recorded, alert.created
included. Previously alerts bypassed the filter entirely, so a portfolio-scoped
endpoint or query returned every alert in the organization regardless of
portfolio. If you scoped an endpoint to a portfolio and relied on it still
receiving all alerts, clear portfolio_id on that endpoint (or add a second,
unscoped endpoint): similarity, class and owner watches match marks you do not
own, and those alerts have no portfolio membership.
changed_fields and changes use public field names. The
trademark.status_changed payload and GET /v1/events/{id} now key the diff by
the field names on the trademark resource instead of our internal column names:
status_primary becomes status, mark_text_primary becomes mark_text,
publication_date_first becomes publication_date,
international_registration_number becomes ir_number, challenge_states
becomes status_challenges, and changed child collections read as owners,
classifications, media and so on. Internal-only columns are omitted rather
than renamed, so both lists can be shorter than before. Every name you now see
is a field you can read back from GET /v1/trademarks/{id}.
September 2, 2026: Richer goods/services validation evidence
POST /v1/goods-services/validate now adds descriptive wording coverage,
candidate spans and USPTO template drafting aids, suggested class inference,
cited indefinite-wording warnings, catalog as_of freshness, and explicit
candidate-search completeness. Summary fields roll up inferred items, warnings,
and complete, truncated, or degraded searches. listed and not_listed keep
their existing catalog-membership meaning. The TypeScript SDK exposes the new
types in version 0.12.0; version 0.11.0 was never published, so no published SDK
contract is broken.
September 2, 2026: Goods/services catalog validation
POST /v1/goods-services/validate checks submitted wording against the
pre-approved catalogs available for US, EM, JP, KR, and CN. listed means the
wording appears in that office’s catalog. not_listed is an absence of
evidence, not a refusal. Other recognized offices return unsupported_office
with reason no_catalog_data.
The endpoint returns one result per input item, bills per item, and can provide
same-class candidate wording when class_number is supplied. An optional
Idempotency-Key enables safe replay. The TypeScript SDK exposes it as
goodsServices.validate() in version 0.11.0.
September 2, 2026: Entity lists and suggest answer 503 when OpenSearch is unavailable
GET /v1/owners, /v1/attorneys, /v1/firms, /v1/entities, /v1/suggest
and /v1/trademarks/suggest no longer fall back to a degraded Postgres page or
an empty result when OpenSearch is unavailable. They answer 503 service_unavailable with a Retry-After header instead. The SDK retries 503
automatically. Cursors and result ordering are unchanged on the happy path.
September 2, 2026: Saved searches removed
The/v1/saved-searches endpoints are gone and now answer 404. The
signa.savedSearches SDK resource, the SavedSearch types, the
from_saved_search option on signa.watches.create and the ssr_ id prefix
were removed with them. The feature had no production usage. Store the search
body on your side and re-send it to POST /v1/trademarks, or create a watch
with the same query.
September 2, 2026: Swedish renewal dates corrected
SE renewal deadlines: registrations applied for before 2019-01-01 are now anchored on the registration date per the transitional rule (SFS 2018:1652 p. 4 a), whenever they were registered. About 1,300 active marks change date, in both directions: roughly 1,290 move later (they were shown up to 6 years early), and 8 move earlier or gain a deadline that was previously outside the horizon (their filing-anchored cycle had already elapsed; the registration-anchored one lands sooner, by up to 2,445 days). Computed at request time, no reindex. Records with an office-reported expiry are unaffected.September 1, 2026: Office-action webhook events
office_action.issued is now a subscribable, versioned semantic event. It
fires once for each newly stored office action on a portfolio mark and carries
the stored prosecution-history fields using public office-code vocabulary.
Emission begins when the API events projector is enabled.
A first detail fetch that newly inserts multiple office actions stores them
without webhook emission. A single-action history may emit one
office_action.issued: one action is indistinguishable from a genuinely new one,
and a stale event is safer than silently dropping a real refusal notice. Once
history is known, each later new action emits once.
September 1, 2026: Trademark status webhooks and portfolio-scoped endpoints
trademark.status_changed is now available as a subscribable webhook event
type. It carries the spine-native event envelope; emission begins when the API
events projector is enabled. Endpoints without a portfolio_id receive every
trademark.status_changed event for the organization; setting a portfolio_id
narrows those deliveries to marks in that portfolio.
POST /v1/webhooks, PATCH /v1/webhooks/{id}, and GET /v1/webhooks now
expose the additive portfolio_id field.
September 1, 2026: Webhook event envelope (BREAKING)
This is a breaking webhook contract change. Foralert.created, the
envelope id and signed webhook-id header now use the spine event identifier
(evt_*) instead of the alert identifier (alt_*). The payload is no longer a
flat merged field bag: data is now { event_id, alert_id, alert }, with the
rich alert resource nested under data.alert.
webhook-id is the documented idempotency key. Migrate or reset stored
idempotency keys during this upgrade so the alt_* to evt_* identity change
does not cause incorrect duplicate handling. Update consumers to read paths
such as data.alert.id and data.alert.event.type.
September 1, 2026: Forward replay on GET /v1/events
The event feed gains a second rail. The default feed keeps its shape and its
rows: newest first, opaque cursor, same order (list items do gain two
timestamp fields, detailed below). What is new is a forward rail a sync client
can resume from, plus two behaviour changes on the existing surface that you
need to know about before you upgrade.
Discard any GET /v1/events cursor you have stored. Event cursors are now
bound to the query that minted them. The payload carries the sort direction and
a fingerprint of the filters, the limit and the sort, so a cursor can only be
replayed against the identical query. Every cursor minted before this change
lacks both, and now returns 400 cursor_invalid. Cursors were always documented
as opaque and short-lived, so this only affects you if you persisted one.
Restart from page one without a cursor.
cursor_invalid is a different failure from cursor_expired, and the split is
deliberate. cursor_expired means the value is not a cursor: malformed,
unsigned, or minted for another endpoint. Restart from page one.
cursor_invalid means the cursor is genuinely ours but is bound to a different
query than the one you just sent, usually because a filter or the limit changed
mid-pagination. Restart from page one with the parameters you actually want.
since now filters on when Signa recorded the event, not when the office
reported it. It used to bind the row’s creation timestamp; it now binds
recorded_at, Signa’s ledger clock. This is what a sync client wants. Source
timestamps can be backdated by an office arbitrarily far, so filtering on them
silently skips late-arriving rows that were recorded after your last poll.
Every event now carries both clocks explicitly, occurred_at for the office
and recorded_at for us, so nothing is lost. created_at stays as an alias of
recorded_at.
sort=id turns the feed into a replay rail. Pair it with
after=<evt_ id> to resume from a checkpoint you persisted, exclusive of the
checkpoint itself. Ledger sequence is the only sortable field, and after is
valid only with sort=id. sort=-id remains the default; its ordering and
cursor behaviour are unchanged. List items gain occurred_at and recorded_at,
and trademark_id is now nullable.
410, not a silent gap.
Replay is bounded by retention. If the events after your checkpoint have been
pruned, the response is 410 replay_window_expired rather than a 200 that
quietly omits them. The floor is per organization, so another tenant’s
retention never affects your answer. Recovery is to start a new initial sync
with sort=id and no after, then persist the newest event ID you see. The
TypeScript SDK maps 410 to a new GoneError.
portfolio_id is family-aware. It filters every event type through the
portfolio membership snapshot captured when the event is recorded, so later
membership changes never rewrite history. That includes alert.created: an
alert is in a portfolio’s feed only when the alerting mark was in the portfolio
at the moment the alert was recorded, and similarity, class and owner watches
routinely match marks you do not own, which have no membership. This is
identical to portfolio-scoped webhook delivery. The parameter requires
portfolios:manage in addition to events:read.
September 1, 2026: Examiner citations
Three new endpoints, a new count on the trademark detail, and a per-office capability flag. Everything here is additive. The only thing that changes for an existing integration is that detailETags rotate once, at deploy.
Citations are now a first-class resource. A citation is a prior mark an
examiner cited against a pending application. GET /v1/citations queries them
across marks, filterable by offices, disposition, action_stage,
refusal_type, trademark_id, cited_trademark_id, cited_ref and an
action_date range. Each row is one citation occurrence: one prior mark, one
application, one office action.
And per mark, in both directions.
GET /v1/trademarks/{id}/citations returns what was cited against that
application. GET /v1/trademarks/{id}/cited-by returns the applications that
mark has been cited against, which is the question a portfolio owner actually
asks. cited-by also picks up citations matched by office-printed reference
where Signa has not linked the row to a record yet, and the
?cited_trademark_id= filter on GET /v1/citations matches the same rows, so
the two views agree.
citations_count on the trademark detail. GET /v1/trademarks/{id} and
POST /v1/trademarks/batch carry a new citations_count. It is present on
every full-detail response, including the batch lookup surface, and it is
nullable. Like events_count and proceedings_count, it is dropped by a
sparse ?fields= projection that does not ask for it. An integer, including 0, means the office is
covered and that is the real count. null means citations are not counted for
that office at all, which is not the same as “there are none”.
capabilities.citations tells you which is which. GET /v1/offices and
GET /v1/offices/{code} now carry a capabilities block whose citations
field reads available, in_progress, not_available or not_applicable.
available offices return a number in citations_count; every other state
returns null. not_applicable is the useful one: an office that does no
ex-officio relative-grounds examination never issues a citation-bearing
refusal, so its empty list is a fact about the regime rather than a gap in our
coverage. Branch on this field instead of inferring coverage from an empty
response. Coverage today is USPTO §2(d) refusals.
SDK. signa.citations.list(), signa.trademarks.citations(id) and
signa.trademarks.citedBy(id), all auto-paginating like every other list.
Detail ETags rotate once. The representation salt goes from v3 to
v4, so the validator format is now "v4.{version}-{epoch}" plus the
derived content hash, plus a citations_count hash on covered offices.
Every cached trademark detail body misses once and refetches. Nothing to
change on your side. The extra hash exists because citations are written by
the extraction pipeline, which does not touch the record’s version: without
it, a client holding an ETag would be revalidated onto a stale count
forever.
September 1, 2026: Every rule has a stable id
Deadline and opposition rules now carry a permanentrule_id, so a computed
date can be traced to the rule that produced it and joined to the catalogue
that documents it. rule_id is an opaque slug (do not parse it), and it will
not be renamed once published.
Alongside it, two dates that were previously conflated are now separate.
effective_from is the earliest date from which a rule’s modelled content is
authoritative, and is null where the corpus does not establish one.
last_verified is when we last checked the rule against its sources; on
opposition rules that is the value rule_version has always carried.
POST /v1/deadlines/compute rows gain rule_id, effective_from,
last_verified and the business-day provenance due_date_adjustment,
grace_expiry_adjustment and holiday_calendar. The two adjustment fields
are moved, unchanged or not_checked. not_checked covers a
jurisdiction that does not observe the roll, an office with no wired calendar,
and a date beyond a calendar’s coverage, so a date we never checked is never
reported as one we checked and left alone. Each item also carries the
jurisdiction’s sources, plus as_of and computed_at, which together make
a response replayable as a record of what was computed and when.
POST /v1/oppositions/compute gains rule_id and effective_from;
rule_version is unchanged. Both catalogues expose the same three fields, and
GET /v1/deadline-rules now also serves the restoration rules for Great
Britain, Singapore and Iceland, which the engine could always compute but the
catalogue never listed. Trademark detail, portfolio deadlines and watch
diagnostics carry rule_id on each row.
All fields are additive. One caching note: the trademark detail response
folds a content hash of its derived block into the ETag, and that block now
carries rule_id, so detail validators rotate once on this release.
September 1, 2026: Prosecution deadlines on /v1/deadlines/compute
POST /v1/deadlines/compute now computes prosecution deadlines as well as
maintenance ones: office action response periods and statement of use clocks,
resolved per fact instance. Send an optional facts array on any item and the
result gains prosecution_deadlines[] and support[].
This is additive. prosecution_deadlines[] and support[] appear only on
items that sent facts. (The same release adds rule identity to every item
(see the entry above), so an item you send without facts is unchanged apart
from those provenance fields.)
Every computed date cites its rule. Each prosecution deadline carries the
rule id, the era it belongs to (effective_from / effective_until), which
case date selected that era, when the rule was last verified against source,
and the sources themselves with pinpoint section, verbatim quoted text and a
sha256 of the snapshotted document. A computed date that cannot cite its rule
does not ship.
Support is now per deadline type, and it is honest about coverage. A
single supported: boolean could not say that a US mark has a renewal
schedule but no office action deadline, so support[] reports one entry per
type with a four-valued status:
computed, a modelled rule produced or retired a datestated, no modelled rule exists but the office stated the deadline itselffacts_required, a rule exists and is verified, but you must supply the triggerunsupported, no rule is modelled
facts_required until you send the trigger. There is no Madrid level rule and
there will not be one, because the Madrid System does not set the holder
response period; it is designated office law. For an unmodelled contracting
party, send a stated_deadline fact carrying what the office declared and the
date comes back with the notification as its authority.
The item level unsupported_reason enum widens from 2 values to 20 so both
engines share one reason vocabulary. The field itself still only emits the two
maintenance values; the new codes appear on support[].reason and
prosecution_deadlines[].reason. Treat it as an open enum.
Billing is unchanged: 1 unit per item, whether or not the item carries facts.
August 31, 2026: Computed data moves under derived
A response-shape change on the trademark detail and batch endpoints, plus a
new provenance field. This is a breaking change: deadlines[] and
opposition_window move, and three fields on each deadline row go away. We
are shipping it during beta, before anyone has built on the old shape.
Everything Signa computes now lives under derived. deadlines[] becomes
derived.deadlines[] and opposition_window becomes
derived.opposition_window. The split makes the boundary visible. Fields at
the top level are what the office told us. derived is what we computed.
Nothing about what we compute has changed, only where it sits.
Deadline rows now carry dates, not countdowns. status, urgency and
days_until_due are gone from the trademark response. Each row instead
carries window_opens, due_date and grace_expiry, plus new
trigger_date, trigger_field, recurring and optional fields.
The reason is caching. Those three fields were functions of the day you read
the response, but the response is cached and revalidated against a
record-versioned ETag. A client that held an ETag and revalidated a week
later got a 304 and kept serving last week’s countdown, indefinitely. A
value that changes without the record changing cannot live in a cacheable
body.
Deriving them is a couple of lines against your own clock:
POST /v1/deadlines/compute takes an
explicit as_of_date and still returns status, urgency and
days_until_due. Its clock is an input, so it caches correctly.
GET /v1/portfolios/{id}/deadlines is unchanged.
Opposition windows lost their clock fields too. derived.opposition_window
drops status, days_until_open and days_remaining, and adds
rule_version. On search and list rows, opposition_window keeps
window_opens and window_closes and drops status. The opposition_status
filter is unaffected. The server still evaluates it, so filtering by open or
not_started works exactly as before.
An empty schedule now says why it is empty. [] used to be ambiguous
between “this mark has no deadlines” and “we declined to compute one”.
derived.deadlines_supported is now false with a
derived.deadlines_unsupported_reason of either unsupported_jurisdiction or
requires_office_date, the same vocabulary POST /v1/deadlines/compute
already returns. derived.ruleset_version stamps the rule state that produced
the block.
renewal_due_date now declares where it came from. It sits at the top
level next to office-reported dates, but it is office-stated for some records
and computed by the connector for others, and nothing said which. The new
renewal_due_date_basis reads reported, derived or unknown, exactly
like expiry_date_basis. Connectors adopt it one at a time, so expect
unknown on records whose connector has not declared one yet.
Detail ETags all rotate. As of this release the validator format is
"v3.{version}-{epoch}" with a content hash of the derived block appended,
so cached copies of the old shape miss and refetch. Nothing to do on your side
beyond expecting one full response per cached mark. (The v3 salt moved to
v4 in the September 1 release below.)
August 30, 2026: Deadline engine statutory corrections
A correctness pass over the maintenance deadline engine. This is a behavior change: the same trademark can now return a differentstatus, a different
number of deadlines[] rows, and different dates on four jurisdictions. Read
this before upgrading if you drive filing workflows off computed deadlines.
The due day and the last grace day are now actionable, not missed. Status
boundaries are inclusive on the actionable side. On the due date a deadline
reads due_soon, not missed. On the last day of the grace period it reads
in_grace, not missed. missed now begins the day after grace expiry (or
the day after the due date where a rule has no grace period, such as the
Mexican third-year declaration of use). If you filtered for missed to build a
“too late to file” list, that list previously included two days you could still
file on.
Refused applications no longer return a maintenance schedule. A refused
application has nothing to maintain, so deadlines[] is now [] for it.
The one exception is Madrid-route records: a provisional refusal from a
designated office is routinely overcome, so Madrid-route marks keep computing
their schedule.
Expired and cancelled marks now return their still-actionable rows instead of
an empty array. These statuses are recoverable for a bounded window, and
returning [] hid exactly the deadlines a customer needs at that moment. An
expired mark now returns its open late-renewal window (the current cycle
while its filing window or grace period is open) plus its restoration row
where the jurisdiction provides one (GB, SG, IS). A cancelled mark returns
its restoration row only, where modeled. Statuses that are terminally dead
(abandoned, withdrawn, surrendered, invalidated, and refused, except
the WIPO international registration record itself under a provisional
refusal) still return [].
- This can add rows to marks you already fetch. A cancelled GB mark that returned no deadlines yesterday can return a restoration row today. Client code that assumed a dead mark implies an empty array should be checked.
- Rows can also disappear for expired marks without a reported expiry. The
engine will not invent a lapse it cannot corroborate: an expired mark with
no office-stated expiry date is served only the cycle whose window is
currently open, never a restoration row derived from an assumed earlier
miss. Clients alerting on
deadlines[]shrinking should expect this.
optional is now false
on those rows, and include_optional=false no longer suppresses them. If you
pass include_optional=false on POST /v1/deadlines/compute to trim the
response, expect restoration rows to appear where they did not before.
Four statutory anchors were corrected. These change computed dates, not
just labels.
- Denmark: the 2019 regime split is keyed on the registration date, not the filing date (Lov 1533/2018 §8 stk. 3). Marks filed before 2019-01-01 but registered after it were anchored up to a year off.
- Mexico: the 2020 regime split is keyed on the filing date, not the grant date (LFPPI Transitorio DÉCIMO). Applications in prosecution when the LFPPI entered into force on 2020-11-05 stay on the old filing-anchored term.
- Philippines: the third-year declaration of use window opens at the filing date and runs to the third anniversary of filing (RA 8293 §124.2). It was previously computed as a single day.
- Thailand: publications before 2016-07-28 get the 90-day opposition window that was in force at the time. The 60-day window applies only from the 2016 amendment forward.
July 25, 2026: Jurisdiction protection scope
A precision fix to whatjurisdictions means, plus honest screening verdicts
when register coverage is incomplete. This is a behavior change: the same
request can now return more results and, for screening, a new verdict value.
Because it changes result sets during beta, read this before upgrading.
jurisdictions now selects rights that protect, or seek protection, in a
territory, not just literal territory legs. Previously jurisdictions=FR
matched only French national filings and Madrid designations of France. It now
also matches regional rights whose membership covers France, so a EU trade mark
(which protects France) is included. See
Search Trademarks and the
glossary.
- Result counts grow. A country-scoped filter picks up the regional rights
that protect it. On production data,
jurisdictions=FRroughly doubles once EU trade marks are counted. Countries with no live national office but active EU coverage (for exampleDE) go from a handful of Madrid hits to full EUTM coverage. territory_match=directrestores the old behavior. Pass it to match only literal territory legs, byte-for-byte the pre-July-2026 result set. The default isterritory_match=protection. Requesting a regional code (EU) stays strict on search: it matches EUTMs and IRs designating the EUIPO, not member-state national marks.- Why results grew is now explained. Under the default
protectionmode, each hit returned with ajurisdictionsfilter carriesterritory_matches[], mapping the requested code to the territory it matched on and the basis (directleg orregional_membership). The field is absent underterritory_match=direct.search_meta.territory_matchechoes the mode that ran. - Suggest and image search grow too.
GET /v1/trademarks/suggestandPOST /v1/trademarks/search/imageapply the same protection-scope expansion and acceptterritory_match. Suggest now also matches Madrid designations of a requested territory (an international registration designating France is suggested underjurisdictions=FR), and image search echoes the applied mode assearch_meta.territory_match. - Member-country codes are newly accepted. Benelux member states (
BE,LU,NL) and OAPI member states (for exampleSN) had no jurisdiction row of their own and previously returned400. They are now validjurisdictionsvalues, sojurisdictions=BEselects Benelux and EU rights that protect Belgium. - Saved searches were removed on September 2, 2026. Saved searches replay under the new semantics automatically. A stored
search with
jurisdictions=FRis re-executed against the current matcher, so it now returns EU trade marks it did not before, with no change on your side. If you need a saved search to keep the old literal-leg behavior, re-save it withterritory_match=direct. - Breaking for pagination. Because the query shape of a jurisdiction-filtered
search changed, pagination cursors minted before this release on such a query
now return
400 cursor_invalid. Clients holding a stale cursor must restart pagination from the first page. - During the rolling deploy, expect a brief mixed window. While the release
rolls out, requests may land on either old or new instances, so a
jurisdiction-filtered query can alternate between the old and new result sets,
and
territory_matchmay return400from a not-yet-updated instance. Stale jurisdiction-filtered cursors invalidate as above. The window closes once every instance is on the new release; retry the request if you hit it.
needs_review when register coverage is incomplete.
A clearance verdict is only trustworthy if Signa can actually see the marks that
protect a requested territory. When the register that would carry a conflict is
not connected live, a zero-conflict screen must not read as clear.
- New verdict value.
GET /v1/screeningverdicts are nowhigh_risk/caution/needs_review/clear.needs_reviewis a would-beclearthat could not be confirmed because a requested territory’s register is dark or stale. Handle it as “we could not rule this out”, not as a weaker clear. Found conflicts still band high or medium exactly as before, observed risk is never suppressed. - Why this is deliberate. Before this change, screening a common brand in a
class scoped to a territory whose national register was not yet connected could
return
clearwith zero conflicts, even though real national marks existed and were simply invisible to us. Returningclearthere is a false negative on a clearance product. We would rather tell you the corpus was incomplete than imply a name is safe. - A new
coverageblock on the screening response reports which registers gated the verdict (offices axis in ST.3 codes, territories axis in jurisdiction codes) and acomplete_for_clearboolean. See Screen a Name. - Check a Listing gets the same protection-scope expansion, and an incomplete
requested register forces a would-be
cleartocaution(the listing verdict enum is unchanged). - Screening responses are no longer client-cacheable. They are served
Cache-Control: private, no-store. Re-run a screen rather than replaying a stored response. screening_idvalues changed at this epoch. The identifier now folds the coverage inputs that can flip a verdict, so ids minted before this release do not correspond to ids minted after. Do not treat a pre-releasescreening_idas stable across this boundary.- Watches are unchanged. Monitoring keeps office-based scoping and does not
apply the protection-scope expansion, so a watch scoped to a country still
watches that country’s office only (a
DEwatch does not surface EU trade marks). See Create Watch.
July 14, 2026
- Compare (beta):
POST /v1/compare, its TypeScript SDK resource, and its developer guide complete the public-facing Intelligence surface alongside Screening. Compare scores one candidate against up to 10 selected conflicts.