@biggora/claude-plugins 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +13 -0
- package/CLAUDE.md +55 -0
- package/LICENSE +1 -1
- package/README.md +208 -39
- package/bin/cli.js +39 -0
- package/package.json +30 -17
- package/registry/registry.json +166 -1
- package/registry/schema.json +10 -0
- package/src/commands/skills/add.js +194 -0
- package/src/commands/skills/list.js +52 -0
- package/src/commands/skills/remove.js +27 -0
- package/src/commands/skills/update.js +74 -0
- package/src/config.js +5 -0
- package/src/skills/codex-cli/SKILL.md +265 -0
- package/src/skills/commafeed-api/SKILL.md +1012 -0
- package/src/skills/gemini-cli/SKILL.md +379 -0
- package/src/skills/gemini-cli/references/commands.md +145 -0
- package/src/skills/gemini-cli/references/configuration.md +182 -0
- package/src/skills/gemini-cli/references/headless-and-scripting.md +181 -0
- package/src/skills/gemini-cli/references/mcp-and-extensions.md +254 -0
- package/src/skills/n8n-api/SKILL.md +623 -0
- package/src/skills/notebook-lm/SKILL.md +217 -0
- package/src/skills/notebook-lm/references/artifact-options.md +168 -0
- package/src/skills/notebook-lm/references/auth.md +58 -0
- package/src/skills/notebook-lm/references/workflows.md +144 -0
- package/src/skills/screen-recording/SKILL.md +309 -0
- package/src/skills/screen-recording/references/approach1-programmatic.md +311 -0
- package/src/skills/screen-recording/references/approach2-xvfb.md +232 -0
- package/src/skills/screen-recording/references/design-patterns.md +168 -0
- package/src/skills/test-mobile-app/SKILL.md +212 -0
- package/src/skills/test-mobile-app/references/report-template.md +95 -0
- package/src/skills/test-mobile-app/references/setup-appium.md +154 -0
- package/src/skills/test-mobile-app/scripts/analyze_apk.py +164 -0
- package/src/skills/test-mobile-app/scripts/check_environment.py +116 -0
- package/src/skills/test-mobile-app/scripts/generate_report.py +250 -0
- package/src/skills/test-mobile-app/scripts/run_tests.py +326 -0
- package/src/skills/test-web-ui/SKILL.md +232 -0
- package/src/skills/test-web-ui/references/test_case_schema.md +102 -0
- package/src/skills/test-web-ui/scripts/discover.py +176 -0
- package/src/skills/test-web-ui/scripts/generate_report.py +237 -0
- package/src/skills/test-web-ui/scripts/run_tests.py +296 -0
- package/src/skills/text-to-speech/SKILL.md +236 -0
- package/src/skills/text-to-speech/references/espeak-cli.md +277 -0
- package/src/skills/text-to-speech/references/kokoro-onnx.md +124 -0
- package/src/skills/text-to-speech/references/online-engines.md +128 -0
- package/src/skills/text-to-speech/references/pyttsx3-espeak.md +143 -0
- package/src/skills/tm-search/SKILL.md +240 -0
- package/src/skills/tm-search/references/field-guide.md +79 -0
- package/src/skills/tm-search/references/scraping-fallback.md +140 -0
- package/src/skills/tm-search/scripts/tm_search.py +375 -0
- package/src/skills/wp-rest-api/SKILL.md +114 -0
- package/src/skills/wp-rest-api/references/authentication.md +18 -0
- package/src/skills/wp-rest-api/references/custom-content-types.md +20 -0
- package/src/skills/wp-rest-api/references/discovery-and-params.md +20 -0
- package/src/skills/wp-rest-api/references/responses-and-fields.md +30 -0
- package/src/skills/wp-rest-api/references/routes-and-endpoints.md +36 -0
- package/src/skills/wp-rest-api/references/schema.md +22 -0
- package/src/skills/youtube-search/SKILL.md +412 -0
- package/src/skills/youtube-search/references/parsing-examples.md +159 -0
- package/src/skills/youtube-search/references/youtube-api-quota.md +85 -0
- package/src/skills/youtube-thumbnail/SKILL.md +1060 -0
- package/tests/commands/info.test.js +49 -0
- package/tests/commands/install.test.js +36 -0
- package/tests/commands/list.test.js +66 -0
- package/tests/commands/publish.test.js +182 -0
- package/tests/commands/search.test.js +45 -0
- package/tests/commands/uninstall.test.js +29 -0
- package/tests/commands/update.test.js +59 -0
- package/tests/functional/skills-lifecycle.test.js +293 -0
- package/tests/helpers/fixtures.js +63 -0
- package/tests/integration/cli.test.js +83 -0
- package/tests/skills/add.test.js +138 -0
- package/tests/skills/list.test.js +63 -0
- package/tests/skills/remove.test.js +38 -0
- package/tests/skills/update.test.js +60 -0
- package/tests/unit/config.test.js +31 -0
- package/tests/unit/registry.test.js +79 -0
- package/tests/unit/utils.test.js +150 -0
- package/tests/validation/registry-schema.test.js +112 -0
- package/tests/validation/skills-validation.test.js +96 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tm-search
|
|
3
|
+
description: >
|
|
4
|
+
Use this skill whenever the user wants to search, validate, or look up US trademarks, brand
|
|
5
|
+
names, or keywords in the USPTO trademark database. Triggers include: checking if a brand name
|
|
6
|
+
or word is trademarked, searching trademark registrations, validating whether a keyword is
|
|
7
|
+
available for trademark, looking up trademark status or owner, batch-checking multiple brand
|
|
8
|
+
names, or building any tool/script involving the USPTO trademark database. Also use for
|
|
9
|
+
requests like "is X trademarked?", "find trademarks for [keyword]", "check trademark
|
|
10
|
+
availability", "search USPTO for [name]", or "validate these words against USPTO trademarks."
|
|
11
|
+
Always use this skill for any trademark search or validation task — even simple lookups benefit
|
|
12
|
+
from the correct API patterns and output formats defined here.
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# US Trademark Search Skill (tm-search)
|
|
16
|
+
|
|
17
|
+
This skill enables an agent to search, validate, and analyze US trademarks via USPTO APIs.
|
|
18
|
+
|
|
19
|
+
## API Overview
|
|
20
|
+
|
|
21
|
+
There are **two main API approaches** — choose based on needs:
|
|
22
|
+
|
|
23
|
+
| Use Case | API |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Keyword/name text search, availability check | **tmsearch.uspto.gov** (web backend) |
|
|
26
|
+
| Status lookup by serial/registration number | **tsdrapi.uspto.gov** (official TSDR API) |
|
|
27
|
+
| Batch/programmatic word validation | **tmsearch.uspto.gov** or RapidAPI wrapper |
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## API 1: tmsearch.uspto.gov (New Trademark Search — No API key required)
|
|
32
|
+
|
|
33
|
+
The USPTO replaced TESS in November 2023 with a new search system at `https://tmsearch.uspto.gov`.
|
|
34
|
+
This is a **web application** but its backend can be called directly.
|
|
35
|
+
|
|
36
|
+
### Search Endpoint
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
POST https://tmsearch.uspto.gov/search/keyword
|
|
40
|
+
Content-Type: application/json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Request body:**
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"keyword": "APPLE",
|
|
47
|
+
"searchType": "1",
|
|
48
|
+
"statusType": "A",
|
|
49
|
+
"pluralVariants": false,
|
|
50
|
+
"start": 0,
|
|
51
|
+
"rows": 25
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**Parameters:**
|
|
56
|
+
- `keyword` — the word/phrase to search (required)
|
|
57
|
+
- `searchType` — `"1"` = basic keyword, `"2"` = design code, `"3"` = owner name
|
|
58
|
+
- `statusType` — `"A"` = active/live only, `"D"` = dead only, `""` = all
|
|
59
|
+
- `pluralVariants` — `true` to include plural variations
|
|
60
|
+
- `start` — pagination offset (0-indexed)
|
|
61
|
+
- `rows` — results per page (max 500)
|
|
62
|
+
|
|
63
|
+
### Alternative: GET search
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
GET https://tmsearch.uspto.gov/search/keyword?keyword=APPLE&statusType=A&rows=25
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Response Fields
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"totalFound": 1247,
|
|
74
|
+
"trademarks": [
|
|
75
|
+
{
|
|
76
|
+
"serialNumber": "75123456",
|
|
77
|
+
"registrationNumber": "2345678",
|
|
78
|
+
"wordMark": "APPLE",
|
|
79
|
+
"status": "Live/Registered",
|
|
80
|
+
"statusCode": "A",
|
|
81
|
+
"filingDate": "1997-03-15",
|
|
82
|
+
"registrationDate": "1999-08-17",
|
|
83
|
+
"owner": "Apple Inc.",
|
|
84
|
+
"ownerAddress": "Cupertino, CALIFORNIA, UNITED STATES",
|
|
85
|
+
"internationalClassification": ["009", "042"],
|
|
86
|
+
"goodsServices": "Computers, computer software...",
|
|
87
|
+
"attorney": "...",
|
|
88
|
+
"markDrawingCode": "4"
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
> **Note:** The tmsearch.uspto.gov backend API is not officially documented. If the above endpoint
|
|
95
|
+
> returns errors, fall back to scraping `https://tmsearch.uspto.gov/search/search-information` or
|
|
96
|
+
> use the TSDR API below. See `references/scraping-fallback.md` for the web scraping approach.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## API 2: TSDR API (Official — requires API key for bulk use)
|
|
101
|
+
|
|
102
|
+
Looks up trademark **by serial number or registration number**. Returns full case status, documents.
|
|
103
|
+
|
|
104
|
+
**Base URL:** `https://tsdrapi.uspto.gov/ts/cd/`
|
|
105
|
+
|
|
106
|
+
### Key Endpoints
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Case status by serial number (HTML)
|
|
110
|
+
GET https://tsdrapi.uspto.gov/ts/cd/casestatus/sn{SERIAL_NUMBER}/content.html
|
|
111
|
+
|
|
112
|
+
# Case status as XML (machine-readable)
|
|
113
|
+
GET https://tsdrapi.uspto.gov/ts/cd/casestatus/sn{SERIAL_NUMBER}/info.xml
|
|
114
|
+
|
|
115
|
+
# Case status by registration number
|
|
116
|
+
GET https://tsdrapi.uspto.gov/ts/cd/casestatus/rn{REG_NUMBER}/info.xml
|
|
117
|
+
|
|
118
|
+
# Case documents as PDF bundle
|
|
119
|
+
GET https://tsdrapi.uspto.gov/ts/cd/casedocs/bundle.pdf?sn={SERIAL_NUMBER}
|
|
120
|
+
|
|
121
|
+
# Raw trademark image
|
|
122
|
+
GET https://tsdrapi.uspto.gov/ts/cd/rawImage/{SERIAL_NUMBER}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### API Key (required for bulk/automated use)
|
|
126
|
+
|
|
127
|
+
- Register at: https://account.uspto.gov/api-manager/
|
|
128
|
+
- Add key as header: `USPTO-API-KEY: YOUR_KEY_HERE`
|
|
129
|
+
- Rate limit: **60 requests/minute per API key**
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
curl -H "USPTO-API-KEY: YOUR_KEY" \
|
|
133
|
+
"https://tsdrapi.uspto.gov/ts/cd/casestatus/sn78787878/info.xml"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## CLI Tool Implementation (tm-search)
|
|
139
|
+
|
|
140
|
+
When building the `tm-search` command-line tool, follow this structure:
|
|
141
|
+
|
|
142
|
+
### Core Commands
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
tm-search keyword <word> # Search by keyword
|
|
146
|
+
tm-search keyword <word> --status=A # Active trademarks only
|
|
147
|
+
tm-search keyword <word> --status=D # Dead trademarks only
|
|
148
|
+
tm-search available <word> # Check if word is available (not registered live)
|
|
149
|
+
tm-search status <serial_number> # Lookup by serial number
|
|
150
|
+
tm-search batch <word1,word2,...> # Check multiple words
|
|
151
|
+
tm-search validate <file.txt> # Validate words from a file (one per line)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Output Format
|
|
155
|
+
|
|
156
|
+
Default output: human-readable table
|
|
157
|
+
With `--json`: raw JSON
|
|
158
|
+
With `--csv`: CSV for spreadsheet use
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
KEYWORD: "CLOUDPEAK"
|
|
162
|
+
Status: AVAILABLE (no live trademarks found)
|
|
163
|
+
Dead marks: 2 (see --show-dead for details)
|
|
164
|
+
|
|
165
|
+
KEYWORD: "APPLE"
|
|
166
|
+
Status: REGISTERED (1,247 live marks found)
|
|
167
|
+
Top matches:
|
|
168
|
+
- "APPLE" | Owner: Apple Inc. | Classes: 009,042 | Reg: 1078312
|
|
169
|
+
- "APPLE MUSIC" | Owner: Apple Inc. | Classes: 041 | Reg: 4960099
|
|
170
|
+
...
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Availability Check Logic
|
|
176
|
+
|
|
177
|
+
A keyword is considered **AVAILABLE** if there are zero live/active marks with exact OR confusingly
|
|
178
|
+
similar text. The agent should:
|
|
179
|
+
|
|
180
|
+
1. Search exact keyword with `statusType=A`
|
|
181
|
+
2. If results > 0 → **LIKELY REGISTERED** — show matches
|
|
182
|
+
3. If results == 0 → **LIKELY AVAILABLE** — note this is not legal advice
|
|
183
|
+
4. Always caveat: suggest professional trademark attorney review before filing
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
def check_availability(keyword):
|
|
187
|
+
results = search_trademark(keyword, status="A")
|
|
188
|
+
if results["totalFound"] == 0:
|
|
189
|
+
return "LIKELY AVAILABLE"
|
|
190
|
+
else:
|
|
191
|
+
return f"LIKELY TAKEN ({results['totalFound']} active marks)"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Batch Validation
|
|
197
|
+
|
|
198
|
+
For validating a list of keywords (e.g., from a CSV or text file):
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
words = ["CloudPeak", "SkyBridge", "NeonPulse"]
|
|
202
|
+
results = []
|
|
203
|
+
for word in words:
|
|
204
|
+
r = search_trademark(word.upper(), status="A")
|
|
205
|
+
results.append({
|
|
206
|
+
"keyword": word,
|
|
207
|
+
"status": "AVAILABLE" if r["totalFound"] == 0 else "TAKEN",
|
|
208
|
+
"count": r["totalFound"]
|
|
209
|
+
})
|
|
210
|
+
# Output as table or CSV
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Rate-limit: Add 0.5–1s delay between requests to avoid throttling.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Implementation Notes
|
|
218
|
+
|
|
219
|
+
- The `tmsearch.uspto.gov` endpoint is a **public government site** — no auth required for search
|
|
220
|
+
- Always **uppercase** keywords before searching (USPTO stores marks in uppercase)
|
|
221
|
+
- Include `User-Agent` header to avoid bot detection: `"Mozilla/5.0 (compatible; tm-search/1.0)"`
|
|
222
|
+
- For `pluralVariants=true`, USPTO auto-expands COFFEE → COFFEES, etc.
|
|
223
|
+
- International Classification (Nice Classification) codes define goods/services category
|
|
224
|
+
- Serial numbers are 8 digits; Registration numbers are 7 digits
|
|
225
|
+
|
|
226
|
+
## Reference Files
|
|
227
|
+
|
|
228
|
+
- `references/field-guide.md` — Full field descriptions and Nice Classification codes
|
|
229
|
+
- `references/scraping-fallback.md` — Web scraping approach if API is unavailable
|
|
230
|
+
- `scripts/tm_search.py` — Ready-to-use Python implementation
|
|
231
|
+
- `scripts/tm_validate.py` — Batch validation script
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## Legal Disclaimer to Include in Output
|
|
236
|
+
|
|
237
|
+
Always include when providing availability results:
|
|
238
|
+
> "This is a preliminary search only. Trademark availability is complex and depends on many
|
|
239
|
+
> factors including similar marks, geographic use, and goods/services classification. Consult a
|
|
240
|
+
> licensed trademark attorney before filing."
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# USPTO Trademark Field Guide
|
|
2
|
+
|
|
3
|
+
## Response Field Descriptions
|
|
4
|
+
|
|
5
|
+
| Field | Description | Example |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `serialNumber` | 8-digit USPTO application serial number | `"78787878"` |
|
|
8
|
+
| `registrationNumber` | 7-digit registration number (if registered) | `"3456789"` |
|
|
9
|
+
| `wordMark` | The literal text of the trademark | `"APPLE MUSIC"` |
|
|
10
|
+
| `status` | Human-readable status | `"Live/Registered"` |
|
|
11
|
+
| `statusCode` | `A` = Active/Live, `D` = Dead/Abandoned | `"A"` |
|
|
12
|
+
| `filingDate` | Date application was filed | `"2015-04-01"` |
|
|
13
|
+
| `registrationDate` | Date trademark was registered | `"2016-05-17"` |
|
|
14
|
+
| `owner` | Name of trademark owner/applicant | `"Apple Inc."` |
|
|
15
|
+
| `ownerAddress` | Owner's city, state, country | `"Cupertino, CA, US"` |
|
|
16
|
+
| `internationalClassification` | Nice Classification codes (list) | `["009", "041", "042"]` |
|
|
17
|
+
| `goodsServices` | Description of goods/services covered | `"Computer software..."` |
|
|
18
|
+
| `attorney` | Attorney of record | `"John Smith"` |
|
|
19
|
+
| `markDrawingCode` | Type of mark (see below) | `"4"` |
|
|
20
|
+
| `colorClaimed` | Color claim if any | `"Red and white"` |
|
|
21
|
+
| `disclaimers` | Disclaimed portions of the mark | `"No claim to MUSIC"` |
|
|
22
|
+
|
|
23
|
+
## Mark Drawing Codes
|
|
24
|
+
|
|
25
|
+
| Code | Meaning |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `1` | Typed drawing (word-only, no stylization) |
|
|
28
|
+
| `2` | Design without text |
|
|
29
|
+
| `3` | Design with text |
|
|
30
|
+
| `4` | Standard character mark (modern equivalent of typed) |
|
|
31
|
+
| `5` | Stylized/special form mark |
|
|
32
|
+
| `6` | Color mark |
|
|
33
|
+
|
|
34
|
+
## Trademark Status Codes
|
|
35
|
+
|
|
36
|
+
| Status | Meaning |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `Live/Registered` | Active registered trademark |
|
|
39
|
+
| `Live/Pending` | Application filed, awaiting review |
|
|
40
|
+
| `Dead/Abandoned` | Application abandoned, not pursued |
|
|
41
|
+
| `Dead/Cancelled` | Registration cancelled |
|
|
42
|
+
| `Dead/Expired` | Registration lapsed (not renewed) |
|
|
43
|
+
|
|
44
|
+
## Nice Classification — Common Codes
|
|
45
|
+
|
|
46
|
+
| Class | Covers |
|
|
47
|
+
|---|---|
|
|
48
|
+
| 009 | Computer hardware, software, electronics |
|
|
49
|
+
| 025 | Clothing, footwear, headwear |
|
|
50
|
+
| 030 | Coffee, tea, flour, bread, pastry |
|
|
51
|
+
| 035 | Advertising, business management |
|
|
52
|
+
| 041 | Education, entertainment, sports |
|
|
53
|
+
| 042 | Software as a service, tech services |
|
|
54
|
+
| 043 | Restaurants, hotels, food/drink services |
|
|
55
|
+
| 044 | Medical, veterinary, health services |
|
|
56
|
+
|
|
57
|
+
Full 45-class list: https://www.uspto.gov/trademark/trademark-updates-and-announcements/nice-agreement-eleventh-edition-general-remarks-class
|
|
58
|
+
|
|
59
|
+
## Search Tips
|
|
60
|
+
|
|
61
|
+
### Proximity Searching
|
|
62
|
+
USPTO searches exact word matches. For broader coverage:
|
|
63
|
+
- Search root word AND common variants manually
|
|
64
|
+
- `CLOUD` then `CLOUDS`, `CLOUDY`, `CLOUDPEAK` separately
|
|
65
|
+
|
|
66
|
+
### Common Gotchas
|
|
67
|
+
- Dead marks can still block registration if famous
|
|
68
|
+
- A search showing "available" doesn't mean no conflicts exist
|
|
69
|
+
- Common words like "ULTRA", "PREMIUM" are frequently refused
|
|
70
|
+
- Geographic terms are often descriptive and hard to register
|
|
71
|
+
|
|
72
|
+
### Classes to Check for Tech/SaaS
|
|
73
|
+
Always search in classes **009, 035, 042** for software/tech products.
|
|
74
|
+
|
|
75
|
+
### Classes to Check for Consumer Brands
|
|
76
|
+
- Apparel: 025
|
|
77
|
+
- Food/Beverages: 030, 032, 033, 043
|
|
78
|
+
- Health: 044
|
|
79
|
+
- Entertainment: 041
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Web Scraping Fallback for tmsearch.uspto.gov
|
|
2
|
+
|
|
3
|
+
Use this when the direct backend API calls return errors or unexpected responses.
|
|
4
|
+
|
|
5
|
+
## Background
|
|
6
|
+
|
|
7
|
+
The tmsearch.uspto.gov frontend is a React SPA. The backend API it uses may change endpoint paths.
|
|
8
|
+
If the documented endpoints in SKILL.md fail, use browser DevTools (Network tab) on
|
|
9
|
+
https://tmsearch.uspto.gov/search/search-information to intercept the actual XHR/fetch requests
|
|
10
|
+
being made, then replicate those in code.
|
|
11
|
+
|
|
12
|
+
## Python Requests Approach
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
import requests
|
|
16
|
+
import time
|
|
17
|
+
|
|
18
|
+
HEADERS = {
|
|
19
|
+
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
|
|
20
|
+
"Accept": "application/json, text/plain, */*",
|
|
21
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
22
|
+
"Referer": "https://tmsearch.uspto.gov/search/search-information",
|
|
23
|
+
"Origin": "https://tmsearch.uspto.gov",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def search_trademark_web(keyword: str, status: str = "A", rows: int = 25) -> dict:
|
|
27
|
+
"""
|
|
28
|
+
Search USPTO trademark database.
|
|
29
|
+
status: "A" = active, "D" = dead, "" = all
|
|
30
|
+
"""
|
|
31
|
+
session = requests.Session()
|
|
32
|
+
|
|
33
|
+
# First GET the main page to get any session cookies
|
|
34
|
+
session.get("https://tmsearch.uspto.gov/search/search-information", headers=HEADERS)
|
|
35
|
+
|
|
36
|
+
# Attempt POST to backend
|
|
37
|
+
payload = {
|
|
38
|
+
"keyword": keyword.upper(),
|
|
39
|
+
"searchType": "1",
|
|
40
|
+
"statusType": status,
|
|
41
|
+
"pluralVariants": False,
|
|
42
|
+
"start": 0,
|
|
43
|
+
"rows": rows
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
response = session.post(
|
|
47
|
+
"https://tmsearch.uspto.gov/search/keyword",
|
|
48
|
+
json=payload,
|
|
49
|
+
headers=HEADERS,
|
|
50
|
+
timeout=30
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
if response.status_code == 200:
|
|
54
|
+
return response.json()
|
|
55
|
+
|
|
56
|
+
# If POST fails, try GET
|
|
57
|
+
params = {
|
|
58
|
+
"keyword": keyword.upper(),
|
|
59
|
+
"statusType": status,
|
|
60
|
+
"rows": rows,
|
|
61
|
+
"start": 0
|
|
62
|
+
}
|
|
63
|
+
response = session.get(
|
|
64
|
+
"https://tmsearch.uspto.gov/search/keyword",
|
|
65
|
+
params=params,
|
|
66
|
+
headers=HEADERS,
|
|
67
|
+
timeout=30
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
return response.json()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Selenium/Playwright Approach (Last Resort)
|
|
74
|
+
|
|
75
|
+
If all HTTP approaches fail, use a headless browser to drive the UI directly:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from playwright.sync_api import sync_playwright
|
|
79
|
+
import json
|
|
80
|
+
|
|
81
|
+
def search_with_playwright(keyword: str) -> list:
|
|
82
|
+
with sync_playwright() as p:
|
|
83
|
+
browser = p.chromium.launch(headless=True)
|
|
84
|
+
page = browser.new_page()
|
|
85
|
+
results = []
|
|
86
|
+
|
|
87
|
+
# Intercept API responses
|
|
88
|
+
def handle_response(response):
|
|
89
|
+
if "search" in response.url and response.status == 200:
|
|
90
|
+
try:
|
|
91
|
+
data = response.json()
|
|
92
|
+
if "trademarks" in data:
|
|
93
|
+
results.extend(data["trademarks"])
|
|
94
|
+
except:
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
page.on("response", handle_response)
|
|
98
|
+
page.goto("https://tmsearch.uspto.gov/search/search-information")
|
|
99
|
+
|
|
100
|
+
# Fill in search form
|
|
101
|
+
page.fill('input[placeholder*="search"]', keyword)
|
|
102
|
+
page.click('button[type="submit"]')
|
|
103
|
+
page.wait_for_load_state("networkidle")
|
|
104
|
+
|
|
105
|
+
browser.close()
|
|
106
|
+
return results
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Install Playwright
|
|
110
|
+
```bash
|
|
111
|
+
pip install playwright
|
|
112
|
+
playwright install chromium
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Alternative: Use RapidAPI Wrapper
|
|
116
|
+
|
|
117
|
+
If USPTO direct access is problematic, the RapidAPI unofficial wrapper is reliable:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# Endpoint: https://uspto-trademark.p.rapidapi.com
|
|
121
|
+
# Requires: RapidAPI key (freemium plan available)
|
|
122
|
+
|
|
123
|
+
curl --request GET \
|
|
124
|
+
--url "https://uspto-trademark.p.rapidapi.com/v1/trademarkSearch/{KEYWORD}/active" \
|
|
125
|
+
--header "x-rapidapi-host: uspto-trademark.p.rapidapi.com" \
|
|
126
|
+
--header "x-rapidapi-key: YOUR_RAPIDAPI_KEY"
|
|
127
|
+
|
|
128
|
+
# Availability check
|
|
129
|
+
curl --request GET \
|
|
130
|
+
--url "https://uspto-trademark.p.rapidapi.com/v1/trademarkAvailable/{KEYWORD}" \
|
|
131
|
+
--header "x-rapidapi-host: uspto-trademark.p.rapidapi.com" \
|
|
132
|
+
--header "x-rapidapi-key: YOUR_RAPIDAPI_KEY"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
RapidAPI wrapper endpoints:
|
|
136
|
+
- `/v1/trademarkSearch/{keyword}/{status}` — keyword search
|
|
137
|
+
- `/v1/trademarkAvailable/{keyword}` — simple yes/no availability
|
|
138
|
+
- `/v1/ownerSearch/{owner_name}/{postcode}` — search by owner
|
|
139
|
+
- `/v1/serialSearch/{serial_number}` — lookup by serial number
|
|
140
|
+
- `/v1/batchTrademarkSearch` — multiple keywords (POST)
|