portfolios:manage scope.
1. Preview the volume
Dry-run the query before going live. Scope to the US withfilters.jurisdictions: ["US"] (equivalently filters.offices: ["uspto"] —
jurisdictions are auto-translated to offices at create time):
trigger_events: ["trademark.created"] (new filings only — drops the
update/status churn) before creating. See
Preview Watch for the
estimate_basis / timeout semantics on heavier queries.
2. Create the watch
Watch object — save its id (wat_*). The watch is
active immediately and evaluates on every USPTO ingestion sync. Mutating
calls like this one require the Idempotency-Key
header.
When do alerts arrive? USPTO ingest runs daily at 01:01 UTC (with
05:01 / 13:01 UTC retry rails), so a new US filing typically alerts within
~24 hours of USPTO’s daily file publication. Webhook delivery itself takes
seconds after detection. See Known beta
limitations.
3. Register a webhook (push)
secret immediately — it is shown once. Each delivery is
an HMAC-signed POST whose data.trademark_id you can pass straight to
GET /v1/trademarks/{id}:
webhook-id header. No receiver yet? Use a tunnel or request-bin
pattern
to develop against real deliveries.
4. Add a polling fallback (pull)
Webhooks deliver in seconds but receivers go down. A daily reconciliation pass over the watch’s alerts catches anything you missed:POST /v1/alerts/lookup or process them
directly from the list response. Page with the pagination.cursor until
has_more is false.
For the full reconciliation pattern (and replay handling), see
Handling alerts.
Variations
-
US filings for a specific competitor:
watch_type: "owner"withfilters: { ownerId: "own_...", jurisdictions: ["US"] }. -
Confusingly-similar US filings:
watch_type: "similarity"withq: "yourmark",score_threshold: 0.85, andfilters: { jurisdictions: ["US"] }. -
More jurisdictions later:
PATCHthe watch with a full replacement query — one watch covers the set.PATCHreplaces the entirequeryobject and re-validates it (version, the type’s required filters,trigger_events), so resend every field, not just the one you’re changing: