> ## Documentation Index
> Fetch the complete documentation index at: https://docs.signa.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Renewal Management

> Never miss a trademark deadline. Query upcoming renewals and declarations, understand grace periods, triage by urgency, and handle US-specific Section 8/15 declarations.

You are a paralegal at a mid-sized IP firm responsible for docketing renewal deadlines across 200+ client marks in 12 jurisdictions. Missing a deadline means losing rights, and potentially a malpractice claim. You need a system that surfaces every upcoming deadline with enough lead time to prepare filings.

This guide walks through building a renewal management workflow with the Signa API.

## Prerequisites

* A Signa API key with `trademarks:read` scope
* A list of trademark IDs (or office-native identifiers) for the client marks you docket

***

<Steps>
  <Step title="Understand deadline types by jurisdiction">
    Not every jurisdiction has the same deadline structure. The Signa API computes deadlines based on jurisdiction-specific rule sets (rules defined for 21 jurisdictions, independent of which offices currently have live trademark record data, see the coverage note below). Start by reviewing the rules for your key jurisdictions.

    <CodeGroup>
      ```bash cURL theme={null}
      # Get all deadline rules for the US
      curl "https://api.signa.so/v1/deadline-rules?jurisdiction=US" \
        -H "Authorization: Bearer $SIGNA_API_KEY"

      # Get rules for multiple jurisdictions in one call
      curl "https://api.signa.so/v1/deadline-rules?jurisdiction=US,EU,GB,DE,CA" \
        -H "Authorization: Bearer $SIGNA_API_KEY"
      ```

      ```typescript TypeScript theme={null}
      import Signa from "@signa-so/sdk";

      const signa = new Signa({ api_key: process.env.SIGNA_API_KEY });

      const rules = await signa.references.deadlineRules({
        jurisdiction: ["US", "EU", "GB", "DE", "CA"],
      });

      for (const rule of rules.data) {
        console.log(
          `[${rule.jurisdiction_code}] ${rule.name} (${rule.type}) ` +
            `due year ${rule.due_year}, grace period ${rule.grace_period_months}mo`,
        );
      }
      ```
    </CodeGroup>

    **Key differences across jurisdictions:**

    | Jurisdiction | Renewal Period | Grace Period | Special Requirements                                                                                   |
    | ------------ | -------------- | ------------ | ------------------------------------------------------------------------------------------------------ |
    | US           | 10 years       | 6 months     | Section 8 (use), Section 15 (incontestability), combined 8+9 at renewal                                |
    | EU           | 10 years       | 6 months     | Simple renewal only                                                                                    |
    | GB           | 10 years       | 6 months     | Simple renewal + restoration period (6 months post-grace)                                              |
    | DE           | 10 years       | 6 months     | DPMA end-of-month rule (due date = last day of expiry month)                                           |
    | CA           | 10 years       | 6 months     | Registrations from before 2019-06-17 have a 15-year initial term, then renew on the same 10-year cycle |

    <Note>
      US marks have the most complex deadline structure. In addition to renewal, you must file a Section 8 Declaration of Use between years 5-6 after registration, and optionally a Section 15 Declaration of Incontestability at year 5. Missing the Section 8 results in cancellation, even if the mark is in active use.
    </Note>

    <Note>
      Rule coverage (`GET /v1/deadline-rules`) and trademark record coverage are tracked separately: rules exist for all 21 supported jurisdictions today, while ingested trademark record data is live for a subset of offices and expanding. See [Data Freshness & Coverage](/guides/data-freshness) for which offices currently have live records.
    </Note>
  </Step>

  <Step title="Collect deadlines across your client marks">
    Every `GET /v1/trademarks/{id}` response includes a `deadlines` array. Each entry already carries a computed `status` (`future`, `window_open`, `due_soon`, `in_grace`, or `missed`), an `urgency` (`routine`, `upcoming`, `critical`, `in_grace`, or `missed`), and `days_until_due`, so you do not need to reimplement that triage logic client-side. Fetch each client mark (or use [Batch Get Trademarks](/api-reference/trademarks/batch-trademarks) for up to 100 at a time) and collect the deadlines that fall inside your docketing horizon.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const clientMarkIds: string[] = [
        /* your tm_... ids */
      ];
      const horizon = "2027-09-24";

      const batch = await signa.trademarks.batch({ ids: clientMarkIds });
      if (batch.not_found.length > 0) {
        console.warn("Not found:", batch.not_found);
      }

      const deadlines = batch.data
        .flatMap((tm) =>
          tm.deadlines.map((d) => ({
            trademark_id: tm.id,
            mark_text: tm.mark_text,
            office_code: tm.office_code,
            jurisdiction_code: tm.jurisdiction_code,
            ...d,
          })),
        )
        .filter((d) => d.due_date <= horizon)
        .sort((a, b) => a.due_date.localeCompare(b.due_date));

      console.log(`Total deadlines before ${horizon}: ${deadlines.length}`);

      const byUrgency: Record<string, number> = {};
      for (const d of deadlines) {
        byUrgency[d.urgency] = (byUrgency[d.urgency] || 0) + 1;
      }
      console.log("By urgency:", byUrgency);
      ```
    </CodeGroup>

    **Expected output:**

    ```json theme={null}
    {
      "object": "list",
      "data": [
        {
          "trademark_id": "tm_abc001",
          "mark_text": "BRIGHTWAVE",
          "office_code": "uspto",
          "type": "declaration_of_use",
          "due_date": "2026-08-14",
          "grace_expiry": "2027-02-14",
          "window_opens": "2025-08-14",
          "jurisdiction_code": "US",
          "status": "window_open",
          "urgency": "upcoming",
          "days_until_due": 41
        },
        {
          "trademark_id": "tm_def002",
          "mark_text": "MERIDIAN",
          "office_code": "euipo",
          "type": "renewal",
          "due_date": "2026-11-30",
          "grace_expiry": "2027-05-31",
          "window_opens": "2025-11-30",
          "jurisdiction_code": "EU",
          "status": "future",
          "urgency": "routine",
          "days_until_due": 149
        }
      ]
    }
    ```
  </Step>

  <Step title="Triage by urgency">
    Group the collected deadlines by the `urgency` field the API already computed, no client-side date math required:

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const byUrgencyList: Record<string, typeof deadlines> = {
        missed: [],
        in_grace: [],
        critical: [],
        upcoming: [],
        routine: [],
      };

      for (const d of deadlines) {
        (byUrgencyList[d.urgency] ??= []).push(d);
      }

      console.log(`MISSED (past grace): ${byUrgencyList.missed.length}`);
      console.log(`IN GRACE PERIOD: ${byUrgencyList.in_grace.length}`);
      console.log(`CRITICAL (due soon): ${byUrgencyList.critical.length}`);
      console.log(`UPCOMING: ${byUrgencyList.upcoming.length}`);
      console.log(`ROUTINE: ${byUrgencyList.routine.length}`);
      ```
    </CodeGroup>

    | Priority | `urgency`  | Action required                                          |
    | -------- | ---------- | -------------------------------------------------------- |
    | P0       | `missed`   | Rights likely lost. Consult counsel immediately.         |
    | P1       | `in_grace` | File immediately. Late fees apply.                       |
    | P2       | `critical` | Prepare and file now, the deadline is close.             |
    | P3       | `upcoming` | Window may be open. Schedule for your next filing batch. |
    | P4       | `routine`  | No action needed yet.                                    |
  </Step>

  <Step title="Handle US-specific Section 8 and Section 15 declarations">
    US marks require more than simple renewal. Filter the deadlines you already collected by jurisdiction and type to identify which declarations are needed.

    <CodeGroup>
      ```bash cURL theme={null}
      # Get full detail including all computed deadlines
      curl https://api.signa.so/v1/trademarks/tm_abc001 \
        -H "Authorization: Bearer $SIGNA_API_KEY"
      ```

      ```typescript TypeScript theme={null}
      // Filter US deadlines by type
      const usDeadlines = deadlines.filter((d) => d.jurisdiction_code === "US");

      const section8 = usDeadlines.filter((d) => d.type === "declaration_of_use");
      const section15 = usDeadlines.filter((d) => d.type === "declaration_of_incontestability");
      const combined89 = usDeadlines.filter((d) => d.type === "combined_renewal_and_use");
      const renewals = usDeadlines.filter((d) => d.type === "renewal");

      console.log(`\nUS Deadlines breakdown:`);
      console.log(`  Section 8 (Declaration of Use): ${section8.length}`);
      console.log(`  Section 15 (Incontestability): ${section15.length}`);
      console.log(`  Combined 8+9 (Renewal + Use): ${combined89.length}`);
      console.log(`  Simple renewals: ${renewals.length}`);

      // For each Section 8, get the full trademark to check filing bases
      for (const d of section8.slice(0, 3)) {
        const tm = await signa.trademarks.retrieve(d.trademark_id);
        console.log(`\n  ${tm.mark_text} (${tm.application_number})`);
        console.log(`  Section 8 due: ${d.due_date} (grace: ${d.grace_expiry})`);
        console.log(`  Filing bases: ${tm.filing_bases.map((b) => b.basis_type).join(", ")}`);
        console.log(`  Classes: ${tm.classifications.map((c) => c.nice_class).join(", ")}`);
      }
      ```
    </CodeGroup>

    **US Declaration timeline for a mark registered on 2021-01-20:**

    ```
    Registration ──────────────────────────────────────────────> Time
         |                                                    |
         v                                                    v
      2021-01-20                                        2031-01-20

      Year 5 (2026-01-20):  Section 15 window opens (optional)
      Year 5 (2026-01-20):  Section 8 window opens
      Year 6 (2027-01-20):  Section 8 DUE (+ 6-month grace)
      Year 10 (2031-01-20): Combined Section 8 + 9 DUE (+ 6-month grace)
    ```

    <Note>
      Section 15 (incontestability) is optional but highly valuable. It eliminates most grounds for cancellation. The window opens at year 5 and remains open indefinitely, but the mark must have been in continuous use for 5 consecutive years with no pending proceedings.
    </Note>
  </Step>
</Steps>

***

## Deadline rules by jurisdiction

Beyond the five jurisdictions above, Signa computes deadlines for all 21 supported jurisdictions. All of them use a 6-month grace period:

| Jurisdiction  | Renewal Period | Grace Period                    | Notes                                                                                   |
| ------------- | -------------- | ------------------------------- | --------------------------------------------------------------------------------------- |
| US            | 10 years       | 6 months                        | Section 8/15 declarations, see above                                                    |
| EU            | 10 years       | 6 months                        | Simple renewal only                                                                     |
| GB            | 10 years       | 6 months + 6 months restoration | Two-stage: grace then restoration                                                       |
| DE            | 10 years       | 6 months                        | DPMA end-of-month rule applies                                                          |
| CA            | 10 years       | 6 months                        | Pre-2019-06-17 registrations keep a 15-year initial term                                |
| CH            | 10 years       | 6 months                        |                                                                                         |
| FR            | 10 years       | 6 months                        |                                                                                         |
| WIPO (Madrid) | 10 years       | 6 months                        | Per designation                                                                         |
| AU            | 10 years       | 6 months                        |                                                                                         |
| MX            | 10 years       | 6 months                        | Renewal grace is 6 months; the separate 3rd-year Declaration of Use has no grace period |

Call [`GET /v1/deadline-rules`](/api-reference/reference/deadline-rules) for the full, current rule set, including the remaining jurisdictions (BR, BX, DK, FI, IS, NO, PH, PL, SE, TH, VN) not itemized here.

## Class coverage

A renewal review is a natural time to also check whether your registered classes still match your business. List your marks filtered to the classes you care about and diff against your target list:

```typescript TypeScript theme={null}
const targetClasses = [9, 35, 42];

const marks = await (
  await signa.owners.trademarks("own_mycompany", {
    nice_classes: targetClasses,
    status_stage: "registered",
    limit: 100,
  })
).toArray();

const covered = new Set(marks.flatMap((tm) => tm.classifications.map((c) => c.nice_class)));
const gaps = targetClasses.filter((c) => !covered.has(c));
console.log("Uncovered classes:", gaps);
```

<Tip>
  Repeat the same query per jurisdiction (add an `offices` filter) to build a jurisdiction x class coverage matrix for the portfolio.
</Tip>

***

## Keep watching for status changes

Refreshing this roll-up nightly from your job scheduler works, but it means you only find out about a status change when you poll. A `portfolio` [watch](/guides/monitoring/watches) with `trigger_events: ["trademark.status_changed"]` over your client marks pushes an alert the moment a mark's status flips (for example to `expired` or `cancelled`), so a missed renewal surfaces the same day the office records it instead of waiting for your next scheduled run. Pair the watch with a [webhook](/guides/monitoring/webhooks) to route it straight to your docketing queue.

If you still want a scheduled roll-up alongside the watch, run the batch fetch from step 2 nightly and diff the results against the previous run:

```typescript TypeScript theme={null}
// Persist yesterday's deadlines keyed by (trademark_id, type, due_date)
const previous = await loadYesterdaysDeadlines(); // from your own store
const todaysKeys = new Set(deadlines.map((d) => `${d.trademark_id}|${d.type}|${d.due_date}`));
const newOrChanged = deadlines.filter(
  (d) => !previous.has(`${d.trademark_id}|${d.type}|${d.due_date}`),
);

console.log(`New or changed deadlines: ${newOrChanged.length}`);
await saveTodaysDeadlines(todaysKeys);
```

***

## What's next

<Card title="M&A Due Diligence" href="/guides/use-cases/mna-due-diligence">
  Audit an acquired portfolio's coverage and deadlines before a deal closes.
</Card>

<Card title="Opposition Tracking" href="/guides/use-cases/opposition-tracking">
  Monitor proceedings that could affect the renewability of contested marks.
</Card>
