List Deadlines
curl --request GET \
--url https://api.signa.so/v1/deadlines \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/deadlines"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/deadlines', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.signa.so/v1/deadlines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signa.so/v1/deadlines"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signa.so/v1/deadlines")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/deadlines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyDeadlines
List Deadlines
List computed maintenance deadlines for a portfolio or trademark
GET
/
v1
/
deadlines
List Deadlines
curl --request GET \
--url https://api.signa.so/v1/deadlines \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/deadlines"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/deadlines', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.signa.so/v1/deadlines",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.signa.so/v1/deadlines"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.signa.so/v1/deadlines")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/deadlines")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_bodyCredits: 1 per page.
Supply exactly one of
A single row looks like this:
portfolio_id or trademark_id. Every request requires
trademarks:read; a portfolio_id request additionally requires
portfolios:manage, and a key missing either scope gets 403 forbidden.
Portfolio requests return 404 for a portfolio outside your organization.
Trademark requests accept any retrievable mark.
Each page costs 1 credit, with a default of 20 and a maximum of 100 rows.
Deadlines are computed when requested. Rows carry rule_id, effective_from,
last_verified, sources[], trigger_date, and trigger_field, alongside
trademark identity, due date, window opening, grace expiry and urgency.
sources[] holds the statutory citations behind the rule, the same ones
Compute Deadlines returns; join
rule_id to List Deadline Rules for
the full rule record. For prosecution deadlines, use
Compute Deadlines.
Filter with a comma-separated type, an inclusive due_before date (YYYY-MM-DD),
or urgency (critical, upcoming, routine, in_grace, missed). The list is
forward-looking by default and omits deadlines whose grace period has already
closed; urgency=missed selects exactly those rows instead. A renewal cycle the
office data proves paid (any cycle before the office-stated expiry, or the cycle
the office’s recorded renewal paid) is not missed and is never listed.
The default cutoff is 720 days after the computation date, within a five-year
computation horizon. A due_before later than the horizon lists rows only up to
it, and the response then carries warnings: [{ "code": "horizon_truncated" }]
with a message naming the horizon date. Portfolios are capped at 5,000 marks;
split larger portfolios.
Results sort by due_date, trademark_id, then rule_id, all ascending, and are
paginated. The cursor pins the computation date, so every
page is computed for the same day, but records and portfolio membership can still
change between pages.
A mark whose deadlines could not be computed has no rows, so the envelope names
it instead. unsupported_marks lists every mark in the requested portfolio or
trademark that was not computed at all (supported: false, with
reason unsupported_jurisdiction or requires_office_date) or
was computed only in part (supported: true, with the declined rules in
unsupported_rules), sorted by trademark_id. A mark whose status ends every
obligation (abandoned, withdrawn, surrendered, invalidated, or refused
other than a WIPO international registration) is never listed, because it is
owed no deadlines in any jurisdiction. A missing anchor of a single rule
lists an expired or cancelled mark only when its status can still be
served that rule (for expired, any rule whose miss costs something, except a
one-off rule of a national mark, whose window closed before its term did, and,
with no renewal on record, the Philippine declaration due at the fifth
anniversary of a renewal; for cancelled, a renewal that opens a modelled
restoration window, which a Madrid designation never has), so a cancelled mark
with no registration date in a jurisdiction with no restoration window is not
listed for it. The whole-record checks do not depend on status: a
cancelled Madrid designation with no international registration date, for
example, is still listed with requires_office_date. These are the same
fields a Compute Deadlines item
carries without include_missed. With urgency=missed the list serves missed
rows, so it also declines the rules whose missed rows lack their anchor, as
compute does with include_missed: an expired or cancelled mark can be
listed then and not on an unfiltered page.
The list covers the whole scope, not just the page, and ignores the type and
due_before filters and every urgency value but missed. It is reported on the first page (a request
without cursor) and is null on every continuation page, because the cursor
pins the computation date and the first page already answered for the chain.
[] on a first page means every mark in scope was fully computed.
"unsupported_marks": [
{
"trademark_id": "tm_019d2141-6ce9-771b-872e-bc8b20e49fcf",
"supported": true,
"reason": null,
"unsupported_rules": [
{
"rule_id": "ph_declaration_of_use_5yr_madrid",
"reason": "requires_office_date",
"missing_field": "protection_grant_date",
"consequence_if_missed": "removal_from_register"
}
]
}
]
GET /v1/portfolios/{id}/deadlines is an alias using the same rows, filters and
cursor. Both paths preserve the portfolio list’s inclusive cutoff semantics, and
a cursor minted on one can be followed on the other. The alias differs in one
deliberate way: it requires portfolios:manage alone, without the base
trademarks:read this path also requires, because its scope is unchanged from
the day it shipped and adding a required scope to a published operation would
break existing keys.
const deadlines = await signa.deadlines.list({
portfolio_id: 'ptf_12345678-1234-1234-1234-123456789012',
type: ['renewal', 'international_renewal'],
limit: 100,
});
for await (const deadline of deadlines) {
console.log(deadline.trademark_id, deadline.due_date, deadline.rule_id);
}
{
"occurrence_key": "us_declaration_of_use_s8:1",
"rule_id": "us_declaration_of_use_s8",
"type": "declaration_of_use",
"jurisdiction_code": "US",
"trigger_date": "2020-03-10",
"trigger_field": "registration_date",
"window_opens": "2025-03-10",
"due_date": "2026-03-10",
"due_date_adjustment": "unchanged",
"grace_expiry_date": "2026-09-10",
"grace_expiry_adjustment": "unchanged",
"holiday_calendar": "uspto_dc",
"is_recurring": false,
"is_optional": false,
"consequence_if_missed": "cancellation",
"trademark_id": "tm_019d2141-6ce9-771b-872e-bc8b20e49fcf",
"mark_text": "EXAMPLE",
"office_code": "US",
"application_number": "88123456",
"registration_number": "6012345",
"ir_number": null,
"urgency": "routine",
"effective_from": null,
"last_verified": "2026-09-02",
"sources": [
{
"citation": "USPTO — Keeping Your Registration Alive",
"url": "https://www.uspto.gov/trademarks/maintain/keeping-your-registration-alive"
},
{
"citation": "15 U.S.C. § 1058(a) — registration term and affidavit requirement",
"url": "https://www.govinfo.gov/content/pkg/USCODE-2024-title15/html/USCODE-2024-title15-chap22-subchapI-sec1058.htm"
},
{
"citation": "15 U.S.C. § 1059(a) — renewal and grace period",
"url": "https://www.govinfo.gov/content/pkg/USCODE-2024-title15/html/USCODE-2024-title15-chap22-subchapI-sec1059.htm"
},
{
"citation": "15 U.S.C. § 1065(3) — incontestability filing period",
"url": "https://www.govinfo.gov/content/pkg/USCODE-2024-title15/html/USCODE-2024-title15-chap22-subchapI-sec1065.htm"
},
{
"citation": "37 CFR § 2.160(a)(3) — Section 8 grace period",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "37 CFR § 2.164(b) — cancellation after missed Section 8 period",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "TMEP § 1604.04 — Time for Filing §8 Declaration",
"url": "https://tmep.uspto.gov/RDMS/TMEP/print?href=TMEP-1600d1e1.html&version=current"
},
{
"citation": "37 CFR § 2.167(f) — incontestability filing period",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "37 CFR § 2.182 — renewal filing window",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "37 CFR § 2.185(b) — expiration after missed renewal period",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "37 CFR § 2.196 — weekend and federal-holiday rollover",
"url": "https://www.ecfr.gov/api/versioner/v1/full/2026-08-28/title-37.xml?part=2"
},
{
"citation": "TMEP § 1606.03 — renewal filing window",
"url": "https://tmep.uspto.gov/RDMS/TMEP/print?href=TMEP-1600d1e1.html&version=current"
}
]
}