> ## 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.

# Trademark Clearance & Screening

> Run a comprehensive availability check before launching a new brand. Search phonetically across jurisdictions, analyze conflicts by status and class, review owner profiles, and generate a clearance report.

You are preparing to launch a new brand called **"Vyntra"** for a line of cloud security software. Before investing in branding and legal filings, you need to determine whether the name is available across your target markets (US, EU, and Canada) in Nice classes 9 and 42.

This guide walks through a full clearance workflow using the Signa API, from initial search to conflict analysis.

## Prerequisites

* A Signa API key with `trademarks:read` scope
* Your target brand name, jurisdictions, and Nice classes

***

<Steps>
  <Step title="Run a phonetic search across jurisdictions">
    Start with a broad search using multiple strategies. Phonetic matching catches near-misses that exact search would miss, for example "Ventra", "Vintra", or "Wyntra".

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.signa.so/v1/trademarks \
        -H "Authorization: Bearer $SIGNA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "query": "Vyntra",
          "strategies": ["exact", "phonetic", "fuzzy", "prefix"],
          "filters": {
            "offices": ["US", "EM", "CA"],
            "nice_classes": [9, 42],
            "status_stage": ["filed", "examining", "published", "registered", "opposition_period"]
          },
          "options": {
            "aggregations": ["status_stage", "office_code", "nice_classes"]
          },
          "limit": 50
        }'
      ```

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

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

      const results = await signa.trademarks.search({
        query: "Vyntra",
        strategies: ["exact", "phonetic", "fuzzy", "prefix"],
        filters: {
          offices: ["US", "EM", "CA"],
          nice_classes: [9, 42],
          status_stage: ["filed", "examining", "published", "registered", "opposition_period"],
        },
        options: {
          aggregations: ["status_stage", "office_code", "nice_classes"],
        },
      });

      console.log(`Matches on this page: ${results.data.length}`);
      console.log("Aggregations:", results.aggregations);
      ```
    </CodeGroup>

    **Expected output:**

    ```json theme={null}
    {
      "object": "list",
      "data": [
        {
          "id": "tm_a1b2c3d4",
          "mark_text": "VENTRA",
          "status": { "primary": "active", "stage": "registered" },
          "office_code": "US",
          "classifications": [
            { "nice_class": 9, "goods_services_text": "Computer software for payment processing and transit fare collection" },
            { "nice_class": 42, "goods_services_text": "Software as a service (SaaS) featuring payment processing software" }
          ],
          "owners": [
            { "id": "own_xyz789", "name": "Cubic Transportation Systems Inc.", "country_code": "US" }
          ],
          "relevance_score": 88,
          "match_explanation": {
            "strategies_matched": ["phonetic", "fuzzy"],
            "boost_factors": [{ "factor": "live_status", "weight": 1.3 }]
          }
        }
      ],
      "aggregations": {
        "status_stage": { "registered": 6, "examining": 4, "abandoned": 3, "expired": 1 },
        "office_code": { "US": 8, "EM": 4, "CA": 2 },
        "nice_classes": { "9": 10, "42": 7, "35": 3 }
      },
      "search_meta": {
        "search_id": "srch_9mKp2vLx",
        "query": "Vyntra",
        "strategies_used": ["exact", "phonetic", "fuzzy", "prefix"],
        "international_registrations": "grouped",
        "execution_time_ms": 87
      },
      "has_more": true,
      "pagination": { "cursor": "eyJpZCI6..." },
      "request_id": "req_8kLm2nPq"
    }
    ```

    <Tip>
      `match_explanation.strategies_matched` tells you **why** each result matched. When `phonetic` is in the list and `relevance_score` is above 85, the names sound nearly identical, a serious conflict risk even if the spelling differs.
    </Tip>
  </Step>

  <Step title="Triage results by risk level">
    Use the aggregations and relevance scores to categorize matches:

    | Risk Level | Criteria                                                                                                                    |
    | ---------- | --------------------------------------------------------------------------------------------------------------------------- |
    | **High**   | `relevance_score` > 85 AND `phonetic` in `strategies_matched` AND same Nice class AND status is `registered` or `examining` |
    | **Medium** | `relevance_score` 70-85 OR adjacent Nice class OR status is `published` / `opposition_period`                               |
    | **Low**    | Only `fuzzy` in `strategies_matched` OR status is `abandoned` / `expired`                                                   |

    Filter the search results to isolate high-risk conflicts:

    <CodeGroup>
      ```bash cURL theme={null}
      # Filter to registered marks with high relevance in the same classes
      curl -X POST https://api.signa.so/v1/trademarks \
        -H "Authorization: Bearer $SIGNA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "query": "Vyntra",
          "strategies": ["exact", "phonetic"],
          "filters": {
            "offices": ["US", "EM", "CA"],
            "nice_classes": [9, 42],
            "status_stage": ["registered", "examining"]
          },
          "limit": 20
        }'
      ```

      ```typescript TypeScript theme={null}
      const highRisk = await signa.trademarks.search({
        query: "Vyntra",
        strategies: ["exact", "phonetic"],
        filters: {
          offices: ["US", "EM", "CA"],
          nice_classes: [9, 42],
          status_stage: ["registered", "examining"],
        },
        limit: 20,
      });

      const conflicts = highRisk.data.filter((tm) => (tm.relevance_score ?? 0) >= 85);
      console.log(`High-risk conflicts: ${conflicts.length}`);
      ```
    </CodeGroup>
  </Step>

  <Step title="Pull full details on each conflict">
    For every high-risk match, fetch the detail tier to see classifications, owners, attorneys, and prosecution history.

    <CodeGroup>
      ```bash cURL theme={null}
      # Batch fetch all conflict marks at once (max 100)
      curl -X POST https://api.signa.so/v1/trademarks/batch \
        -H "Authorization: Bearer $SIGNA_API_KEY" \
        -H "Content-Type: application/json" \
        -d '{
          "ids": ["tm_a1b2c3d4", "tm_e5f6a7b8", "tm_c9d0e1f2"]
        }'
      ```

      ```typescript TypeScript theme={null}
      const details = await signa.trademarks.batch({
        ids: conflicts.map((c) => c.id),
      });

      for (const tm of details.data) {
        console.log(`${tm.mark_text} (${tm.office_code})`);
        console.log(`  Status: ${tm.status.stage}`);
        console.log(`  Classes: ${tm.classifications.map((c) => c.nice_class).join(", ")}`);
        console.log(`  Owner: ${tm.owners[0]?.name}`);
        console.log(`  G&S: ${tm.classifications[0]?.goods_services_text}`);
      }
      if (details.not_found.length > 0) {
        console.log("Not found:", details.not_found);
      }
      ```
    </CodeGroup>

    **Expected output (per mark):**

    ```json theme={null}
    {
      "id": "tm_a1b2c3d4",
      "mark_text": "VENTRA",
      "status": { "primary": "active", "stage": "registered" },
      "office_code": "US",
      "classifications": [
        {
          "nice_class": 9,
          "goods_services_text": "Computer software for payment processing and transit fare collection"
        },
        {
          "nice_class": 42,
          "goods_services_text": "Cloud computing services for payment platforms"
        }
      ],
      "owners": [
        { "id": "own_xyz789", "name": "Cubic Transportation Systems Inc.", "country_code": "US" }
      ],
      "filing_date": "2019-04-12",
      "registration_date": "2020-01-14"
    }
    ```

    <Note>
      Pay close attention to the `goods_services_text` in each classification. Two marks in the same Nice class can coexist if their goods and services descriptions do not overlap. "Payment processing software" and "cybersecurity software" are both Class 9 but serve different markets.
    </Note>
  </Step>

  <Step title="Review the owner's full portfolio">
    Understanding the conflicting owner's portfolio reveals how aggressively they protect their brand and whether they operate in adjacent spaces.

    <CodeGroup>
      ```bash cURL theme={null}
      # Get owner profile with stats
      curl https://api.signa.so/v1/owners/own_xyz789 \
        -H "Authorization: Bearer $SIGNA_API_KEY"

      # List their marks in classes 9 and 42
      curl "https://api.signa.so/v1/owners/own_xyz789/trademarks?nice_classes=9,42&limit=50" \
        -H "Authorization: Bearer $SIGNA_API_KEY"
      ```

      ```typescript TypeScript theme={null}
      const owner = await signa.owners.retrieve("own_xyz789");

      console.log(`Portfolio size: ${owner.stats?.trademark_count}`);
      console.log(`Grant rate: ${((owner.stats?.grant_rate ?? 0) * 100).toFixed(0)}%`);
      console.log(`Jurisdictions: ${owner.stats?.jurisdiction_count}`);

      const ownerMarks = await signa.owners.trademarks("own_xyz789", {
        nice_classes: [9, 42],
        limit: 50,
      });
      console.log(`Marks in Class 9/42: ${ownerMarks.data.length}`);
      ```
    </CodeGroup>

    **Expected output:**

    ```json theme={null}
    {
      "stats": {
        "trademark_count": 142,
        "registered_count": 118,
        "grant_rate": 0.83,
        "jurisdiction_count": 12
      }
    }
    ```

    <Tip>
      A high `grant_rate` (above 80%) and broad jurisdiction coverage suggest an owner with an active legal team. They are more likely to oppose a confusingly similar filing.
    </Tip>
  </Step>

  <Step title="Check for proceedings history">
    See whether the conflicting mark has been involved in oppositions or cancellations. This tells you how actively the owner enforces their rights.

    <CodeGroup>
      ```bash cURL theme={null}
      # Check proceedings on the conflicting mark
      curl "https://api.signa.so/v1/trademarks/tm_a1b2c3d4/proceedings" \
        -H "Authorization: Bearer $SIGNA_API_KEY"

      # Search for opposition proceedings involving the owner
      curl "https://api.signa.so/v1/proceedings?q=Cubic+Transportation+Systems&proceeding_type=opposition&limit=20" \
        -H "Authorization: Bearer $SIGNA_API_KEY"
      ```

      ```typescript TypeScript theme={null}
      // Check proceedings on the conflicting mark
      const proceedings = await signa.trademarks.proceedings("tm_a1b2c3d4");

      // Search for opposition proceedings involving the owner
      const ownerOppositions = await signa.proceedings.list({
        q: "Cubic Transportation Systems",
        proceeding_type: "opposition",
        limit: 20,
      });

      console.log(`Mark proceedings: ${proceedings.data.length}`);
      console.log(`Owner oppositions filed: ${ownerOppositions.data.length}`);

      for (const p of ownerOppositions.data) {
        console.log(`  ${p.proceeding_type} (${p.status}), filed ${p.filed_date}`);
      }
      ```
    </CodeGroup>

    **Expected output:**

    ```json theme={null}
    {
      "object": "list",
      "data": [
        {
          "id": "prc_op001",
          "proceeding_type": "opposition",
          "status": "decided_granted",
          "parties": [
            { "owner_id": "own_xyz789", "name": "Cubic Transportation Systems Inc.", "role": "opponent" },
            { "owner_id": "own_other", "name": "Ventra Labs LLC", "role": "respondent" }
          ],
          "filed_date": "2023-06-15",
          "decision_date": "2024-02-20"
        }
      ]
    }
    ```

    <Note>
      An owner who has successfully opposed similar marks in the past poses a higher risk. In this example, Cubic already won an opposition against another "Ventra"-variant mark, strong evidence they would oppose "Vyntra" too.
    </Note>
  </Step>

  <Step title="Compile a clearance summary">
    Bring together all findings into a structured report. Repeat the opposition lookup from the previous step for each distinct conflict owner, then fold the count into the risk assessment:

    <CodeGroup>
      ```typescript TypeScript theme={null}
      function assessRisk(input: {
        relevanceScore: number;
        status: string;
        phoneticMatch: boolean;
        ownerOppositionsFiled: number;
      }): "high" | "medium" | "low" {
        if (input.relevanceScore >= 85 && input.status === "registered" && input.phoneticMatch) {
          return "high";
        }
        if (input.relevanceScore >= 70 || input.ownerOppositionsFiled > 0) {
          return "medium";
        }
        return "low";
      }

      // Oppositions filed by each distinct conflict owner
      const oppositionsByOwner = new Map<string, number>();
      for (const ownerName of new Set(conflicts.map((tm) => tm.owners[0]?.name).filter((n): n is string => Boolean(n)))) {
        const filed = await signa.proceedings.list({ q: ownerName, proceeding_type: "opposition", limit: 20 });
        oppositionsByOwner.set(ownerName, filed.data.length);
      }

      const report = {
        candidateName: "Vyntra",
        targetJurisdictions: ["us", "eu", "ca"],
        targetClasses: [9, 42],
        searchDate: new Date().toISOString(),
        totalConflicts: conflicts.length,
        conflicts: conflicts.map((tm) => {
          const phoneticMatch = tm.match_explanation?.strategies_matched.includes("phonetic") ?? false;
          const ownerName = tm.owners[0]?.name ?? null;
          const ownerOppositionsFiled = oppositionsByOwner.get(ownerName ?? "") ?? 0;
          return {
            trademarkId: tm.id,
            markText: tm.mark_text,
            office: tm.office_code,
            status: tm.status.stage,
            niceClasses: tm.classifications.map((c) => c.nice_class),
            relevanceScore: tm.relevance_score ?? 0,
            ownerName,
            ownerOppositionsFiled,
            riskLevel: assessRisk({
              relevanceScore: tm.relevance_score ?? 0,
              status: tm.status.stage,
              phoneticMatch,
              ownerOppositionsFiled,
            }),
          };
        }),
        recommendation: conflicts.some((tm) => (tm.relevance_score ?? 0) >= 90)
          ? "HIGH RISK - Consider alternative names"
          : "MODERATE RISK - Proceed with legal counsel review",
      };

      console.log(JSON.stringify(report, null, 2));
      ```
    </CodeGroup>
  </Step>
</Steps>

***

## Watch for new conflicts

Rather than re-running this search on a schedule, create a [watch](/guides/monitoring/watches) scoped to the same query and register a [webhook](/guides/monitoring/webhooks). Signa then evaluates every data update against the watch and pushes an alert the moment a conflicting mark is filed, instead of you polling for one.

If you would rather pull results yourself, keep the `POST /v1/trademarks` body in version control and re-run it on your own schedule, narrowing to `filing_date` so each call only returns conflicts filed since the last run:

```typescript TypeScript theme={null}
const clearanceQuery = {
  query: "Vyntra",
  strategies: ["exact", "phonetic", "fuzzy"],
  filters: {
    offices: ["US", "EM", "CA"],
    nice_classes: [9, 42],
    status_stage: ["filed", "examining", "published", "registered", "opposition_period"],
    filing_date: { gte: lastRunIso },
  },
  limit: 100,
};

const fresh = await signa.trademarks.search(clearanceQuery);
console.log(`New conflicts since ${lastRunIso}: ${fresh.data.length}`);
```

<Tip>
  Persist the timestamp of your last successful run. On the next invocation, pass it as `filing_date.gte` so the API only returns marks filed since then.
</Tip>

***

## What's next

<Card title="Opposition Tracking" href="/guides/use-cases/opposition-tracking">
  Monitor TTAB proceedings if a conflict owner files an opposition against your application.
</Card>

<Card title="Competitor Intelligence" href="/guides/use-cases/competitor-intelligence">
  Track competing owners to catch new filings in your space before they publish.
</Card>
