Skip to content
Terry Carroll edited this page Feb 24, 2021 · 21 revisions

These examples illustrate basic use of Plumage to retrieve status information on a trademark application. Note that as of October 2, 2020, the USPTO requires an API key to access TSDR through its API; to use Plumage, you'll need to register with the USPTO and obtain the free API key. See the PTO's web page TSDR Data API for more information.

The example below calls getTSDRInfo to get TSDR information on application number 75/181,334. The status information is stored in a TSDRData object. Within the TSDRData object, The boolean flag TSDRMapIsValid can be queried to ensure that the TSDR call completed successfully.

The TSDRData object contains two mappings of the TSDR data returned: TSDRSingle and TSDRMulti.

TSDRSingle

TSDRSingle is a mapping of single-valued attributes of the mark. Examples of this are the mark's application number, or its registration date. There is only one such value for each mark, and each is accessed by the key associated with the field. For example, TSDRSingle["ApplicationNumber"] addresses the mark's application number. The keys typically correspond to the attribute names in the XML data provided by TSDR (which may vary from the labels displayed on TSDR itself). The values are strings (even if the value is entirely numeric, such as the application number).

In Plumage-py TSDRSingle is implemented as a Python dict. In Plumage-dotnet (C#), it is implemented as Dictionary<string, string>.

TSDRMulti

TSDRMulti is a set of lists of mappings, where multiple values are applicable, for recurring or potentially recurring data. For example, in the course of a trademark application's life, it has multiple prosecution events: the application is entered into the PTO's system; it is assigned to an examiner; it may have one or more office actions, and the applicant may make one or more amendments or other replies. Each of these is an "event" and reported as an entry in a list (in the case of an event, the MarkEventList) in TSDRMulti. Other multi-valued data are assignments (where ownership or other interest in a mark is transferred from one party to another) and applicants (the PTO tracks the applicant at multiple stages in the prosecution, e.g. at time of application, at time of publication, at time of registration, etc).

For example:

  • TSDRMulti["MarkEventList"] is a list of events associated with the application.
  • TSDRMulti["MarkEventList"][0] is the entry corresponding the first event (the most recent, as the PTO currently orders the entries) in that list.

That event entry will have a number of key-value entries that pertain to the event:

  • TSDRMulti["MarkEventList"][0]["MarkEventEntryNumber"] is the number of the event. For example, if there have been nineteen events in the history of the mark, the value of this field for the most recent event will be "19".
  • TSDRMulti["MarkEventList"][0]["MarkEventDate"] is the date (and possibly a time) of the event, exactly as the USPTO reports it; for example, "2001-10-03" or "2001-10-03-04:00".
  • TSDRMulti["MarkEventList"][0]["MarkEventDateTruncated"] is the date (and only the date) of the event; for example, "2001-10-03".
  • TSDRMulti["MarkEventList"][0]["MarkEventDescription"] is a description of that event. For example, immediately after a mark is published for opposition, this text will read "PUBLISHED FOR OPPOSITION". The actual text will vary depending on the actual status of the mark you are examining.

In Plumage-py, TSDRMulti is represented as a dict. Each entry in the dict is a list. Each entry in the list is a dict whose keys and data are each strings.

In Plumage-dotnet, TSDRMulti is represented as type Dictionary<string, List<Dictionary<string, string>>>. That is, each entry in the Dictionary is represented as type List<Dictionary<string, string>>; and each entry in the List is of type Dictionary<string, string>.

Examples

The example below (in Python and multiple .NET languages) illustrate the retrieval and display of data from both TSDRSingle and TSDRMulti. It displays several pieces of single-valued data (such as the application and registration numbers and dates) from TSDRSingle. For multi-valued data in TSDRMulti, it selects the most recent (first-listed) entries in ApplicantList and MarkEventList, and displays owner and status information for those entries, respectively.

A complete list of elements returned in the TSDRData object can be found in TSDRData contents.

Python

from Plumage import plumage
t = plumage.TSDRReq()
t.SetAPIKey("32characterAPIKeyYouGotFromTheUSPTO")
t.getTSDRInfo("75181334", "s")   # get info on application ser. no 75/181,334
tsdrdata=t.TSDRData
if tsdrdata.TSDRMapIsValid:
   print("Application serial no: ", tsdrdata.TSDRSingle["ApplicationNumber"])
   print("Trademark text: ", tsdrdata.TSDRSingle["MarkVerbalElementText"])
   print("Application filing date: ", tsdrdata.TSDRSingle["ApplicationDate"])
   print("Registration no: ", tsdrdata.TSDRSingle["RegistrationNumber"])
   # Owner info is in most recent (0th) entry in ApplicantList
   applicant_list = tsdrdata.TSDRMulti["ApplicantList"]
   current_owner_info = applicant_list[0]
   print("Owner:", current_owner_info["ApplicantName"])
   print("Owner address: ", current_owner_info["ApplicantCombinedAddress"])
   # Get most recent event: 0th entry in event list
   event_list = tsdrdata.TSDRMulti["MarkEventList"]
   most_recent_event = event_list[0]
   print("Most recent event: ", most_recent_event["MarkEventDescription"])
   print("Event date: ", most_recent_event["MarkEventDate"])

C#

Plumage.TSDRReq t = new Plumage.TSDRReq();
t.SetAPIKey("32characterAPIKeyYouGotFromTheUSPTO");
t.getTSDRInfo("75181334", "s");  // get info on application ser. no 75/181,334
if (t.TSDRData.TSDRMapIsValid){
    Console.WriteLine("Application serial no: " + t.TSDRData.TSDRSingle["ApplicationNumber"]);
    Console.WriteLine("Trademark text: " + t.TSDRData.TSDRSingle["MarkVerbalElementText"]);
    Console.WriteLine("Application filing date: " + t.TSDRData.TSDRSingle["ApplicationDate"]);
    Console.WriteLine("Registration no: " + t.TSDRData.TSDRSingle["RegistrationNumber"]);
    // Owner info is in most recent (0th) entry in ApplicantList
    List<Dictionary<string, string>> applicant_list = t.TSDRData.TSDRMulti["ApplicantList"];
    Dictionary<string, string> current_owner_info = applicant_list[0];
    Console.WriteLine("Owner: " + current_owner_info["ApplicantName"]);
    Console.WriteLine("Owner address: " + current_owner_info["ApplicantCombinedAddress"]);
    // Get most recent event: 0th entry in event list
    List<Dictionary<string, string>> event_list = t.TSDRData.TSDRMulti["MarkEventList"];
    Dictionary<string, string> most_recent_event = event_list[0];
    Console.WriteLine("Most recent event: " + most_recent_event["MarkEventDescription"]);
    Console.WriteLine("Event date: " + most_recent_event["MarkEventDate"]);
    }

Although coded in C#, Plumage is a .NET library, and can be invoked from other .NET languages, e.g. Visual Basic .NET and C++ .NET. (Note, I learned just enough VB and C++ to write and test these examples; they are likely not idiomatic code.)

Visual Basic .NET

Dim t As Plumage.TSDRReq = New Plumage.TSDRReq
t.SetAPIKey("32characterAPIKeyYouGotFromTheUSPTO")
t.getTSDRInfo("75181334", "s")   ' get info on application ser. no 75/181,334
If t.TSDRData.TSDRMapIsValid Then
    Console.WriteLine("Application serial no: " + t.TSDRData.TSDRSingle("ApplicationNumber"))
    Console.WriteLine("Trademark text: " + t.TSDRData.TSDRSingle("MarkVerbalElementText"))
    Console.WriteLine("Application filing date: " + t.TSDRData.TSDRSingle("ApplicationDate"))
    Console.WriteLine("Registration no: " + t.TSDRData.TSDRSingle("RegistrationNumber"))
    ' Owner info is in most recent (0th) entry in ApplicantList
    Dim applicant_list As List(Of Dictionary(Of String, String)) = t.TSDRData.TSDRMulti("ApplicantList")
    Dim current_owner_info As Dictionary(Of String, String) = applicant_list(0)
    Console.WriteLine("Owner: " + current_owner_info("ApplicantName"))
    Console.WriteLine("Owner address: " + current_owner_info("ApplicantCombinedAddress"))
    ' Get most recent event: 0th entry in event list
    Dim event_list As List(Of Dictionary(Of String, String)) = t.TSDRData.TSDRMulti("MarkEventList")
    Dim most_recent_event As Dictionary(Of String, String) = event_list(0)
    Console.WriteLine("Most recent event: " + most_recent_event("MarkEventDescription"))
    Console.WriteLine("Event date: " + most_recent_event("MarkEventDate"))
End If

C++ .NET

Plumage::TSDRReq^ t =  gcnew Plumage::TSDRReq;
t->SetAPIKey("32characterAPIKeyYouGotFromTheUSPTO")
t->getTSDRInfo("75181334", "s");  // get info on application ser. no 75/181,334
if (t->TSDRData->TSDRMapIsValid){
    Console::WriteLine("Application serial no: " + t->TSDRData->TSDRSingle["ApplicationNumber"]);
    Console::WriteLine("Trademark text: " + t->TSDRData->TSDRSingle["MarkVerbalElementText"]);
    Console::WriteLine("Application filing date: " + t->TSDRData->TSDRSingle["ApplicationDate"]);
    Console::WriteLine("Registration no: " + t->TSDRData->TSDRSingle["RegistrationNumber"]);
    // Owner info is in most recent (0th) entry in ApplicantList
    List<Dictionary<String^, String^>^>^ applicant_list = t->TSDRData->TSDRMulti["ApplicantList"];
    Dictionary<String^, String^>^ current_owner_info = applicant_list[0];
    Console::WriteLine("Owner: " + current_owner_info["ApplicantName"]);
    Console::WriteLine("Owner address: " + current_owner_info["ApplicantCombinedAddress"]);
    // Get most recent event: 0th entry in event list
    List<Dictionary<String^, String^>^>^ event_list = t->TSDRData->TSDRMulti["MarkEventList"];
    Dictionary<String^, String^>^ most_recent_event = event_list[0];
    Console::WriteLine("Most recent event: " + most_recent_event["MarkEventDescription"]);
    Console::WriteLine("Event date: " + most_recent_event["MarkEventDate"]);
    };

Sample output

In each of the above cases, the examples will print the following information (as of February 2021) on U.S. trademark application serial number 75/181,334.

Application serial no:  75181334
Trademark text:  MONTY PYTHON'S FLYING CIRCUS
Application filing date:  1996-10-15-04:00
Registration no:  2564831
Owner: Python (Monty) Pictures Ltd.
Owner address:  Room 537/538, The Linen Hall//London//W1R 5TB/GB
Most recent event:  CANCELLED SEC. 8 (6-YR)
Event date:  2009-02-07-05:00

Querying by registration number

In the examples show above, the application has matured to registration, and therefore has a registration number (2,564,831) in addition to its application serial number (75/181,334). So in this case, the same date would have been displayed if the getTSDRInfo call had requested data for registration no. 2,564,831 instead of for application serial no. 75/181,334.

Python:

t.getTSDRInfo("2564831", "r")   # get info on reg. no 2,564,831

C#:

t.getTSDRInfo("2564831", "r");  // get info on reg. no 2,564,831

Visual Basic .NET:

t.getTSDRInfo("2564831", "r")   ' get info on reg. no 2,564,831

C++ .NET:

t->getTSDRInfo("2564831", "r");  // get info on reg. no 2,564,831

Note the second parameter has changed from "s" (indicating a serial number) to "r" (indicating a registration number).

Multiple queries

A single TSDRReq object may be reused to successively query TSDR, as shown in the following example (Python), which displays the text of five trademarks, fetched by application number.

t = plumage.TSDRReq()
t.SetAPIKey("32characterAPIKeyYouGotFromTheUSPTO")
application_numbers = ["76535603", "75854426", "86142154", "78790815", "75533975"] 
for application_number in application_numbers:
  result = t.getTSDRInfo(application_number, "s")
  print(t.TSDRData.TSDRSingle["MarkVerbalElementText"])

This displays:

NO BUDDY
ESPEX
ZA
SPANISH
INQUISITION

If making a large number of TSDR queries, be aware that, by default, Plumage pauses for up to one second between TSDR queries, to avoid hammering the TSDR server and to comply with PTO's standard rate limit of sixty queries per minute. See TSDR API Key Usage FAQs, section What is the rate limit for the TSDR API?

Additional features

For simply accessing TSDR status information, the use described above is all that is generally required. However, Plumage provides additional information and options. These include:

  • access to other TSDR data, such as images (set the PTO format to "zip" for this);
  • invoking Plumage in stages, to obtain intermediate data, i.e., the raw XML or the CSV-parsed data, and potentially modifying them before they are processed in later stages;
  • obtaining data in ST.66 XML format, rather than the default ST.96 XML format;
  • overriding the XSLT to obtain different data or additional to accommodate potential future changes made by the USPTO; and
  • obtaining data from a local file rather than from the USPTO (usually useful only for development and testing).

See Data members and Methods for details.