US Trademark Status (USPTO TSDR)
Pricing
$6.00 / 1,000 trademark statuses
US Trademark Status (USPTO TSDR)
Look up your own list of US trademarks by serial or registration number and get each mark's current USPTO status, dates, classes and owner from TSDR, one row per mark.
Look up your own list of US trademarks by serial or registration number and get each mark's current status from the USPTO: status text and date, TM5 status, filing, publication and registration dates, international classes with their goods and services, and the current owner.
The data comes from the public status pages of the USPTO's Trademark Status & Document Retrieval (TSDR) system, one page per mark, and is delivered as a clean dataset you can download as JSON, CSV or Excel, or pull through the API. HTTP-only, no browser. This Actor is not affiliated with or endorsed by the USPTO.
Who it is for: brand owners, in-house counsel and trademark paralegals watching a portfolio, and anyone who needs the status of a known list of marks — before a renewal deadline, during due diligence, or on a schedule to catch a change of status.
What it is not: a bulk downloader or a trademark search. It looks up the numbers you give it and nothing else, at most 1,000 per run, one request at a time with at least 3 seconds between them. If you need the register in bulk, use the USPTO's own bulk data products on the USPTO Open Data Portal — they are the right tool for that, and the USPTO asks bulk users to use them.
What data you get
One row per mark (per serial number):
| Field | Description |
|---|---|
url | The TSDR status page the row was read from |
scrapedAt | ISO 8601 timestamp of the lookup |
caseUrl | The interactive TSDR page for the mark |
serialNumber | Application serial number, 8 digits |
registrationNumber | Registration number, 7 digits (zero-padded); null while not registered |
markText | The mark's literal elements; null for a design-only mark |
markType | Trademark, Service Mark, Collective Mark, Certification Mark, or a combination |
register | Principal or Supplemental |
status | TSDR's status text (without the website's on-screen instructions) |
statusDate | Date of the current status (YYYY-MM-DD) |
statusDescriptor | TM5 common status, e.g. LIVE/REGISTRATION/Issued and Active |
filingDate | Application filing date |
registrationDate | Registration date; null while not registered |
publicationDate | Date published for opposition, where TSDR shows one |
internationalClasses | Array of { classNumber, goodsAndServices, classStatus }, one entry per class |
ownerName | Current owner (holder) of the mark as it appears on the register |
ownerLegalEntityType | CORPORATION, LIMITED LIABILITY COMPANY, INDIVIDUAL, … |
ownerCity | City of the owner's address — organisations only, null for individuals |
ownerState | State of the owner's address (US addresses) — organisations only |
ownerCountry | Country of the owner's address — organisations only |
ownerCount | How many current owners TSDR lists; the owner fields describe the first one |
Dates are ISO 8601 strings. classNumber is a string exactly as the USPTO writes it ("009", "032",
and "A", "B" or "200" for certification and collective membership marks). In goodsAndServices,
the USPTO's own notation is kept: [..] marks deleted goods, ((..)) goods not claimed in a Section 15
affidavit, *..* added wording.
Input
| Option | Type | Default | Description |
|---|---|---|---|
serialNumbers | array | - | Serial numbers, 8 digits each (85569725) |
registrationNumbers | array | - | Registration numbers, 7 digits each (4185310; pad older ones: 0022406) |
maxItems | integer | 1000 | Stop after this many results (max 1,000). Also your cost cap. |
There is no proxy option: the Actor always talks to TSDR directly, as one identified client (see "How it treats the USPTO's servers").
- Spaces and punctuation are stripped before a number is checked, so
97/123,456and4,185,310work. - Numbers are validated strictly: a serial number has exactly 8 digits, a registration number exactly 7.
An invalid number is not looked up and not charged; it is listed, with the reason, in the run summary
(
lookups.invalidNumbers) and in the log. - A number given twice is looked up once. A mark given by both its serial and its registration number is returned — and charged — once.
- One run looks up at most 1,000 numbers (both lists together, after removing invalid and repeated ones). A bigger list fails the run before any request is made; split it across runs.
- An empty input is not free. With no numbers at all, the Actor looks up three example marks —
GOOGLE (serial
85569725), STARBUCKS COFFEE (serial98137935) and COCA-COLA (registration0022406) — and charges for them like any other result (three results).
Example input:
{"serialNumbers": ["85569725", "98137935"],"registrationNumbers": ["0022406", "4185310"]}
Output example
A real row from a local run on 2026-09-27 (registration number 0022406):
{"url": "https://tsdr.uspto.gov/statusview/rn0022406","scrapedAt": "2026-09-27T10:37:47.880Z","caseUrl": "https://tsdr.uspto.gov/#caseNumber=70022406&caseSearchType=US_APPLICATION&caseType=DEFAULT&searchType=statusSearch","serialNumber": "70022406","registrationNumber": "0022406","markText": "COCA-COLA","markType": "Trademark","register": "Principal","status": "The registration has been renewed.","statusDate": "2022-09-27","statusDescriptor": "LIVE/REGISTRATION/Issued and Active","filingDate": "1892-05-14","registrationDate": "1893-01-31","publicationDate": null,"internationalClasses": [{"classNumber": "032","goodsAndServices": "[ NUTRIENT OR ] TONIC BEVERAGES","classStatus": "ACTIVE"}],"ownerName": "Coca Cola Company, The","ownerLegalEntityType": "CORPORATION","ownerCity": "Atlanta","ownerState": "GEORGIA","ownerCountry": "UNITED STATES","ownerCount": 1}
A run summary is stored in the run's key-value store under the key OUTPUT. Besides the usual counts
(items pushed, requests, failed requests by category, stop reason) it has a lookups block that accounts
for every number you gave: how many were invalid, repeated, returned, came back with no record (or while
TSDR was unavailable), failed or were not attempted, with a notReturned list naming each number that
produced no row of its own and why, and an invalidNumbers list. A tsdr block says whether the run was
stopped because TSDR refused requests or looked unavailable.
Pricing
Pay per result. You are charged per result and nothing else: no platform usage, no compute units. Invalid numbers, numbers with no TSDR record, numbers not attempted, retries and failed requests are free. An empty input is charged for its three example marks (see "Input"). The current rate is on the Pricing tab of this Actor — that is the only place it is set, so no figure is repeated here.
maxItemscaps the number of results, and therefore the cost, of a run.- The run also stops when it reaches the maximum total charge you set for the run in Apify Console or through the API.
Tips
- Schedule the Actor on your portfolio's list to catch status changes; compare
status,statusDateandstatusDescriptorbetween runs. - Expect about 3.5 seconds per number (3 seconds of spacing plus the answer): 100 numbers take roughly 6 minutes, 1,000 roughly an hour.
- Numbers listed under
lookups.notReturnedwithreason: "notAttempted"were never looked up — the run stopped first (see "Limitations"). Run them again later; they were not charged.
Limitations
- Your list only. No search by mark text, owner or class, and no crawling beyond the numbers given.
- At most 1,000 numbers per run, looked up one at a time, at least 3 seconds between the end of one answer and the next request.
- Status page only. Prosecution history, documents, images, assignments and TTAB proceedings are not fetched.
- Numbers TSDR does not hold, and outages. TSDR answers a number it has no record of with an HTTP
503 "system unavailable" page — the same page its own website shows for it, and the same page an outage
produces. Each number is asked at most twice: after that page, or after a failed request (another
5xx, a timeout, a network error, a page that cannot be read), the Actor asks once more straight away.
If the second ask gets the same page, the number is reported under
lookups.notReturnedwithreason: "noRecordOrUnavailable"; if it fails, withreason: "failed". Either way it cannot tell a bad number from an outage by one answer, so after three such numbers in a row it looks up one mark known to exist (COCA-COLA, registration0022406, not charged). If that fails too, TSDR is taken to be down: the run stops, and the numbers not yet looked up are reported asnotAttempted. If it succeeds, the run goes on and checks again only after a longer streak (6, then 12, …). - The run stops when TSDR refuses it. A 401, 403 or 429 answer is recorded as failed (
blocked) and never asked again. After three refusals in a row — the known-mark check included — the run stops and the remaining numbers are reported asnotAttempted. A refused check counts as a refusal, not as an outage — see "How it treats the USPTO's servers". - Joint owners. When TSDR lists several current owners, the owner fields describe the first one and
ownerCountsays how many there are. - Owner location is given only for organisations (corporations, LLCs, partnerships) and is read from
the address as TSDR prints it (city, then state for US addresses, then country); for some foreign
addresses the USPTO record has a district or prefecture in the city position. For an individual, a sole
proprietorship or any other entity type the three fields are
null.
Source caveats. What the USPTO says about this data:
- The USPTO's online databases "are not designed or intended to be a source for bulk downloads"; bulk data is published separately (see data.uspto.gov).
- TSDR shows the status as of the moment the page is generated; the record changes as the USPTO acts on
the file. A row is a snapshot at
scrapedAt, not a certified copy of the register.
Data and compliance
This Actor collects publicly available data from a public register, and keeps personal data out:
- It fetches TSDR status pages that are reachable without logging in, needs no account or API key, and does not bypass access controls.
- Kept: the name of the mark's current owner, as the holder of the mark, exactly as it appears on the register, with its legal entity type alongside so you can see when the owner is an individual. For an organisation (corporation, LLC, partnership) the city, state and country of its address are kept too. The mark text is the trademark itself and is kept even when it is a person's name.
- Never collected: where an individual owner is located (city, state, country — the fields are
null), or the location of any owner whose entity type is not a known organisation type; any owner's street address and postal code; an individual owner's citizenship; any e-mail address or phone or fax number; the attorney of record; the correspondent (name, address, e-mail); the domestic representative; examining attorneys and other USPTO staff; signatories on filings. These fields are not extracted, and a safety net removes them should they ever appear. - The USPTO asks that its data be credited: "Source: United States Patent and Trademark Office, www.uspto.gov". Trademarks in the results belong to their owners.
How it treats the USPTO's servers
The USPTO's terms of use say that anyone who "in effect, deny or decrease service by generating unusually high numbers of database accesses", manually or automated, may be denied access. This Actor is built to stay far from that:
- one request at a time, at least 3 seconds after the previous answer (robots.txt included), at most two asks per mark, no search pages, no documents;
- at most 1,000 numbers per run;
- no proxy, and no option to add one: the USPTO sees one plain, identified client, never a rotating pool of addresses;
- a plain User-Agent that names the Actor, and no headers that imitate a browser;
- a 401, 403 or 429 answer is recorded and the request abandoned — never asked again, never from another address — and three in a row end the run;
- when three numbers in a row come back without a record or fail, and the known mark cannot be fetched either, the run stops instead of working through the rest of the list.
How robots.txt is handled
Before the first page on a host is fetched, the Actor fetches that host's robots.txt once and obeys
it for the rest of the run. Rules are read for the product token openrows, falling back to the *
group when the file does not name us, with * and $ wildcards and the standard "longest matching
rule wins" precedence. A Crawl-delay set for us is honoured, up to 10 seconds. When a page redirects,
the URL the redirect actually leads to is checked again against its own host's rules before anything is
read from it, so a redirect cannot carry the Actor onto a site, or a path, that its owner puts off limits.
- Disallowed URLs are never requested. They are reported under
skipped.robotsDisallowedin the run summary, so you can see exactly how many of your input URLs the site puts off limits. - No
robots.txt(404 or 410) means no rules, and the host is crawled normally. It is counted asrobotsAbsentin the summary. - A
robots.txtwe cannot read means the host is skipped, not crawled. Any other response — 401, 403, 429, a 5xx, a timeout, a network failure, or a 200 that turns out to be an error or login page — leaves us without the site's rules, and this Actor will not guess. Every URL on that host is skipped and counted underskipped.robotsUnknown, and the host and the status that stopped us are listed underrobots.unknownHostsin the summary. If a host you supplied returns no results, look there first.
Removal requests. If you believe this Actor exposes data it should not, open an issue on the Actor's Issues tab and state the serial number(s) concerned. Requests are answered there, and the fields or records in question are removed.
You are responsible for using the extracted data in line with the USPTO's terms of use and the laws that apply to you.
Support
Report bugs and request fields on the Issues tab of this Actor. Include the run ID.