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

# Batch Get Trademarks

> Retrieve multiple trademarks by ID or office-native identifiers in a single request

## Overview

Fetch up to 100 trademarks in a single request. This is significantly more efficient than making individual `GET /v1/trademarks/{id}` calls when hydrating a list of known marks, e.g. after a search or when loading a portfolio view.

The endpoint accepts either:

* `ids`: an array of Signa public IDs (`tm_*`), or
* `identifiers`: an array of office-native identifiers (application number + office, registration number + office, or IR number).

You must supply exactly one of `ids` or `identifiers`. Items that resolve are returned in the `data` array; items that do not match any trademark are returned in the `not_found` array, so callers can reconcile the inputs against the response.

## Request Body

<ParamField body="ids" type="string[]">
  Array of Signa trademark IDs (`tm_*`), max 100. Mutually exclusive with `identifiers`.
</ParamField>

<ParamField body="identifiers" type="object[]">
  Array of office-native identifiers, max 100. Mutually exclusive with `ids`. Each entry must include exactly one of:

  * `application_number` + `office` (lowercase office code, e.g. `uspto`)
  * `registration_number` + `office`
  * `ir_number` (no office; Madrid IRs are global)

  <Expandable title="Identifier object">
    <ParamField body="application_number" type="string">Office-native application number.</ParamField>
    <ParamField body="registration_number" type="string">Office-native registration number.</ParamField>
    <ParamField body="ir_number" type="string">Madrid International Registration number.</ParamField>
    <ParamField body="office" type="string">Office code (lowercase). Required when using `application_number` or `registration_number`.</ParamField>
  </Expandable>
</ParamField>

## Response

<ResponseField name="object" type="string">Always `list`.</ResponseField>

<ResponseField name="data" type="object[]">
  Array of trademark detail-tier objects matching the requested inputs.
</ResponseField>

<ResponseField name="not_found" type="(string | object)[]">
  Inputs that could not be resolved. When `ids` was supplied, this is an array of the unresolved Signa IDs. When `identifiers` was supplied, this is an array of the original identifier objects that did not match. Callers should diff this against the input list to know what to retry or surface.
</ResponseField>

<ResponseField name="has_more" type="boolean">Always `false`. Batch is not paginated.</ResponseField>
<ResponseField name="pagination" type="object">Always `{ "cursor": null }`.</ResponseField>
<ResponseField name="request_id" type="string">Unique request identifier for support and debugging.</ResponseField>

<ResponseExample>
  ```json Response (ids) theme={null}
  {
    "object": "list",
    "data": [
      {
        "id": "tm_8kLm2nPq",
        "object": "trademark",
        "mark_text": "AURORA",
        "mark_text_language": "en",
        "mark_text_script": null,
        "mark_feature_type": "word",
        "mark_legal_category": "standard",
        "right_kind": "trademark",
        "is_series_mark": false,
        "series_count": null,
        "status": {
          "primary": "active",
          "stage": "registered",
          "reason": null,
          "challenges": [],
          "effective_date": "2024-09-18",
          "source": "office",
          "raw_code": "800",
          "raw_label": "Registered"
        },
        "office_code": "uspto",
        "jurisdiction_code": "US",
        "filing_route": "direct_national",
        "scope_kind": "national",
        "origin_office_code": null,
        "source_primary_id": "97123456",
        "application_number": "97123456",
        "registration_number": "7123456",
        "ir_number": null,
        "filing_date": "2023-04-12",
        "registration_date": "2024-09-18",
        "expiry_date": "2034-09-18",
        "expiry_date_basis": "registration_date",
        "renewal_due_date": "2034-09-18",
        "publication_date": "2024-06-01",
        "priority_date": null,
        "termination_date": null,
        "protection_effective_date": null,
        "designation_date": null,
        "dependency_period_end_date": null,
        "transformation_deadline_date": null,
        "is_retracted": false,
        "owners": [
          {
            "id": "own_R3jK9mN2",
            "name": "Aurora Digital Inc.",
            "country_code": "US",
            "entity_type": "corporation",
            "role": "owner",
            "address": {
              "lines": ["100 Market Street"],
              "city": "SAN FRANCISCO",
              "state": "CA",
              "postal_code": "94105",
              "country_code": "US"
            }
          }
        ],
        "attorneys": [
          {
            "id": "att_Lp3mN7qR",
            "name": "Jane Smith",
            "firm_id": "firm_Xk9pQ2rS",
            "firm_name": "Smith & Associates LLP",
            "role": "representative",
            "address": {
              "lines": ["200 Main Street", "Suite 400"],
              "city": "SAN FRANCISCO",
              "state": "CA",
              "postal_code": "94105",
              "country_code": "US"
            }
          }
        ],
        "classifications": [
          {
            "nice_class": 9,
            "nice_edition": "12",
            "goods_services_text": "Computer software for data analytics",
            "goods_services_language": "en",
            "status": null,
            "class_status_raw": null
          },
          {
            "nice_class": 35,
            "nice_edition": "12",
            "goods_services_text": "Business consulting services",
            "goods_services_language": "en",
            "status": null,
            "class_status_raw": null
          },
          {
            "nice_class": 42,
            "nice_edition": "12",
            "goods_services_text": "Cloud computing services",
            "goods_services_language": "en",
            "status": null,
            "class_status_raw": null
          }
        ],
        "design_codes": [],
        "text_variants": [],
        "statements": [],
        "media": [],
        "priority_claims": [],
        "filing_bases": [],
        "publications": [],
        "office_extensions": {},
        "deadlines": [],
        "madrid": null,
        "has_media": false,
        "events_count": 12,
        "proceedings_count": 0,
        "coverage_count": 0,
        "relationships_count": 0,
        "data_freshness": {
          "source_data_date": "2026-04-10",
          "source_format": "dtd_v2",
          "last_updated_at": "2026-04-10T06:00:00.000Z"
        },
        "created_at": "2025-08-01T12:00:00.000Z",
        "updated_at": "2026-04-10T06:00:00.000Z"
      }
    ],
    "not_found": ["tm_Zr5nK8jL"],
    "has_more": false,
    "pagination": { "cursor": null },
    "request_id": "req_bT9kM3nP"
  }
  ```
</ResponseExample>

<ResponseExample>
  ```json Response (identifiers) theme={null}
  {
    "object": "list",
    "data": [
      {
        "id": "tm_8kLm2nPq",
        "object": "trademark",
        "mark_text": "AURORA",
        "mark_feature_type": "word",
        "mark_legal_category": "standard",
        "right_kind": "trademark",
        "status": {
          "primary": "active",
          "stage": "registered",
          "reason": null,
          "challenges": [],
          "effective_date": "2024-09-18",
          "source": "office",
          "raw_code": "800",
          "raw_label": "Registered"
        },
        "office_code": "uspto",
        "jurisdiction_code": "US",
        "filing_route": "direct_national",
        "scope_kind": "national",
        "application_number": "97123456",
        "registration_number": "7123456",
        "filing_date": "2023-04-12",
        "registration_date": "2024-09-18",
        "expiry_date": "2034-09-18",
        "owners": [
          {
            "id": "own_R3jK9mN2",
            "name": "Aurora Digital Inc.",
            "country_code": "US",
            "entity_type": "corporation",
            "role": "owner",
            "address": {
              "lines": ["100 Market Street"],
              "city": "SAN FRANCISCO",
              "state": "CA",
              "postal_code": "94105",
              "country_code": "US"
            }
          }
        ],
        "classifications": [
          {
            "nice_class": 9,
            "nice_edition": "12",
            "goods_services_text": "Computer software for data analytics",
            "goods_services_language": "en",
            "status": null,
            "class_status_raw": null
          }
        ],
        "attorneys": [],
        "design_codes": [],
        "text_variants": [],
        "statements": [],
        "media": [],
        "priority_claims": [],
        "filing_bases": [],
        "publications": [],
        "office_extensions": {},
        "deadlines": [],
        "madrid": null,
        "has_media": false,
        "events_count": 5,
        "proceedings_count": 0,
        "coverage_count": 0,
        "relationships_count": 0,
        "data_freshness": {
          "source_data_date": "2026-04-10",
          "source_format": "dtd_v2",
          "last_updated_at": "2026-04-10T06:00:00.000Z"
        },
        "created_at": "2025-08-01T12:00:00.000Z",
        "updated_at": "2026-04-10T06:00:00.000Z"
      }
    ],
    "not_found": [
      { "registration_number": "9999999", "office": "uspto" }
    ],
    "has_more": false,
    "pagination": { "cursor": null },
    "request_id": "req_cL2nP4qR"
  }
  ```
</ResponseExample>

## Code Examples

<CodeGroup>
  ```bash cURL (ids) theme={null}
  curl -X POST "https://api.signa.so/v1/trademarks/batch" \
    -H "Authorization: Bearer sig_YOUR_KEY_HERE" \
    -H "Content-Type: application/json" \
    -d '{
      "ids": ["tm_8kLm2nPq", "tm_Xp4wQ7vR", "tm_Zr5nK8jL"]
    }'
  ```

  ```bash cURL (identifiers) theme={null}
  curl -X POST "https://api.signa.so/v1/trademarks/batch" \
    -H "Authorization: Bearer sig_YOUR_KEY_HERE" \
    -H "Content-Type: application/json" \
    -d '{
      "identifiers": [
        { "application_number": "97123456", "office": "uspto" },
        { "registration_number": "6789012", "office": "uspto" },
        { "ir_number": "1234567" }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  resp = requests.post(
      "https://api.signa.so/v1/trademarks/batch",
      headers={"Authorization": "Bearer sig_YOUR_KEY_HERE"},
      json={
          "identifiers": [
              {"application_number": "97123456", "office": "uspto"},
              {"ir_number": "1234567"},
          ],
      },
  )
  body = resp.json()
  print(f"Resolved: {len(body['data'])}, missing: {len(body['not_found'])}")
  ```

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

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

  const result = await signa.trademarks.batch({
    identifiers: [
      { application_number: "97123456", office: "uspto" },
      { registration_number: "6789012", office: "uspto" },
      { ir_number: "1234567" },
    ],
  });

  console.log(`Resolved ${result.data.length}, missing ${result.not_found.length}`);
  ```
</CodeGroup>

## When to Use Batch vs. Individual Lookups

| Scenario                                    | Recommended Approach                                                   |
| ------------------------------------------- | ---------------------------------------------------------------------- |
| Display a single trademark detail page      | Individual [Get Trademark](/api-reference/trademarks/get-trademark)    |
| Hydrate a dashboard with 10--50 known IDs   | Batch (this endpoint)                                                  |
| Sync a portfolio of trademarks periodically | Batch, chunked into groups of 100                                      |
| Search for trademarks matching criteria     | [List Trademarks](/api-reference/trademarks/list-trademarks)           |
| Iterate through all trademarks in your org  | Paginated [List Trademarks](/api-reference/trademarks/list-trademarks) |

<Tip>
  A batch request of 50 IDs counts as **one request** against your rate limit, not 50. Use batches whenever you know the IDs upfront. See [Rate Limits](/api-reference/rate-limits).
</Tip>

## Batch Sizing

<Warning>
  Keep batch sizes at or below **100 items**. Requests with more than 100 IDs are rejected with a `400` validation error.
</Warning>

The batch endpoint always returns detail-tier data. Approximate response sizes:

| Batch Size | Approximate Response Size |
| ---------- | ------------------------- |
| 20         | \~200 KB                  |
| 50         | \~500 KB                  |
| 100        | \~1--2 MB                 |

For large batches, smaller chunks complete faster and use less memory.

## Chunking Large Sets

When you have more than 100 IDs, split them into chunks and process sequentially or with controlled concurrency:

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

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

  function chunk<T>(array: T[], size: number): T[][] {
    const chunks: T[][] = [];
    for (let i = 0; i < array.length; i += size) {
      chunks.push(array.slice(i, i + size));
    }
    return chunks;
  }

  async function fetchAllTrademarks(ids: string[]) {
    const results = [];
    for (const batch of chunk(ids, 100)) {
      const response = await signa.trademarks.batch({ ids: batch });
      results.push(...response.data);
      if (response.not_found.length > 0) {
        console.warn("Not found:", response.not_found);
      }
    }
    return results;
  }
  ```

  ```python Python theme={null}
  import requests

  API_KEY = "sig_YOUR_KEY"
  BASE_URL = "https://api.signa.so/v1"

  def chunk(items: list, size: int) -> list[list]:
      return [items[i : i + size] for i in range(0, len(items), size)]

  def fetch_all_trademarks(ids: list[str]) -> list[dict]:
      results = []
      for batch in chunk(ids, 100):
          response = requests.post(
              f"{BASE_URL}/trademarks/batch",
              headers={"Authorization": f"Bearer {API_KEY}"},
              json={"ids": batch},
          )
          response.raise_for_status()
          body = response.json()
          results.extend(body["data"])
          if body.get("not_found"):
              print(f"Not found: {body['not_found']}")
      return results
  ```
</CodeGroup>

<Note>
  A batch request returns HTTP `200` even if some requested items are not found. Always check the `not_found` array to reconcile against your input list.
</Note>

## Errors

| Status | Type               | Description                                                                                                                        |
| ------ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `validation_error` | Both `ids` and `identifiers` supplied, neither supplied, more than 100 items, or an identifier missing the required `office` field |
| 401    | `unauthorized`     | Missing or invalid API key                                                                                                         |
| 403    | `forbidden`        | API key lacks the `trademarks:read` scope                                                                                          |
| 429    | `rate_limited`     | Rate limit exceeded                                                                                                                |

## Related Endpoints

* [Get Trademark](/api-reference/trademarks/get-trademark) -- single trademark lookup
* [List Trademarks](/api-reference/trademarks/list-trademarks) -- filtered listing with pagination
