The USPTO receives thousands of new trademark applications every working day. Most of them don't matter to you. The few that do are the ones that look or sound like your brand, in your classes, filed by someone else. After filing, an application is examined and then published for opposition, and that publication opens a short window to object. Find it late and your options get slower and more expensive.
The USPTO Trademark API returns every US application and registration with its owner, attorney, goods and services and status. This post builds three things on it in Python: a quick clearance check, a portfolio pull by owner, and a daily watch of new filings.
Disclosure: I'm Aurelix, and I built the USPTO Trademark API. It's a paid tool (prices below).
What each record holds
One row per application or registration, straight from USPTO's public Trademark Search:
-
serial_number,registration_number,mark,mark_type,drawing_type,register. -
status(live or dead),status_codeand USPTO'sstatus_description. - Dates:
filing_date,published_for_opposition_date,registration_date,abandoned_date,cancelled_date,renewal_date, first use. -
international_classesand the fullgoods_and_servicestext per class. - The current owner:
owner_name,owner_legal_form,owner_place_of_organization,owner_address, plusprevious_ownersafter an assignment, and theattorneyof record. -
image_url(the drawing) andtsdr_url(USPTO's status page).
A clearance check before you file
pip install apify-client
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("aurelix/uspto-trademark-search").call(
run_input={
"marks": ["glow ritual", "glowritual"],
"classes": ["3"],
"status": "live",
"matchMode": "similar",
"includeNoMatchRows": True,
"maxResultsPerSearch": 50,
}
)
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
if not r["match_found"]:
print(f"{r['search']}: no live mark found")
continue
print(f"{r['search']} -> {r['mark']} ({r['serial_number']}), {r['status_description']}, "
f"owner {r['owner_name']}, classes {', '.join(r['international_classes'])}")
matchMode: "similar" adds one-letter misspellings of longer words and USPTO's sound-alike text, so a check for "nite" also surfaces NIGHT. includeNoMatchRows adds a row for each name that found nothing, so a clean result is explicit rather than an empty file. It is a search, not legal advice: a real clearance also looks at state marks, common-law use and logos.
A competitor's portfolio by owner
run = client.actor("aurelix/uspto-trademark-search").call(
run_input={"owners": ["Patagonia"], "status": "live", "maxResultsPerSearch": 1000}
)
marks = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(len(marks), "live marks")
newest = sorted(marks, key=lambda r: r["filing_date"] or "", reverse=True)[:10]
for r in newest:
print(r["filing_date"], r["mark"], "|", "; ".join(r["goods_and_services"])[:100])
Recent filings and their goods and services are an early hint of what a company plans to sell. Suffixes like Inc. or LLC are optional in owners.
The daily watch
run = client.actor("aurelix/uspto-trademark-search").call(
run_input={
"marks": ["apify"],
"matchMode": "similar",
"classes": ["9", "42"],
"filedWithinDays": 7,
"incremental": True,
"stateKey": "watch-apify",
}
)
for r in client.dataset(run["defaultDatasetId"]).iterate_items():
print(r["change_type"], r["filing_date"], r["mark"], r["owner_name"], r["attorney"], r["tsdr_url"])
With incremental on, the first run returns the current matches and sets a baseline. Each later run with the same stateKey returns only applications filed since the previous run, plus status changes of marks it returned before, such as an application published for opposition (change_type says which). Older matches are never returned as new. Save the input as a task in the Apify Console, schedule it daily in the afternoon UTC (USPTO loads new filings about a day after filing) and add a Slack webhook URL in slackWebhookUrl for a digest. On a quiet day you pay only the run's start fee.
Leave marks and owners empty and keep classes and filedWithinDays set, and you get every new filing in those classes: a morning list for trademark firms whose business development starts from new applications. An empty attorney means the applicant filed without one.
Why this tool
- Search by mark words (exact or similar spelling), by owner, or by serial or registration number, with TSDR links.
- A filing-date filter.
- Only new or changed records since the last run, status changes included: it is built as a watch.
- The full record per mark: owner address, attorney, and goods and services text.
If your interest is new companies rather than new brands, the Recently Funded Companies API does the same for US companies that just raised money, from SEC Form D filings.
Limits
- US federal marks only. No state registrations, common-law use or other countries.
- 10,000 records per search and 100 searches per run. Split bigger jobs by class, filing date or into several runs.
- Similar is spelling and sound, not legal judgement. It does not compare logos.
- Paced for USPTO. USPTO blocks IPs that send too many requests, so a run sends at most about 60 requests per 5 minutes; up to 20 searches share one request, so 100 searches take seconds and 10,000 new filings about 90 seconds. If USPTO still refuses, the run stops cleanly.
-
No prosecution history or documents.
tsdr_urllinks to them on USPTO's status site.
Cost
You pay per record returned, plus the start fee. Records an earlier run already returned and searches USPTO failed to answer are free; the optional no-match row costs the same as a record. The current prices are on the Store page. Apify's free plan includes $5 of credit a month, about 5,000 records.
Top comments (0)