Skip to main content
You are an in-house IP manager at a consumer goods company with 500+ active trademark registrations spanning 15 jurisdictions. You need a system that alerts you when any mark changes status, flags upcoming deadlines, and keeps your team in sync — without manually checking each office website. This guide shows how to build that system with the Signa API.

Prerequisites

  • A Signa API key with trademarks:read, portfolios:manage, and events:read scopes
  • A list of your trademark IDs or application/registration numbers

1

Create portfolios by brand family

Organize marks into logical groups. Most companies structure portfolios by brand family, geography, or business unit.
# Create a portfolio for your core brand
curl -X POST https://api.signa.so/v1/portfolios \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-portfolio-aurora" \
  -d '{
    "name": "Aurora Core",
    "description": "All registrations for the Aurora brand family",
    "metadata": { "brand_family": "aurora", "business_unit": "consumer" }
  }'

# Create a second portfolio for a sub-brand
curl -X POST https://api.signa.so/v1/portfolios \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: create-portfolio-aurora-sport" \
  -d '{
    "name": "Aurora Sport",
    "description": "Sport line extension marks",
    "metadata": { "brand_family": "aurora", "sub_brand": "sport" }
  }'
Expected output:
{
  "id": "ptf_core01",
  "object": "portfolio",
  "name": "Aurora Core",
  "mark_count": 0,
  "created_at": "2026-03-24T10:00:00Z"
}
2

Add marks to portfolios

If you already know your Signa trademark IDs, add them directly. If you have office-native identifiers (application or registration numbers), use a batch lookup first.
# Look up marks by office-native identifiers
curl -X POST https://api.signa.so/v1/trademarks/batch \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: batch-lookup-aurora-core" \
  -d '{
    "identifiers": [
      { "registration_number": "6789012", "office": "uspto" },
      { "registration_number": "018456789", "office": "euipo" },
      { "application_number": "2045678", "office": "cipo" },
      { "ir_number": "1456789" }
    ]
  }'

# Add the resolved IDs to the portfolio
curl -X POST https://api.signa.so/v1/portfolios/ptf_core01/marks \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: add-marks-aurora-core-001" \
  -d '{
    "trademark_ids": ["tm_a1b2c3d4", "tm_e5f6a7b8", "tm_c9d0e1f2", "tm_g3h4i5j6"]
  }'
Expected output:
{
  "object": "portfolio_marks_result",
  "added": 4,
  "already_in_portfolio": 0,
  "not_found": 0
}
The not_found count tells you how many of your IDs did not match any trademark record. This is non-fatal — the remaining IDs are added successfully. Check not_found to ensure your reference data is correct.
3

Set up a portfolio watch for status changes

A portfolio watch monitors every mark in the portfolio and fires an alert whenever a status changes (registration, abandonment, opposition, renewal, etc.).
curl -X POST https://api.signa.so/v1/watches \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: watch-aurora-core-status" \
  -d '{
    "name": "Aurora Core - status changes",
    "watch_type": "portfolio",
    "criteria": { "portfolio_id": "ptf_core01" },
    "triggers": ["status_change", "any_change"],
    "delivery_channels": ["api"],
    "metadata": { "slack_channel": "#ip-alerts" }
  }'
Expected output:
{
  "id": "wat_abc123",
  "object": "watch",
  "watch_type": "portfolio",
  "name": "Aurora Core - status changes",
  "status": "active",
  "alert_count": 0,
  "unacknowledged_count": 0
}
4

Poll for alerts

Check for new alerts on your watches. In production, you would run this on a schedule (hourly or daily).
# Get unacknowledged alerts across all watches
curl "https://api.signa.so/v1/alerts?status=unacknowledged&sort=-created_at&limit=20" \
  -H "Authorization: Bearer $SIGNA_API_KEY"
Expected output:
{
  "object": "list",
  "data": [
    {
      "id": "alt_def456",
      "severity": "high",
      "event_type": "trademark.status_changed",
      "summary": {
        "mark_text": "AURORA",
        "office_code": "euipo",
        "status_stage": "opposition_period"
      },
      "status": "unacknowledged",
      "created_at": "2026-03-24T08:15:00Z"
    }
  ]
}
5

Query upcoming deadlines

Get all deadlines across the portfolio within the next 12 months, sorted by urgency.
curl "https://api.signa.so/v1/portfolios/ptf_core01/deadlines?due_before=2027-03-24&limit=50" \
  -H "Authorization: Bearer $SIGNA_API_KEY"
Expected output:
{
  "object": "list",
  "data": [
    {
      "trademark_id": "tm_a1b2c3d4",
      "mark_text": "AURORA",
      "office_code": "uspto",
      "type": "declaration_of_use",
      "due_date": "2027-01-20",
      "grace_expiry": "2027-07-20",
      "window_opens": "2026-01-20",
      "jurisdiction_code": "US"
    },
    {
      "trademark_id": "tm_e5f6a7b8",
      "mark_text": "AURORA",
      "office_code": "euipo",
      "type": "renewal",
      "due_date": "2027-03-15",
      "grace_expiry": "2027-09-15",
      "window_opens": "2026-03-15",
      "jurisdiction_code": "EU"
    }
  ]
}
6

Subscribe to an iCal feed

Export deadlines as an iCal calendar feed that your entire team can subscribe to in Google Calendar, Outlook, or Apple Calendar. The feed auto-updates as deadlines change.
# Get the iCal feed URL (add to your calendar app)
# Reminders at 90, 30, and 7 days before each deadline
curl "https://api.signa.so/v1/portfolios/ptf_core01/deadlines.ics?reminder_days=90,30,7" \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -o aurora-deadlines.ics
The iCal response contains VEVENT entries like this:
BEGIN:VEVENT
SUMMARY:Renewal: AURORA (EUIPO)
DTSTART;VALUE=DATE:20270315
DESCRIPTION:Trademark AURORA (EU) - Renewal due. Grace period ends 2027-09-15.
BEGIN:VALARM
TRIGGER:-P90D
ACTION:DISPLAY
DESCRIPTION:90-day reminder: AURORA renewal due 2027-03-15
END:VALARM
BEGIN:VALARM
TRIGGER:-P30D
ACTION:DISPLAY
DESCRIPTION:30-day reminder: AURORA renewal due 2027-03-15
END:VALARM
END:VEVENT
Set reminder_days to match your internal SLA. Most firms use 90/60/30/7 day reminders. The 90-day window gives you time to engage outside counsel for filings that require documentation.

Scaling to large portfolios

For organizations with thousands of marks, use pagination to process deadlines and alerts in batches:
async function* getAllDeadlines(portfolioId: string, dueBefore: string) {
  let cursor: string | null = null;
  do {
    const page = await signa.portfolios.deadlines(portfolioId, {
      due_before: dueBefore,
      limit: 100,
      cursor,
    });
    yield* page.data;
    cursor = page.has_more ? page.pagination.cursor : null;
  } while (cursor);
}

// Process all deadlines
for await (const deadline of getAllDeadlines("ptf_core01", "2027-03-24")) {
  // Send to your internal ticketing system, Slack, etc.
}

What’s next

Renewal Management

Deep dive into deadline types, grace periods, and US declaration requirements.

Competitor Intelligence

Set up watches to track competitor filings alongside your own portfolio.

Class Coverage Audits

Identify gaps in your Nice class coverage across jurisdictions.