# USPTO Trademark Status Monitor & Lookup (`technicaldost/uspto-trademark-status-monitor`) Actor

Track US trademarks by serial number. Returns mark text, LIVE/DEAD status, owner, Nice classes, goods and services, and reports exactly what changed since your last run. Built for scheduled portfolio and competitor watching. No API key needed.

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

## Pricing

from $3.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.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## USPTO Trademark Status Monitor & Lookup

**Watch your US trademark portfolio and get told the moment a status changes — abandonment, registration, cancellation, a new owner or a new opposition. No API key required.**

Give it a list of USPTO serial numbers, put it on a weekly schedule, and it reports exactly which marks changed and what changed about them. Missing a status deadline can cost a registration, and nothing on the USPTO side emails you when a third party's mark goes abandoned.

***

### What you get

```json
{
  "markText": "SEEK BEAUTY",
  "serialNumber": "88888888",
  "changeStatus": "changed",
  "changedFields": ["caseStatus", "statusDate", "liveDeadStatus"],
  "liveDeadStatus": "DEAD",
  "caseStatus": "Abandoned because no Statement of Use or Extension Request timely filed after Notice of Allowance was issued.",
  "statusDate": "2022-12-12",
  "previousCaseStatus": "Notice of Allowance sent",
  "previousStatusDate": "2021-11-09",
  "filingDate": "2020-04-27",
  "publicationDate": "2021-09-14",
  "registrationDate": null,
  "register": "Principal",
  "niceClasses": ["036", "039"],
  "goodsAndServices": [
    { "classNumber": "036", "description": "Real estate services, namely, property management services for condominium buildings..." },
    { "classNumber": "039", "description": "Leasing of garage space; Parking garage services..." }
  ],
  "ownerName": "1000 South Michigan Equities, LLC",
  "owners": [
    {
      "name": "1000 South Michigan Equities, LLC",
      "citizenship": "UNITED STATES OF AMERICA",
      "address": "c/o Time Equities, 55 Fifth Avenue, 15th Floor, New York, NEW YORK, 10003, UNITED STATES OF AMERICA"
    }
  ],
  "attorneyName": "Matthew J. Levinstein",
  "attorneyEmail": "chiipmail@gtlaw.com",
  "assignmentCount": 0,
  "proceedingCount": 0,
  "tsdrUrl": "https://tsdr.uspto.gov/statusview/sn88888888",
  "checkedAt": "2026-08-17T17:22:04.118Z"
}
```

`changeStatus` is one of `new`, `changed` or `unchanged`. When it is `changed`, `changedFields` names exactly which fields moved and `previousCaseStatus` / `previousStatusDate` show what they were before.

***

### Main use cases

- **Portfolio docketing.** Watch every mark you own or prosecute and catch status movement without checking TSDR by hand.
- **Competitor and watch-list monitoring.** Track a competitor's applications through publication, allowance and registration — or catch the moment one goes abandoned and the wording becomes available.
- **Abandonment alerts.** `liveDeadStatus` flipping to `DEAD` is the single most actionable signal here.
- **Assignment / ownership tracking.** `assignmentCount` and owner changes surface when a mark is sold.
- **Opposition awareness.** `proceedingCount` rises when TTAB proceedings are filed.
- **Docket reconciliation.** Cross-check your practice management system against the register.

***

### Quick start

Baseline your portfolio (returns everything, records the current state):

```json
{
  "serialNumbers": ["88888888", "97000001"],
  "onlyChanges": false
}
```

Then switch on change-only mode and schedule it weekly:

```json
{
  "serialNumbers": ["88888888", "97000001"],
  "onlyChanges": true
}
```

***

### Input reference

| Field | Type | Default | What it does |
|---|---|---|---|
| `serialNumbers` | array | **required** | 8-digit serial numbers. `88/888,888` and `sn88888888` are normalised. Up to 2,000 per run. |
| `onlyChanges` | boolean | `false` | Return only marks that changed since the last run. |
| `includeMarkText` | boolean | `true` | Add mark wording and goods/services. Cached after the first fetch. |
| `includeProsecutionHistory` | boolean | `false` | Add the file history with document links. |
| `prosecutionHistoryLimit` | integer | `20` | Most recent history entries to include. |
| `stateStoreName` | string | `uspto-trademark-state` | Named store holding previous observations. Use different names for separate portfolios. |

***

### How the monitoring works

Previous observations live in a **named Key-Value Store on your own account**, so your history is yours and persists between runs.

The Actor compares a deliberately narrow set of fields between runs — case status, status date, LIVE/DEAD, registration date, owner name, assignment count and proceeding count. Prosecution history is *excluded* from that comparison on purpose: it accumulates entries constantly, and treating every new document as a "change" would make the monitor cry wolf.

**Mark text is fetched once, then cached.** The USPTO page carrying the mark wording is rate-limited hard, so fetching it for every mark on every run would make scheduled runs slow. Since that wording never changes, the Actor reads it the first time it sees a mark and reuses it afterwards. A weekly run over an established portfolio makes one fast request per mark.

***

### Pricing

| Event | Price | When it happens |
|---|---|---|
| **Trademark record** | **$0.003** | A mark is returned — new, or changed |
| Status check | **$0.0005** | A mark was checked and found unchanged (change-only mode) |

The two-tier design exists so scheduled monitoring stays cheap. A weekly run over 200 marks where nothing changed costs `200 × $0.0005 = $0.10`. The week one mark goes abandoned it costs `199 × $0.0005 + 1 × $0.003 = $0.10`.

**You are not charged for:**

- serial numbers with no USPTO record
- failed requests, retries or USPTO rate-limiting
- invalid serial numbers — reported and skipped before any work
- anything after the maximum charge you set for the run

#### How this compares

| Actor | Price per record | Change detection | Mark text |
|---|---|---|---|
| **This Actor** | **$0.003** (+ $0.0005 unchanged) | yes | yes |
| `memo23/uspto-trademark-scraper` | $0.007 + $0.00005/run | — | — |
| `nexgendata/uspto-trademark-search` | $0.05 + $0.0001/run | — | — |
| `nexgendata/euipo-esearch-trademarks` | $0.10 + $0.005/run | — | EUIPO, not USPTO |

Competitors' list prices as published on Apify Store on 2026-08-17; check current figures before relying on this table.

***

### Using the API

```bash
curl -X POST "https://api.apify.com/v2/acts/technicaldost~uspto-trademark-status-monitor/run-sync-get-dataset-items?token=<TOKEN>" \
  -H 'Content-Type: application/json' \
  -d '{ "serialNumbers": ["88888888"], "onlyChanges": false }'
```

**JavaScript — alert on anything that went dead:**

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('technicaldost/uspto-trademark-status-monitor').call({
    serialNumbers: ['88888888', '97000001'],
    onlyChanges: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const mark of items.filter((m) => m.liveDeadStatus === 'DEAD')) {
    console.log(`${mark.markText} (${mark.serialNumber}) is now DEAD: ${mark.caseStatus}`);
}
```

**Python:**

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")

run = client.actor("technicaldost/uspto-trademark-status-monitor").call(run_input={
    "serialNumbers": ["88888888"],
    "onlyChanges": True,
})

for m in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(m["markText"], m["changeStatus"], m["changedFields"])
```

Add a **webhook** on your Task so a change pushes straight into Slack or your docketing system.

***

### Limitations

Please read these before buying — the scope is deliberate.

- **Lookup by serial number only. There is no wordmark search.** The USPTO search endpoint sits behind a bot-detection challenge, and this Actor does not attempt to defeat it. If you need to *find* marks by name, do that in [USPTO's own search](https://tmsearch.uspto.gov), then bring the serial numbers here to monitor them.
- **Registration numbers are not accepted as input.** The status endpoint keys on serial numbers. A registered mark's serial number is on its registration certificate and on TSDR.
- **Mark text comes from a rate-limited page.** The first run over a large portfolio is slow — budget roughly 4 seconds per new mark. Later runs are fast because the wording is cached. Set `includeMarkText: false` for a fast first run without the wording.
- **No similarity or clearance analysis.** This Actor reports the register's own data. It does not judge likelihood of confusion.
- **US marks only.** No EUIPO, WIPO or other national registers.
- **Not legal advice.** This is a data tool. Docketing decisions and filing deadlines should be confirmed against USPTO's own records and with a qualified attorney.

***

### Related Actors

- **[UK Companies House Scraper & Company Intelligence](https://apify.com/technicaldost/uk-companies-house-intelligence)** — company-level due diligence to sit alongside IP checks.
- **[SEC EDGAR Filing Monitor](https://apify.com/technicaldost/sec-edgar-filing-monitor)** — the same change-detection pattern for US public company filings.

***

### Data source and responsible use

Data comes from public USPTO TSDR endpoints. US trademark register data is a public record produced by the United States federal government. The Actor paces its requests to stay within what the service tolerates and does not attempt to bypass rate limiting or bot detection.

Records include attorney and owner contact details **as published on the public register**. Use them for legitimate IP administration.

Not affiliated with or endorsed by the United States Patent and Trademark Office.

# Actor input Schema

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

8-digit USPTO application serial numbers. Formats like 88/888,888 and sn88888888 are accepted and normalised. Find a serial number on tsdr.uspto.gov or on any USPTO filing receipt.

## `onlyChanges` (type: `boolean`):

Recommended for scheduled runs. The first run records a baseline and returns everything; later runs return only marks that actually changed. Unchanged marks are billed at the much cheaper status-check rate.

## `includeMarkText` (type: `boolean`):

Adds the mark's literal wording and its goods and services. USPTO rate-limits this page hard, so the first run is slower — but the values never change, so they are cached and reused on every later run at no extra time cost.

## `includeProsecutionHistory` (type: `boolean`):

Adds the file history: office actions, responses and notices, each with a document link.

## `prosecutionHistoryLimit` (type: `integer`):

How many of the most recent history entries to include.

## `stateStoreName` (type: `string`):

Named Key-Value Store on your account holding the previous observations and the cached mark text. Use different names to keep separate portfolios independent.

## Actor input object example

```json
{
  "serialNumbers": [
    "88888888"
  ],
  "onlyChanges": false,
  "includeMarkText": true,
  "includeProsecutionHistory": false,
  "prosecutionHistoryLimit": 20,
  "stateStoreName": "uspto-trademark-state"
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `runSummary` (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 = {
    "serialNumbers": [
        "88888888"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("technicaldost/uspto-trademark-status-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 = { "serialNumbers": ["88888888"] }

# Run the Actor and wait for it to finish
run = client.actor("technicaldost/uspto-trademark-status-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 '{
  "serialNumbers": [
    "88888888"
  ]
}' |
apify call technicaldost/uspto-trademark-status-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,technicaldost/uspto-trademark-status-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/kFxUGP68wEvAI4ykU/builds/u1xAbwZld6rkFQ2IQ/openapi.json
