# USPTO Trademark Search API, Scraper & New Filing Monitor (`neverempty/uspto-trademark-search-monitor`) Actor

For brand clearance, trademark watch and competitor filings: USPTO trademarks as an API, one row per mark with serial number, mark, status, owner, classes, goods and services, dates. Search by mark text, owner, live/dead and class. Trademark monitoring returns only new filings and status changes.

- **URL**: https://apify.com/neverempty/uspto-trademark-search-monitor.md
- **Developed by:** [NeverEmpty](https://apify.com/neverempty) (community)
- **Categories:** Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 trademark returneds

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

## USPTO Trademark Search API, Scraper & New Filing Monitor

Search US trademarks at the United States Patent and Trademark Office (USPTO) by **mark text, owner name, live/dead status and international class**, and get one clean row per trademark. Turn on **monitoring mode** and run the same search on a schedule: you get only **new filings** and **trademarks whose status changed** since the last run.

No API key, no login, no proxy. The Actor reads the same public search that the USPTO trademark search page uses.

### What you can do with it

- **Clearance check**: is a brand name already filed or registered in the US, by whom, in which classes, and is it still live?
- **Brand watch**: schedule a search for your brand name and be told when somebody files a similar mark.
- **Competitor watch**: schedule a search by owner name and see every new application a company files and every status change (published, registered, abandoned, cancelled).
- **Portfolio export**: all trademarks of one owner with status, classes, dates and goods and services.

### Input

| Field | What it does |
|---|---|
| `markText` | Words of the trademark. Uses the word-mark field of the USPTO search: marks that match every word are returned, an exact phrase ranks first. |
| `ownerName` | Owner or applicant name. Marks with an owner whose name contains these words as a phrase (same order) are returned. |
| `status` | `all` (default), `live` or `dead`, as the USPTO marks the record. |
| `internationalClasses` | One or more international (Nice) classes, `001` to `045`. A mark matches when it is filed in at least one of them. |
| `filedAfter` | Only marks filed on or after this date (`YYYY-MM-DD`). |
| `sortBy` | `relevance` (default) or `newest` (filing date, newest first). |
| `maxResults` | Rows to return with monitoring off. Default 100, up to 1,000 per run. |
| `monitoringMode` | Return only new filings and status changes since the last run of the same search. |
| `resetMonitoringState` | Forget everything remembered and start over. |

Give at least one of `markText`, `ownerName` or `internationalClasses`.

Example: every live mark that contains "never empty":

```json
{ "markText": "never empty", "status": "live", "maxResults": 100 }
```

Example: watch new filings of one company:

```json
{ "ownerName": "Fluid Research Corporation", "monitoringMode": true }
```

### Output

One row per trademark:

```json
{
  "serialNumber": "86641208",
  "registrationNumber": null,
  "markText": "NEVEREMPTY",
  "markPseudoText": ["NEVER EMPTY"],
  "isLive": false,
  "isRegistered": false,
  "statusCode": 602,
  "statusDescription": "ABANDONED-FAILURE TO RESPOND OR LATE RESPONSE",
  "markTypes": ["TRADEMARK"],
  "drawingDescription": "(4) STANDARD CHARACTER MARK",
  "filedDate": "2015-05-26",
  "registrationDate": null,
  "abandonDate": "2016-10-14",
  "firstUseDate": "2010-01-01",
  "internationalClasses": ["007"],
  "goodsAndServices": ["(ABANDONED) IC 007: Automated liquid dispending machines; ..."],
  "ownerNames": ["Fluid Research Corporation (CORPORATION; WISCONSIN, USA)"],
  "ownerEntity": "CORPORATION",
  "ownerCity": "Germantown",
  "ownerStateCountry": "WISCONSIN 53022, UNITED STATES",
  "attorney": "Daniel E. Kattman",
  "filingBasis": ["1a"],
  "registerTypes": ["PRINCIPAL"],
  "recordLoadedAt": "2025-11-07T22:57:15",
  "tsdrUrl": "https://tsdr.uspto.gov/#caseNumber=86641208&caseType=SERIAL_NO&searchType=statusSearch",
  "searchedFor": { "markText": "neverempty", "ownerName": null, "status": "all", "internationalClasses": [], "filedAfter": null },
  "scrapedAt": "2026-10-05T09:00:00.000Z"
}
```

Other columns: `publishedForOppositionDate`, `cancelDate`, `renewalDate`, `firstUseInCommerceDate`, `priorityDate`, `usClasses`, `ownerCitizenship`, `ownerType`, `drawingCode`, `isStandardCharacterMark`, `disclaimer`, `markDescription`, `translation`, `designCodes`. In monitoring mode every row also has `change` (`new` or `status-changed`), `previousStatusCode` and `previousCheckedAt`.

Values are passed on as the USPTO gives them. Status codes and descriptions are the USPTO's own; nothing is translated or guessed. A value the USPTO does not give is `null` or an empty list. Design marks without words have `markText: null`. The USPTO word-mark field also matches pseudo marks and some translated or transliterated marks (a search for "apple" returned the mark YABLONI), so a few rows may not show your word in `markText`. The street address of the owner is not returned.

### Monitoring mode

1. **First run of a search**: the trademarks that match now and their status codes are remembered. No trademark row is returned and nothing is charged.
2. **Later runs of the same search** return only:
   - `change: "new"`: a trademark that was not in the search before. Usually a new filing. With a `status` filter it can also be an existing mark whose status moved into the filter.
   - `change: "status-changed"`: a trademark whose USPTO status code is different from the remembered one; `previousStatusCode` holds the old code.
3. A run that finds nothing new returns no trademark row, says so in a free note row (`no-change-since-last-run`) and is charged one small monitoring check.

Good to know:

- Trademarks are remembered per search (mark text, owner name, status, classes, filed-after). Changing any of them starts a new search with its own first run.
- One search watches up to 2,000 trademarks, newest filing dates first. If more match, a note row says so; status changes of older marks are then not seen. Narrow the search to watch all of it.
- `maxResults` is not applied in monitoring mode: every new or changed trademark is returned. If the maximum charge of the run is too small for all of them, the rest are not remembered and come in the next run.
- The USPTO search index looked refreshed about once a day when this Actor was built (October 2026), so running more often than daily rarely finds anything new.
- Do not run two schedules with the same search at the same moment; one could overwrite what the other remembered.

### Rows that are not charged

When there is no trademark row to give, the dataset holds a note row with `status` and `message` instead, so an empty result is never silent: `no-results` (the USPTO answered that 0 trademarks match), `no-change-since-last-run`, `monitoring-baseline`, `monitoring-covers-newest-only`, `limit-reached`, `budget-reached`, `partial-read`, `unreadable`, `blocked`, `search-rejected`, `bad-input`, `not-read`. Note rows have `serialNumber: null`.

### Price

- **Trademark returned**: charged per trademark row.
- **Monitoring check**: charged once for a monitoring run that compared the search and had nothing new to return.
- No start fee. Note rows, the first monitoring run, and searches that could not be read are free.

### Limits

- Up to 1,000 rows per run with monitoring off, 2,000 watched trademarks per search in monitoring mode. This Actor is for searches and watches, not for copying the register; for the whole register use the USPTO's bulk data products.
- Requests go to the USPTO one at a time with more than a second between them, at most 100 trademarks per request.
- The data is the USPTO search index. The official record of a trademark is its USPTO status page (`tsdrUrl`). This is not legal advice and not a full clearance search: similar-sounding marks, design marks and common-law marks need their own search.
- If the USPTO refuses or changes the search, the run says so in a note row and charges nothing for it.

Data source: United States Patent and Trademark Office (USPTO), www.uspto.gov. This Actor is not affiliated with or endorsed by the USPTO.

### Thanks for using this Actor

We build these tools for people who run them every day, and we improve them from what users tell us.

- **Missing a field, or need another filter?** Tell us in the **Issues** tab. If the data is there, we add it.
- **Found a bug or a wrong value?** Post the run ID in the **Issues** tab. Wrong data is the thing we fix first.

If this Actor saved you time, a short review helps other people find it.

# Actor input Schema

## `markText` (type: `string`):

Words of the trademark to search for, for example a brand name. Uses the word-mark field of the USPTO search: trademarks that match every word you give are returned, and an exact phrase match ranks first. Not case-sensitive. The USPTO field also matches pseudo marks and some translated or transliterated marks, so a few rows may not show the word in markText. Leave empty to search by owner or class only.

## `ownerName` (type: `string`):

Name of the owner or applicant, for example Fluid Research Corporation. Trademarks with an owner whose name contains these words as a phrase (same order, not case-sensitive) are returned. Leave empty to search by mark text or class only.

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

Live or dead as the USPTO marks the record.

## `internationalClasses` (type: `array`):

Keep only trademarks filed in at least one of these international (Nice) classes, 1 to 45. Leave empty for every class.

## `filedAfter` (type: `string`):

Keep only trademarks with a filing date on or after this date (YYYY-MM-DD).

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

Used with monitoring off. A search without mark text and owner name is always ordered by filing date. Monitoring always reads the newest filings first.

## `maxResults` (type: `integer`):

With monitoring off, at most this many trademark rows are returned (up to 1,000 per run). Each row is charged; trademarks that are not returned are not read and not charged. Not applied in monitoring mode, where every new or changed trademark is returned.

## `monitoringMode` (type: `boolean`):

Remembers the trademarks of this search between runs. The first run of a search only remembers the trademarks that match now and their status: nothing is returned and nothing is charged. Later runs of the same search return only trademarks that are new in the search (change: new) and trademarks whose USPTO status code changed (change: status-changed, with the previous code). A run that finds nothing new is charged one monitoring check (search-checked) and returns no trademark row. Up to 2,000 trademarks per search are watched, newest filing dates first. Trademarks are remembered per search (mark text, owner, status, classes, filed-after). Do not run two schedules with the same search at the same moment.

## `resetMonitoringState` (type: `boolean`):

Clears everything remembered for this Actor on your account (for every search) before this run reads anything, so with monitoring on this run is a first run again. Use it for one run and turn it off again.

## Actor input object example

```json
{
  "markText": "neverempty",
  "status": "all",
  "sortBy": "relevance",
  "maxResults": 100,
  "monitoringMode": false,
  "resetMonitoringState": false
}
```

# Actor output Schema

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

One row per US trademark that matches the search: serial number, registration number, mark text, live or dead, USPTO status code and description, filing, registration and other dates, international classes, goods and services, owner names and the link to the USPTO status page. In monitoring mode only new trademarks and trademarks with a changed status code. Searches that could not be read, searches with no result or no change, and runs that hit a limit come back as their own rows and are not charged.

# 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 = {
    "markText": "neverempty"
};

// Run the Actor and wait for it to finish
const run = await client.actor("neverempty/uspto-trademark-search-monitor").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 = { "markText": "neverempty" }

# Run the Actor and wait for it to finish
run = client.actor("neverempty/uspto-trademark-search-monitor").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 '{
  "markText": "neverempty"
}' |
apify call neverempty/uspto-trademark-search-monitor --silent --output-dataset

```

## MCP server setup

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

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/dOynqawWidGXXrkbx/builds/3aaJv62E5QAzftFPL/openapi.json
