-
Notifications
You must be signed in to change notification settings - Fork 4
Basic examples
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
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
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 string
s.
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>
.
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.
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"])
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.)
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
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"]);
};
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
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).
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?
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.