How to Check If a Phrase Is Trademarked (USPTO, in Bulk)

Uses USPTO Trademark Search — Check If a Phrase Is Trademarked

Short answer: Run your phrases through USPTO Trademark Search in contains mode with the classes for your product (25 for clothing, 21 for mugs). Anything marked registered-live or pending needs a closer look; clear means only that no matching mark text is on the US register, not that the phrase is safe. This is not legal advice.

Print-on-demand sellers, Etsy shops and brand namers all hit the same question: has someone already trademarked this phrase? The USPTO's own Trademark Search answers it one query at a time, which is fine for a single name and painful for a spreadsheet of 300 slogans.

The other difficulty is reading the results. A phrase can match dead marks that no longer matter, live marks in classes unrelated to your product, or a pending application that has not been registered yet but can still block you. What you want is a quick triage: which phrases are obviously taken for your product type, which need a human look, and which have nothing on the register.

This guide shows how to do that triage in bulk against the official US register, and where its limits are. It is a first-pass filter, not legal advice, and it does not replace a trademark attorney for anything you plan to build a brand on.

Step by step

  1. Be clear about what a register check can tell you

    The check reports what is on the USPTO register at the moment you run it. It does not cover unregistered common-law rights, state registrations, marks in other countries, design-only marks with no matching text, or confusingly similar marks such as a different spelling. Treat a clear verdict as 'nothing found on the register', not 'free to use'.

  2. Prepare your phrase list

    Put one phrase, slogan or brand name per entry, up to 10,000 per run. Case and extra spaces do not matter, a trailing . or ! is ignored in exact mode, and duplicates are removed and never charged, so you can paste straight from a design sheet without cleaning it first.

  3. Pick a match mode

    exact only finds marks whose whole text equals your phrase. contains finds your phrase anywhere inside a mark, so CAT LOVER also finds CRAZY CAT LOVERS. words requires every word of the phrase in any order, with very common words such as IT or THE ignored by the USPTO index. For screening designs, contains is the cautious default.

  4. Limit the check to your product's classes

    Trademarks are registered for specific Nice classes. For apparel use 25, for mugs and housewares 21, for stickers, posters and paper goods 16, for bags 18 and for phone cases 9. The class filter applies to the verdict too, so a phrase registered only for software comes back clear when you check classes 25 and 21. Leave classes empty if you want to see every registration.

    {
      "phrases": ["Mama Bear", "Coffee Before Talkie", "Plant Mom Club"],
      "searchMode": "contains",
      "classes": ["25"],
      "statusFilter": "all",
      "maxResultsPerPhrase": 10
    }
  5. Triage the results by verdict

    Each row has a verdict of registered-live, pending, dead-only or clear, plus match counts. Pending still counts as a risk: it is a live application in examination. The script below sorts a run's results into three CSV files: blocked, needs review and nothing found. It lists the first matching owner and the TSDR link so the review pile is quick to work through.

    import csv
    import os
    
    from apify_client import ApifyClient
    
    client = ApifyClient(os.environ["APIFY_TOKEN"])
    phrases = [line.strip() for line in open("phrases.txt", encoding="utf-8") if line.strip()]
    
    run = client.actor("actor-forge/uspto-trademark-search").call(run_input={
        "phrases": phrases,
        "searchMode": "contains",
        "classes": ["25", "21"],
        "maxResultsPerPhrase": 5,
    })
    
    buckets = {"blocked": [], "review": [], "nothing_found": []}
    for row in client.dataset(run["defaultDatasetId"]).iterate_items():
        verdict = row.get("verdict")
        matches = row.get("matches") or []
        top = matches[0] if matches else {}
        record = [row.get("phrase"), verdict, top.get("mark", ""), top.get("owner", ""), top.get("tsdrUrl", "")]
        if verdict == "registered-live":
            buckets["blocked"].append(record)
        elif verdict in ("pending", "dead-only"):
            buckets["review"].append(record)
        elif verdict == "clear":
            buckets["nothing_found"].append(record)
    
    for name, rows in buckets.items():
        with open(f"{name}.csv", "w", newline="", encoding="utf-8") as f:
            writer = csv.writer(f)
            writer.writerow(["phrase", "verdict", "mark", "owner", "tsdrUrl"])
            writer.writerows(rows)
        print(name, len(rows))
  6. Open the official record for anything borderline

    Every listed mark has a TSDR link to the official USPTO case file, along with the owner name, state and country, international classes, goods and services, status text and filing and registration dates. Reading the goods and services description is usually the fastest way to see whether a live mark actually covers what you sell.

  7. Re-check before you reprint or scale

    The register changes as new applications are filed; the data is usually updated daily. Re-run your active phrases before a big reprint or a new marketplace launch, and talk to a trademark attorney before relying on any result for a brand you plan to invest in.

Sample input

{
  "phrases": [
    "Just Do It",
    "Mama Bear",
    "Webvan",
    "Coffee Before Talkie"
  ],
  "searchMode": "exact",
  "statusFilter": "live",
  "maxResultsPerPhrase": 20
}

Sample output

Each phrase gets one row with its verdict and live, registered, pending and dead match counts:

phraseverdictliveMatchCountregisteredLiveCountpendingCountdeadMatchCountmatches[0].ownermatches[0].internationalClasses
JUST DO ITregistered-live12759Nike, Inc.009, 010, 021, 025
MAMA BEARregistered-live88026Build-A-Bear Retail Management, Inc.028
WEBVANdead-only00013
COFFEE BEFORE TALKIEclear0000

Run it from code

cURL

curl -X POST "https://api.apify.com/v2/acts/actor-forge~uspto-trademark-search/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"phrases": ["Just Do It", "Mama Bear", "Webvan", "Coffee Before Talkie"], "searchMode": "exact", "statusFilter": "live", "maxResultsPerPhrase": 20}'

JavaScript (Node.js)

// Node.js 18+ (built-in fetch). Set APIFY_TOKEN in your environment.
const input = {
  "phrases": [
    "Just Do It",
    "Mama Bear",
    "Webvan",
    "Coffee Before Talkie"
  ],
  "searchMode": "exact",
  "statusFilter": "live",
  "maxResultsPerPhrase": 20
};

const res = await fetch(
  "https://api.apify.com/v2/acts/actor-forge~uspto-trademark-search/run-sync-get-dataset-items",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.APIFY_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(input),
  }
);
const items = await res.json();
console.log(items.length, items[0]);

Python

# pip install apify-client   (set APIFY_TOKEN in your environment)
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
    "phrases": [
        "Just Do It",
        "Mama Bear",
        "Webvan",
        "Coffee Before Talkie"
    ],
    "searchMode": "exact",
    "statusFilter": "live",
    "maxResultsPerPhrase": 20
}

run = client.actor("actor-forge/uspto-trademark-search").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

The run-sync-get-dataset-items endpoint waits for the run (up to 5 minutes) and returns the dataset rows directly. For longer runs, start the run asynchronously and read the dataset when it finishes, as the Python example does. Replace APIFY_TOKEN with your own token from the Apify console.

What it costs

Checking a batch of 250 slogans costs 250 x $0.03 = $7.50, and 1,000 phrases cost $30.00. Duplicates, invalid phrases and failed checks are not charged.

Charged forWhenPricePer 1,000Worked example
Phrase checkedCharged per phrase checked against the register and delivered (verdict, counts and up to 100 matching marks included)$0.03$301,000 phrases = $30.00
Actor Start (platform start fee)Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event).$0.00005—One run at up to 1 GB = $0.00005 (charged as one event)

Ready to try it? USPTO Trademark Search — Check If a Phrase Is Trademarked runs on Apify, pay per result.

Run on Apify → Read the full actor page

Tips and pitfalls

FAQ

Can I put a trademarked phrase on a T-shirt if the mark is in a different class?

The class filter shows whether a mark is registered for your product class, but whether a use infringes is a legal question that depends on more than the class. Treat the result as information and ask a trademark attorney if it matters.

What does dead-only mean?

Only abandoned, cancelled or expired marks match the phrase. There is no live registration or pending application for it on the register, though older dead marks can be worth a look.

Does this check trademarks outside the US?

No. It checks only the US register held by the USPTO. Marks in other countries and EU registrations are not covered.

Is the data official?

It comes from the public backend of USPTO Trademark Search (tmsearch.uspto.gov) and is as fresh as that service, usually updated daily. The actor is not affiliated with the USPTO.

Actors used in this guide

USPTO Trademark Search — Check If a Phrase Is Trademarked

Bulk-check phrases against the official US trademark register before you list a T-shirt, mug or Amazon product. Verdict per phrase (registered…

$30 per 1,000 · phrase checked

Related guides

How to Export Shopify Store Product Data to CSV or JSON

Give the ActorForge Shopify Store Scraper a store URL, let it page through the public products.json feed, then download the dataset as CSV or JSON…

How to Track Google Trends Trending Searches by Country

Run the ActorForge Google Trends actor with a list of country codes, schedule it daily with only-new mode, and keep a small pandas history to see…

All guides