# USPTO Trademark Search — Lookup & Monitoring API | $2.50/1k (`glasswing/uspto-trademark-scraper`) Actor

Search US trademarks on USPTO by word mark, owner or goods, or look up serial and registration numbers: status, Nice classes, filing and registration dates, company owner, goods and services. Filter live/dead, class, filing date. No login.

- **URL**: https://apify.com/glasswing/uspto-trademark-scraper.md
- **Developed by:** [Raffy](https://apify.com/glasswing) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 trademark records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does USPTO Trademark Search do?

Search the US trademark register and get every match as a clean row: **word mark**, serial and registration number, **status** (live or dead, plus the USPTO status text), **Nice classes**, goods and services, filing, publication, registration, abandonment and cancellation dates, and the **owner when it is a company** (name, entity type, state of incorporation, city). It is built for brand owners, trademark attorneys and paralegals, startups naming a product, and IP-monitoring tools that need USPTO trademark data in bulk instead of one search at a time.

Type a word, an owner name or a goods description, or paste serial and registration numbers, and get a **USPTO trademark lookup** as JSON, CSV or Excel, or from the Apify API. It works as a simple **USPTO trademark API**: filter by live/dead status, international class and filing date, sort by newest filing, and schedule it for **trademark monitoring**. The default 20-mark run finished in **about 7 seconds**.

It reads the public USPTO trademark search (tmsearch.uspto.gov) that any visitor can use, with no login and no API key. Owners who are **individuals are redacted**, and attorney and correspondent details are never output.

### Use cases for this USPTO trademark scraper

- 🔎 **Clearance and name checks.** Before you name a product, search the word in your classes (`classes: ["9", "42"]`, `status: "live"`) and see which live marks already exist, who owns them and since when.
- 🛡️ **Trademark monitoring.** Schedule a daily run with your brand words, `sortBy: "newest"` and `filedFrom` set to last week, and get every new application that contains them.
- 🏢 **Competitor portfolios.** Set **Search in** to owner and type a company name to list its marks, classes and filing activity.
- ⏳ **Status tracking.** Look up your own serial or registration numbers and follow `markStatus` and `registrationDate`.
- 📊 **Market research.** Count new filings in a class or for a word over time (`totalMatches`, `filingDate`) to spot trends.
- 🔁 **Automation.** Send rows to Google Sheets, Airtable, Supabase or a CRM with n8n, Make or Zapier, or call the Actor from an AI agent: it runs with no input at all.

### What data you get from every trademark

One row per trademark application. The **Overview** table shows `serialNumber`, `registrationNumber`, `wordmark`, `markStatus`, `isLive`, `filingDate`, `registrationDate`, `internationalClasses`, `ownerName`, `ownerEntityType`, `searchTerm`, `url`, `status` and `error`.

| Field | What it is |
|---|---|
| `serialNumber` | USPTO serial (application) number, 8 digits. |
| `registrationNumber` | Registration number once the mark is registered. |
| `wordmark` | The mark text (empty for pure design marks). |
| `markStatus` | USPTO status text, for example `REGISTERED AND RENEWED` or `ABANDONED - NO STATEMENT OF USE FILED`. |
| `statusCode` | USPTO numeric status code. |
| `isLive` / `isRegistered` | Live = pending or registered; registered = has a registration. |
| `filingDate`, `publicationDate`, `registrationDate`, `abandonmentDate`, `cancellationDate` | Dates as `YYYY-MM-DD`. |
| `firstUseDate`, `firstUseInCommerceDate` | Claimed dates of first use. |
| `internationalClasses` | Nice classes as 3-digit strings, e.g. `025`. |
| `goodsAndServices` | The goods and services statements, per class. |
| `ownerName` | Current owner when it is an organisation. Omitted for individuals. |
| `ownerEntityType` | `CORPORATION`, `LIMITED LIABILITY COMPANY`, `INDIVIDUAL`, ... |
| `ownerLegalJurisdiction` | Where the owner is organised, e.g. `OREGON, USA`. |
| `ownerCity`, `ownerRegion` | Owner city and state/postcode/country line (organisations only). |
| `ownerRedacted` | `true` when the owner's name and address were removed. |
| `owners` | Every owner on record (original applicant, later owners) with the same redaction rule. |
| `markType`, `drawingType`, `registrationType`, `filingBasis` | Trademark or service mark, drawing code, principal or supplemental register, filing basis (1a, 1b, 44e, 66a). |
| `markDescription`, `disclaimer`, `translation`, `designCodes` | Description and colour claims, disclaimed words, translation, logo design search codes. |
| `searchTerm`, `totalMatches` | The term that found the mark and how many marks the search matched in total. |
| `url` | The mark's public TSDR status page. |

#### Result status (tri-state output)

Every row has a `status`:

- `ok` - a trademark record. This is the only billed row type.
- `not_found` - the search matched no marks, or a serial/registration number does not exist. Free.
- `error` - the source could not be read after retries, or an input entry was unusable; `error` says why. Free.

### How to search USPTO trademarks with this Actor

1. Open the Actor in Apify Console and click **Try for free**.
2. Type one or more **Search terms**, one per line, and pick **Search in** (word mark, owner name, goods and services, or all). Or paste **Serial or registration numbers**.
3. Optionally narrow it down with **Status**, **International classes**, **Filed on or after/before** and **Sort by**.
4. Set **Maximum results** (start with the default 20) and click **Start**. Records appear in the dataset in real time.
5. Open the **Output** tab or **Export** the dataset as JSON, CSV, Excel, XML or HTML.

To automate it, use the **API** tab (Node.js, Python, curl examples) or add a **Schedule**.

### Input

Every field is optional; the prefilled values already produce a complete run.

| Field | Type | Default | When to change it |
|---|---|---|---|
| `keywords` | array of strings | `["nike"]` | The words to search. Each term is its own search. `"exact phrase"`, `nik*` and `-word` work. |
| `searchIn` | `wordmark` | `owner` | `goods` | `all` | `wordmark` | Search owner names or goods and services instead of the mark text. |
| `serialNumbers` | array of strings | empty | Look up specific serial (8 digits) or registration numbers. |
| `maxItems` | integer | 20 | Rows in total; each search term returns at most this many (max 10,000 per term). |
| `status` | `all` | `live` | `dead` | `all` | Only live or only dead marks. |
| `classes` | array of strings | empty | Nice classes 1-45, e.g. `["25", "9"]`. |
| `filedFrom`, `filedTo` | date `YYYY-MM-DD` | empty | Filing date window. |
| `sortBy` | `relevance` | `newest` | `oldest` | `relevance` | `newest` for monitoring new filings. |
| `startUrls` | array of URLs | an example | TSDR status page URLs or tmsearch URLs with a `query` parameter. Leave the example as is when you use Search terms. |

Example input (a monitoring run for new live coffee filings in classes 30 and 43):

```json
{
    "keywords": ["coffee"],
    "status": "live",
    "classes": ["30", "43"],
    "filedFrom": "2026-10-01",
    "sortBy": "newest",
    "maxItems": 100
}
```

### Output

A real row from the default run (trimmed):

```json
{
    "url": "https://tsdr.uspto.gov/#caseNumber=75187260&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch",
    "status": "ok",
    "serialNumber": "75187260",
    "wordmark": "NIKE",
    "markStatus": "ABANDONED - NO STATEMENT OF USE FILED",
    "statusCode": 606,
    "isLive": false,
    "isRegistered": false,
    "filingDate": "1996-10-24",
    "publicationDate": "1997-11-04",
    "abandonmentDate": "1999-01-28",
    "internationalClasses": ["014"],
    "goodsAndServices": ["(ABANDONED) IC 014: [ timepieces of all types, namely, stopwatches, radial link watches; jewelry ]."],
    "ownerName": "Nike, Inc.",
    "ownerEntityType": "CORPORATION",
    "ownerLegalJurisdiction": "OREGON, USA",
    "ownerCity": "Beaverton",
    "ownerRegion": "OREGON 97005, UNITED STATES",
    "ownerRedacted": false,
    "owners": [{ "name": "Nike, Inc.", "entityType": "CORPORATION", "role": "OWNER AT PUBLICATION", "redacted": false }],
    "markType": "TRADEMARK",
    "drawingType": "(1) TYPED DRAWING",
    "registrationType": "PRINCIPAL",
    "filingBasis": "1b",
    "searchTerm": "nike",
    "totalMatches": 204,
    "scrapedAt": "2026-10-19T07:15:43.528Z"
}
```

When the owner is an individual the row keeps `ownerEntityType: "INDIVIDUAL"` and `ownerRedacted: true`, and has no `ownerName`, `ownerCity` or `ownerRegion`. A missing field means the USPTO record has no such value; it is never a guess.

### How much does it cost to search USPTO trademarks?

Pay per result: **$2.50 per 1,000 trademark records**, plus a $0.005 start fee per run. Rows with status `not_found` or `error` are free.

| Event | Price | Charged when |
|---|---|---|
| `apify-actor-start` | $0.005 | Once per run, when it starts. |
| `result` | $0.0025 | Each trademark record saved with status `ok`. |

| Records | Cost |
|---|---|
| 100 | $0.26 |
| 1,000 | $2.51 |
| 10,000 | $25.01 |

The Actor stops gracefully when your run's maximum charge is reached. No proxy is needed and compute is included.

### How it compares

Other USPTO trademark Actors in the Store charge $3 to $7 per 1,000 records. This one costs $2.50 per 1,000, combines keyword search, owner search, goods-and-services search and number lookups in one run, and filters by status, class and filing date on the USPTO side, so you only pay for the marks you asked for.

It is not for you if you need the full prosecution history, office action documents, the mark images, or attorney and correspondent contact details (never output).

### Integrations, exports and API access

Run it from the Apify API, the JavaScript or Python client, the Apify CLI, or on a **Schedule**. Connect the dataset to Google Sheets, Airtable, Make, n8n, Zapier, Slack or a webhook. AI agents can call it through the Apify MCP server.

### Limitations

- The USPTO search index returns at most 10,000 marks per search. For more, split the search by class, filing date window or status.
- Individual owners are redacted (name, city, address). Owners that are trusts, estates, sole proprietorships or of unknown type are treated the same way.
- The data is what the USPTO search index holds. On 2026-10-19 its newest filings were dated 2026-10-17, so the newest filings and status changes can lag TSDR by a few days.
- Design-only marks have no `wordmark`; search them by owner or goods, or by number.
- The USPTO limits unusually heavy use. The Actor keeps to a few parallel requests; very large monitoring jobs are best split into several scheduled runs.

### FAQ

**Do I need a USPTO account or API key?** No. The Actor uses the public trademark search that any visitor can use. No account, no key.

**Is this the USPTO's own API?** No. It is an independent tool that reads the public USPTO trademark search and returns plain rows.

**How do I monitor new filings for my brand?** Put your brand words in **Search terms**, set **Sort by** to newest and **Filed on or after** to the start of your window, and add a daily **Schedule**.

**Why did I get fewer rows than `maxItems`?** The search matched fewer marks, or the run hit your **Max total charge**. `totalMatches` shows how many marks the search matched.

**Why is `ownerName` empty on some rows?** The owner is an individual (or not clearly an organisation), so the name and address are redacted; `ownerRedacted` is `true` and `ownerEntityType` still tells you the owner type.

**What happens if the USPTO changes something?** Rows come back with `status: error` and a reason instead of silently wrong data, and you are not billed for them. Report it in the **Issues** tab with the run ID.

**Can I use this Actor from an AI agent or MCP client?** Yes. It runs with no input at all, every row is self-describing (`status` plus `error`), and inputs are plain strings.

### Related Actors

- [Domain Intelligence Report](https://apify.com/glasswing/domain-intelligence-report) - use it to check whether the matching .com domain for a name is taken, and who runs it.
- [LinkedIn Company Scraper](https://apify.com/glasswing/linkedin-company-scraper) - use it to profile the companies that own conflicting marks.
- [Google News Scraper](https://apify.com/glasswing/google-news-scraper) - use it to follow news about a brand or a trademark dispute.
- [Keyword Suggestions Scraper](https://apify.com/glasswing/keyword-suggestions-scraper) - use it to see what people search for a brand word before you file it.
- [Google Trends Scraper](https://apify.com/glasswing/google-trends-scraper) - use it to compare interest in candidate brand names.
- [Companies House Scraper](https://apify.com/glasswing/companies-house-scraper) - use it to verify a UK company's legal status, incorporation date, registered office and SIC codes.

### Legal and data-protection notice

This Actor extracts only data that the USPTO publishes in its public trademark search. US government trademark records are public; the USPTO asks that heavy users not overload its servers, and the Actor keeps its request rate low. Owner names, cities and addresses are output only for organisations; for individuals (and owners that are not clearly organisations) they are removed, and attorney and correspondent names, emails, phones and addresses are never output. A word mark can itself be a person's name, because that is what was filed. Your results could therefore still contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you are unsure whether your reason is legitimate, consult your lawyers. You are responsible for complying with applicable law when using the extracted data.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by the United States Patent and Trademark Office. All trademarks belong to their respective owners.

# Changelog

This Actor's version history is a separate document: https://apify.com/glasswing/uspto-trademark-scraper/changelog.md

# Actor input Schema

## `keywords` (type: `array`):

Words to search for, one per line (for example `nike`, `coffee`, `"just do it"`). Each term is a separate search. Quotes match an exact phrase, `*` is a wildcard (`nik*`), `-word` excludes a word. Where the term is searched is set by Search in.

## `searchIn` (type: `string`):

Which part of the record the search terms are matched against.

## `serialNumbers` (type: `array`):

Look up specific marks: 8-digit serial numbers (`97123456`) or registration numbers (`0978952`, `3038323`). Numbers the USPTO does not know return a free `not_found` row.

## `maxItems` (type: `integer`):

Stop after this many records in total. Each search term returns at most this many marks (and never more than 10,000). Each record with status `ok` is one billable result.

## `status` (type: `string`):

Only live marks (pending or registered), only dead marks (abandoned, cancelled, expired), or both.

## `classes` (type: `array`):

Nice classes 1-45, for example `25` (clothing) or `9` (software, electronics). A mark matches if it covers any of the listed classes.

## `filedFrom` (type: `string`):

Only applications filed on or after this date (YYYY-MM-DD). Combine with Sort by newest to monitor new filings.

## `filedTo` (type: `string`):

Only applications filed on or before this date (YYYY-MM-DD).

## `sortBy` (type: `string`):

Best match first, newest filings first, or oldest filings first.

## `startUrls` (type: `array`):

Optional. TSDR status page URLs (`https://tsdr.uspto.gov/#caseNumber=...`) are looked up by their number; tmsearch.uspto.gov URLs with a `query` parameter are searched. Leave the example as is when you use Search terms.

## `proxyConfiguration` (type: `object`):

Optional. The Actor works from Apify's datacenter IPs without a proxy.

## Actor input object example

```json
{
  "keywords": [
    "nike"
  ],
  "searchIn": "wordmark",
  "maxItems": 20,
  "status": "all",
  "sortBy": "relevance",
  "startUrls": [
    "https://tsdr.uspto.gov/#caseNumber=72414176&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "nike"
    ],
    "maxItems": 20,
    "startUrls": [
        "https://tsdr.uspto.gov/#caseNumber=72414176&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("glasswing/uspto-trademark-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": ["nike"],
    "maxItems": 20,
    "startUrls": ["https://tsdr.uspto.gov/#caseNumber=72414176&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("glasswing/uspto-trademark-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "nike"
  ],
  "maxItems": 20,
  "startUrls": [
    "https://tsdr.uspto.gov/#caseNumber=72414176&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call glasswing/uspto-trademark-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,glasswing/uspto-trademark-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/wnQIRV5EakP4uU44v/builds/jGGfkWUIc04hEMpt7/openapi.json
