Skip to main content
You have just closed the acquisition of Helios Consumer Brands Inc. (see M&A Due Diligence). Now you need to execute the ownership transfer — recording the assignment of 312 trademarks across 14 jurisdictions from the old owner to your corporate entity. This is a multi-month project with office-specific requirements and strict sequencing. This guide shows how to use the Signa API to plan, track, and verify the transfer.

Prerequisites

  • A Signa API key with trademarks:read, portfolios:manage, and events:read scopes
  • Completed due diligence with a known list of marks to transfer
  • The acquiring entity’s owner ID in Signa

1

Create a transfer portfolio

Create a dedicated portfolio to track the marks being transferred. Use metadata to store the deal reference and key dates.
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-helios-transfer" \
  -d '{
    "name": "Helios Acquisition - Transfer Tracking",
    "description": "312 marks transferring from Helios Consumer Brands Inc. to Apex Global Corp.",
    "metadata": {
      "deal_id": "ACQ-2026-0042",
      "seller_owner_id": "own_helios01",
      "buyer_owner_id": "own_apex01",
      "closing_date": "2026-03-01",
      "target_completion": "2026-09-30"
    }
  }'
2

Populate the portfolio with all acquired marks

Add every mark from the seller (and subsidiaries) to the transfer portfolio.
# Collect all mark IDs from the seller and subsidiaries
# (use pagination as shown in the M&A Due Diligence guide)

# Add them in batches of 100
curl -X POST https://api.signa.so/v1/portfolios/ptf_transfer01/marks \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: add-transfer-marks-batch-001" \
  -d '{
    "trademark_ids": ["tm_hel001", "tm_hel002", "tm_hel003"]
  }'
3

Assess transfer readiness for each mark

Not every mark can be transferred immediately. Check for blocking conditions: pending proceedings, marks in opposition, grace period deadlines, and marks held by subsidiaries that may need separate assignment documents.
interface TransferAssessment {
  trademarkId: string;
  markText: string;
  office: string;
  jurisdiction: string;
  status: string;
  currentOwner: string;
  blockers: string[];
  urgentDeadlines: any[];
  readiness: "ready" | "blocked" | "needs_attention";
}

const assessments: TransferAssessment[] = [];

// Fetch full details for all marks
for (let i = 0; i < allMarkIds.length; i += 100) {
  const batch = allMarkIds.slice(i, i + 100);
  const details = await signa.trademarks.batch({ ids: batch });

  for (const tm of details.data) {
    const blockers: string[] = [];

    // Check status blockers
    if (["abandoned", "cancelled", "expired", "refused"].includes(tm.status.stage)) {
      blockers.push(`Status is ${tm.status.stage} - cannot transfer`);
    }

    // Check for pending proceedings
    if (tm.proceedings_count > 0) {
      const procs = await signa.trademarks.proceedings(tm.id, { limit: 5 });
      const pending = procs.data.filter((p) => p.status === "pending");
      if (pending.length > 0) {
        blockers.push(`${pending.length} pending proceeding(s)`);
      }
    }

    // Check for imminent deadlines
    const urgentDeadlines = tm.deadlines.filter((d) => {
      const daysUntil = Math.ceil(
        (new Date(d.due_date).getTime() - Date.now()) / (1000 * 60 * 60 * 24),
      );
      return daysUntil <= 90 && daysUntil > 0;
    });

    if (urgentDeadlines.length > 0) {
      blockers.push(`${urgentDeadlines.length} deadline(s) within 90 days`);
    }

    assessments.push({
      trademarkId: tm.id,
      markText: tm.mark_text,
      office: tm.office_code,
      jurisdiction: tm.jurisdiction_code,
      status: tm.status.stage,
      currentOwner: tm.owners[0]?.name || "unknown",
      blockers,
      urgentDeadlines,
      readiness:
        blockers.length === 0
          ? "ready"
          : blockers.some((b) => b.includes("cannot transfer"))
            ? "blocked"
            : "needs_attention",
    });
  }
}

// Summary
const ready = assessments.filter((a) => a.readiness === "ready");
const blocked = assessments.filter((a) => a.readiness === "blocked");
const needsAttention = assessments.filter((a) => a.readiness === "needs_attention");

console.log("\n=== Transfer Readiness ===");
console.log(`Ready to transfer: ${ready.length}`);
console.log(`Needs attention: ${needsAttention.length}`);
console.log(`Blocked: ${blocked.length}`);

if (needsAttention.length > 0) {
  console.log("\n--- Marks needing attention ---");
  for (const a of needsAttention) {
    console.log(`  ${a.markText} (${a.office} / ${a.jurisdiction})`);
    for (const b of a.blockers) {
      console.log(`    - ${b}`);
    }
  }
}
Expected output:
=== Transfer Readiness ===
Ready to transfer: 278
Needs attention: 19
Blocked: 15

--- Marks needing attention ---
  HELIOS GLOW (euipo / EU)
    - 1 pending proceeding(s)
    - 1 deadline(s) within 90 days
  HELIOS PURE (uspto / US)
    - 1 deadline(s) within 90 days
4

Plan the recording sequence by jurisdiction

Each office has different requirements and timelines for recording assignments. Group marks by office and plan the sequence.
// Group ready marks by office
const byOffice: Record<string, TransferAssessment[]> = {};
for (const a of assessments.filter((a) => a.readiness === "ready")) {
  if (!byOffice[a.office]) byOffice[a.office] = [];
  byOffice[a.office].push(a);
}

console.log("\n=== Recording Plan ===");
for (const [office, marks] of Object.entries(byOffice).sort((a, b) => b[1].length - a[1].length)) {
  console.log(`\n${office.toUpperCase()} (${marks.length} marks)`);

  // Count unique current owners (some may be subsidiaries)
  const owners = [...new Set(marks.map((m) => m.currentOwner))];
  console.log(`  Current owners: ${owners.join(", ")}`);
  console.log(`  Assignment documents needed: ${owners.length}`);
}
Office-specific transfer requirements:
OfficeRecording MethodTypical TimelineNotes
USPTOFile assignment via ETAS (electronic)2-4 weeksOne document can cover multiple marks
EUIPORecord transfer via eService4-8 weeksEach mark needs separate request
WIPO (Madrid)File MM5 form via Madrid eRenewal6-12 weeksRecorded at IB, then notified to each designated office
CIPOFile via CIPO Online4-6 weeks
UKIPOFile TM16 form2-4 weeks
DPMAFile via DPMAregister4-8 weeksGerman language required
5

Set up watches to track recording progress

Create a watch on the transfer portfolio to detect when offices process the ownership changes. When an office records the assignment, the mark’s owner field will update — triggering an alert.
curl -X POST https://api.signa.so/v1/watches \
  -H "Authorization: Bearer $SIGNA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: watch-helios-transfer" \
  -d '{
    "name": "Helios transfer - ownership changes",
    "watch_type": "portfolio",
    "criteria": { "portfolio_id": "ptf_transfer01" },
    "triggers": ["any_change"],
    "delivery_channels": ["api"],
    "metadata": { "deal_id": "ACQ-2026-0042", "watch_purpose": "transfer_tracking" }
  }'
6

Monitor transfer progress

Periodically check how many marks have been re-recorded to the new owner. Use the event stream and owner lookups to track progress.
// Check how many marks are now owned by the acquiring entity
const buyerMarks = await signa.owners.trademarks("own_apex01", {
  limit: 1,
  include_total: true,
});

// Check alerts for ownership changes
const alerts = await signa.alerts.list({
  watch_id: transferWatch.id,
  status: "unacknowledged",
  sort: "-created_at",
  limit: 50,
});

// For each alert, check if it is an ownership change
let transfersRecorded = 0;
for (const alert of alerts.data) {
  const detail = await signa.events.retrieve(alert.id);
  // Ownership changes appear as trademark.updated events
  // with changed_fields including owner-related fields
  if (detail.type === "trademark.updated") {
    transfersRecorded++;
  }
}

const totalToTransfer = allMarkIds.length;
const readyCount = ready.length;
const blockedCount = blocked.length;

console.log("\n=== Transfer Progress ===");
console.log(`Total marks: ${totalToTransfer}`);
console.log(`Ready to transfer: ${readyCount}`);
console.log(`Transfers detected: ${transfersRecorded}`);
console.log(`Blocked/Inactive: ${blockedCount}`);
console.log(`Remaining: ${readyCount - transfersRecorded}`);
console.log(
  `Progress: ${((transfersRecorded / readyCount) * 100).toFixed(0)}%`,
);
Run this progress check weekly and share the results with the deal team. Set a calendar reminder using the portfolio’s iCal feed for key milestones (e.g., “all USPTO transfers should be complete by June 30”).
7

Verify completed transfers

Once a transfer is recorded, verify that the mark’s owner record has been updated correctly by pulling the trademark detail.
curl https://api.signa.so/v1/trademarks/tm_hel001 \
  -H "Authorization: Bearer $SIGNA_API_KEY"
You can also review the change history to see exactly when the ownership changed:
curl "https://api.signa.so/v1/trademarks/tm_hel001/changes?limit=5&sort=-created_at" \
  -H "Authorization: Bearer $SIGNA_API_KEY"

Transfer timeline tracker

Build a summary view for your deal team:
PhaseStatusCountTarget Date
Due diligence completeDone312 marks inventoried2026-03-01
Assignment documents executedDone4 documents (3 entities)2026-03-15
USPTO recordings filedIn progress124 marks2026-04-30
EUIPO recordings filedIn progress68 marks2026-05-31
WIPO/Madrid recordings filedPending42 marks2026-06-30
Other offices filedPending44 marks2026-07-31
All recordings confirmedPending278 marks (excl. blocked)2026-09-30

What’s next

Portfolio Monitoring

Set up ongoing monitoring for the transferred marks under the new owner entity.

Renewal Management

Ensure no deadlines are missed during the transfer process.

Class Coverage Audits

Audit the combined portfolio for coverage gaps after the acquisition.