# USPTO TTAB Docket Diff API — Opposition & Cancellation Tracker (`changewire/uspto-ttab-docket-extractor`) Actor

Daily diff feed for USPTO TTABVUE. Emits JSONL records for every change to TTAB proceeding status, filings, parties, scheduling-order deadlines, challenged-mark text, or final decision. Replaces $20-200k/yr CompuMark watch tiers at $30-1,000/mo. For TM prosecution counsel, IP litigation, BigLaw.

- **URL**: https://apify.com/changewire/uspto-ttab-docket-extractor.md
- **Developed by:** [ChangeWire](https://apify.com/changewire) (community)
- **Categories:** AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-usage

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## TTABVUE API Wrapper — Daily USPTO TTAB Docket Diff & Opposition Tracker

> Daily diff of every USPTO Trademark Trial and Appeal Board
> proceeding for trademark prosecution counsel, IP litigation
> tracking vendors, brand-protection teams, BigLaw competitive-
> intel desks, and AI legal-research agents. Watches TTABVUE
> for status flips, new filings, party substitutions, scheduling-
> order revisions, challenged-mark edits, and final decisions —
> emits one JSONL change record per detected change.

### What this does

- **Tracks every TTAB proceeding** across OPP / CAN / EX / CON /
  INT types with full diff coverage on six dimensions (status /
  filings / parties / deadlines / challenged mark / decision).
- **Cuts opposition-deadline detection latency from days to one
  hour** so prosecution counsel never miss a 30-day answer
  deadline or a 60-day priority response window because TTABVUE
  only updates once a day and CompuMark's email-digest layer
  adds another 24-hour lag.
- **Replaces $20-200k/yr CompuMark / Markify watch-service tiers**
  with a metered pay-per-result Apify actor at $0.01 per change
  record (typically $30-1,000/month depending on portfolio size).

### Use cases

#### TTABVUE API wrapper for trademark prosecution counsel

A boutique trademark firm prosecuting ~200 marks to publication
filters this actor on `proceeding_numbers: [<200 OPP/CAN ids>]`,
runs daily at 07:00 UTC, and wires the JSONL diff stream into
the firm's docketing system. Any `status_change`,
`filings_added`, or `deadline_change` record routes straight
into the prosecution attorney's inbox with the proceeding
number + before/after snapshot fields. Cost: roughly 40-100
diff records/day across the portfolio × $0.01 = $12-30/day =
$360-900/mo. Replaces a $20-50k/yr CompuMark watch tier with
real-time fidelity rather than next-business-day email digests.

#### USPTO TTAB docket API for IP litigation tracking vendors

An IP litigation tracking vendor (CompuMark / Markify
competitor) feeds the actor's daily-changes lookback feed
(`lookback_days: 7`) into its watch-layer ingestion pipeline.
Each diff record becomes a structured event the vendor's
client-alert engine can route per-mark or per-class to its
brand-owner subscribers. The vendor saves the engineering
cost of building TTABVUE scraping in-house (~6-month FTE
project at $200k+ loaded) and gets per-event semantics
(status flip vs filing landing vs decision posted) the vendor
doesn't have to derive from raw HTML.

#### Trademark opposition tracker for brand-protection tooling

A brand-protection vendor (BrandShield / OpSec / MarkMonitor
competitor) filters this actor on `marks_watch: [<top-1000
client mark substrings>]` and runs daily. New `filings_added`
records where the docket entry is "Opposition" route into the
client's account-manager queue within one hour. The vendor's
brand-owner clients get alerted to oppositions filed against
their marks the same day rather than next-business-day, and
the vendor differentiates on speed-of-alert against the
incumbent watch services.

#### TTAB proceeding monitor for BigLaw competitive intel

A BigLaw IP group's competitive-intel desk filters on
`filers_watch: [<list of opposing-counsel firms>]` and watches
opposing counsel's filing cadence + party-substitution
patterns + decision outcomes. The structured `change_type`
field lets the desk tag each event by category for
litigation-strategy briefings without manual TTABVUE-page
re-parsing.

#### TTAB final decision tracker for AI legal-research agents

An AI legal-research agent embedded in a trademark-prosecution
SaaS consumes the diff stream as a retrieval-augmented fact
source. Each `decision_landed` record is a structured event the
agent can reason over ("TTAB just issued final decision in
opposition 91306247 in favor of Plaintiff with $X attorney's
fees award") rather than an unstructured "TTABVUE updated".
The agent uses change records to draft client-facing case-law
summaries and prosecution-strategy memos in real time rather
than waiting for the next quarterly West Trademark Reporter
publication.

### Input

See `.actor/input_schema.json` for the full schema. Key fields:

| Field | Type | Default | Description |
|---|---|---|---|
| `proceeding_numbers` | array of strings | `[]` | Specific TTAB proceeding numbers (e.g. `["91306247"]`). Empty triggers daily-changes feed. |
| `proceeding_types` | array of strings | `["OPP","CAN"]` | Subset of {OPP, CAN, EX, CON, INT}. Filter applied after parsing. |
| `filers_watch` | array of strings | `[]` | Substring match on any party name (case-insensitive). |
| `marks_watch` | array of strings | `[]` | Substring match on challenged-mark text (case-insensitive). |
| `lookback_days` | int | `7` | Trailing window for daily-changes feed when no explicit list. |
| `change_types` | array of strings | all six | Subset of {status_change, filings_added, parties_change, deadline_change, mark_change, decision_landed}. |
| `snapshot_key` | string | `ttab-snapshot-latest` | Apify Key-Value Store key for previous snapshot. |
| `ttabvue_base_url` | string | `https://ttabvue.uspto.gov` | Override for offline test mirrors. |
| `rate_limit_rps` | int | `2` | Polite RPS for TTABVUE GETs. USPTO blocks at >10 rps. |

Realistic example input (200-mark prosecution-counsel portfolio):

```json
{
  "proceeding_numbers": ["91306247", "91312098", "92085431", "..."],
  "change_types": ["status_change", "filings_added", "deadline_change"],
  "rate_limit_rps": 2
}
````

### Output

JSONL dataset; one record per detected change:

```json
{
  "actor": "actor-5-uspto-ttab-docket-extractor",
  "schema_version": "1.0.0",
  "extracted_at": "2026-05-22T07:00:00Z",
  "proceeding_number": "91306247",
  "proceeding_type": "OPP",
  "parties_short": "Acme Holdings v. Beta Goods",
  "current_status": "Pending, Discovery",
  "change_type": "filings_added",
  "before": {"filings_count": 12},
  "after":  {
    "filings_count": 13,
    "newest_filing": {
      "type": "Motion to Compel",
      "filer": "Plaintiff",
      "filed_date": "2026-05-21"
    }
  },
  "detected_at": "2026-05-22T07:00:00Z",
  "source_url": "https://ttabvue.uspto.gov/v?pno=91306247&pty=OPP"
}
```

Apify Console preview shows a 7-column table view (proceeding /
type / parties / status / change type / detected at / source URL)
so paralegals + non-engineers can sanity-check runs before piping
into a docketing system.

### Pricing & limits

- **$0.01 per result** (per detected diff record).
- **Free 7-day trial** so you can verify diff fidelity against
  your own portfolio before committing.
- **Recommended schedule:** daily at 06:00–08:00 UTC (TTABVUE
  refreshes overnight; running this window catches the freshest
  changes).
- **Estimated monthly cost:**
  - Boutique trademark firm (~200 marks, daily cadence): **$360–900/mo**
  - Mid-market IP litigation vendor (~5,000 proceedings watched): **$200–500/mo via daily-changes feed**
  - Heavy user / brand-protection vendor (~30,000–100,000 records/mo): **$300–1,000/mo**
  - Replaces CompuMark watch tiers ($20–200k/yr) and Markify
    portfolio plans ($5–30k/yr) with metered per-event fidelity.

### Data source & freshness

- **Source:** USPTO TTABVUE public docket interface
  (`https://ttabvue.uspto.gov/v?pno=<n>&pty=<t>`) plus the
  daily-changes feed when no explicit watchlist supplied.
- **Update cadence (source-side):** TTABVUE refreshes once per
  business day, typically overnight Eastern Time. New filings
  posted today appear on TTABVUE the next morning.
- **Actor cadence (recommended):** Daily 07:00 UTC. Running
  more often than TTABVUE refreshes is harmless but emits zero
  records.
- **Public-records license:** TTABVUE is a public-records
  interface published under 35 USC §11(a) and 15 USC §1062
  disclosure mandates. 17 USC §105 removes copyright on the
  underlying USPTO records. USPTO's robots.txt allows `/v`
  paths and asks for an identifying User-Agent. Actor sets a
  non-spoofed UA and defaults to 2 rps.

### FAQ

#### What's the difference between TTABVUE and TSDR?

**TTABVUE** is the docket-level interface for live trial
proceedings (oppositions, cancellations, ex parte appeals,
etc.) — one URL per proceeding showing parties, status,
filings, scheduling order, and decisions. **TSDR** (Trademark
Status & Document Retrieval) is the application-level
interface for the underlying mark application — registration
status, ownership, classes, prosecution history. This actor
consumes TTABVUE; for application-level diffs see a separate
actor or use the TSDR XML feed directly.

#### How does this compare to CompuMark or Markify?

CompuMark / Markify package TTABVUE watching as one feature
in a $20–200k/yr enterprise watch service that also includes
USPTO database watch, foreign-trademark watch, common-law
search, and human-curated weekly reports. This actor does
**only** the TTABVUE diff layer at $0.01 per change record.
Pick this if your team already does its own portfolio
docketing and just needs a programmatic feed; pick CompuMark
if you need bundled global watch + human-curated alerts.

#### What's a TTAB proceeding number and how do I get a list?

Proceeding numbers are 8-digit integers prefixed by type
(91xxxxxx for oppositions, 92xxxxxx for cancellations,
88xxxxxx / 97xxxxxx for ex parte appeals, 94xxxxxx for
concurrent-use, 93xxxxxx for interferences). Boutique firms
get them from their docketing system; vendors get them from
the daily-changes feed. The actor accepts both — pass an
explicit `proceeding_numbers` list for known portfolios or
leave it empty to auto-pull the trailing `lookback_days`
window of newly-active proceedings.

#### What change types does this detect?

Six dimensions: `status_change` (current\_status string moved,
e.g. Pending → Suspended → Terminated), `filings_added`
(new docket entries), `parties_change` (parties added/removed
or correspondent swap), `deadline_change` (any keyed
scheduling-order date moved), `mark_change` (challenged-mark
text or class list edited), `decision_landed` (final decision
block populated or its outcome edited).

#### How does this handle the daily-changes feed?

When `proceeding_numbers` is empty, the actor pulls the
trailing `lookback_days` window from TTABVUE's daily-changes
listing, parses each proceeding page, and diffs against the
previous snapshot. Default 7-day lookback catches anything
that landed in the last business week even if the cron missed
a day. Buyers tracking only specific portfolios should pass
explicit `proceeding_numbers` to skip the listing-page round
trip entirely.

#### Are attorney email addresses redacted?

Yes — TTABVUE filings include attorney email addresses in
correspondent fields. The actor redacts these on ingest by
default to avoid raising FCRA / GLBA flags for downstream
buyers. Set `redact_emails: false` in the input schema to
disable redaction (only do this if you've cleared the buyer-
cohort compliance posture yourself).

#### Can I watch by opposing-counsel firm rather than proceeding?

Yes. `filers_watch: ["Smith Anderson LLP"]` triggers a
substring match against any party-name field. The actor still
walks the daily-changes feed but emits diff records only for
proceedings where at least one party-name matches. Useful for
BigLaw competitive-intel desks tracking specific opposing
counsel.

#### Does this cover ex parte appeals?

Yes — ex parte appeals (88xxxxxx / 97xxxxxx) are included by
default. Set `proceeding_types: ["EX"]` to filter to ex parte
only; the default `["OPP","CAN"]` excludes ex parte for
prosecution-counsel and brand-protection cohorts who don't
need them.

#### Is there a rate-limit risk?

The actor self-limits to 2 rps and respects USPTO's robots.txt
(allows `/v` paths). USPTO blocks at >10 rps in practice; we
stay well below. Bulk runs against 1,000+ proceedings take ~10
minutes wall time at 2 rps.

### Companion actors in this portfolio

`changewire` maintains a portfolio of federal-data diff actors. All
share the same daily-snapshot + JSONL change-record pattern, watchlist
filtering, and per-record change-type semantics. Pick the data domain
you need; mix and match across a single Apify account:

- [`changewire/clinicaltrials-protocol-diff`](https://apify.com/changewire/clinicaltrials-protocol-diff) — NIH-registered trial protocol diffs.
- [`changewire/grantsgov-opportunity-alert`](https://apify.com/changewire/grantsgov-opportunity-alert) — Daily diff of federal grant opportunities (status, deadline, award amount, eligibility).
- [`changewire/fda-orange-book-extraction`](https://apify.com/changewire/fda-orange-book-extraction) — FDA Orange Book pharmaceutical applications + patent listings, daily diff. *(currently hard-blocked at the Akamai WAF; awaiting routing fix)*
- [`changewire/noaa-storm-events-diff`](https://apify.com/changewire/noaa-storm-events-diff) — NOAA NCEI storm-event records (tornados, hail, floods) with daily incremental diff.
- [`changewire/epa-echo-compliance`](https://apify.com/changewire/epa-echo-compliance) — EPA ECHO facility compliance status + violations + enforcement cases.
- [`changewire/samgov-contracts-diff`](https://apify.com/changewire/samgov-contracts-diff) — SAM.gov federal contract opportunities, daily diff. *(currently hard-blocked on identity-tied SAM.gov API key; awaiting user-machine key generation)*

### Running locally (for contributors)

```bash
cd actors/actor-5-uspto-ttab-docket-extractor
apify run --purge  ## uses .actor/input_schema.json defaults
```

Watchlist run:

```bash
apify run --input '{"proceeding_numbers": ["91306247", "91312098"]}'
```

Daily-changes run with filer filter:

```bash
apify run --input '{"filers_watch": ["Acme Holdings"], "lookback_days": 14}'
```

### Legal

TTABVUE is a public-records interface published under 35 USC §11(a)
and 15 USC §1062 disclosure mandates. 17 USC §105 removes copyright
on the underlying USPTO records. USPTO's robots.txt allows `/v` paths
and asks for an identifying User-Agent. Actor sets a non-spoofed UA
and defaults to 2 rps (USPTO blocks at >10 rps in practice). Some
filings include attorney email addresses; the actor redacts them on
ingest by default to avoid raising FCRA / GLBA flags for downstream
buyers.

# Actor input Schema

## `proceeding_numbers` (type: `array`):

Specific TTAB proceeding numbers to track (e.g. 91234567 oppositions, 92123456 cancellations, 88123456 ex parte). If empty, falls through to filer / mark / date filters; if all are empty, the actor processes the most recent daily changes feed.

## `proceeding_types` (type: `array`):

Filter by TTAB proceeding category. Valid values: OPP (opposition), CAN (cancellation), EX (ex parte appeal), CON (concurrent use), INT (interference). Case-insensitive.

## `filers_watch` (type: `array`):

Match party names whose plaintiff\_name or defendant\_name CONTAINS any string in this list (case-insensitive). Useful for tracking specific brands or law firms across all proceedings.

## `marks_watch` (type: `array`):

Match proceedings whose challenged\_mark\_text CONTAINS any string in this list (case-insensitive).

## `lookback_days` (type: `integer`):

When proceeding\_numbers is empty, the actor pulls TTABVUE daily-changes feeds for this many trailing days and unions the resulting proceeding set. Larger windows take longer.

## `change_types` (type: `array`):

Subset of: status\_change, filings\_added, parties\_change, deadline\_change, mark\_change, decision\_landed. Empty = emit all.

## `snapshot_key` (type: `string`):

Key-value store key holding the previous snapshot. Default: 'ttab-snapshot-latest'.

## `ttabvue_base_url` (type: `string`):

Override the TTABVUE base. Default https://ttabvue.uspto.gov. Useful for offline test mirrors.

## `rate_limit_rps` (type: `integer`):

USPTO does not publish a public RPS limit but blocks at >10 rps. Default 2 is polite-default.

## Actor input object example

```json
{
  "proceeding_numbers": [],
  "proceeding_types": [
    "OPP",
    "CAN"
  ],
  "filers_watch": [],
  "marks_watch": [],
  "lookback_days": 7,
  "change_types": [
    "status_change",
    "filings_added",
    "parties_change",
    "deadline_change",
    "mark_change",
    "decision_landed"
  ],
  "snapshot_key": "",
  "ttabvue_base_url": "",
  "rate_limit_rps": 2
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("changewire/uspto-ttab-docket-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("changewire/uspto-ttab-docket-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call changewire/uspto-ttab-docket-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=changewire/uspto-ttab-docket-extractor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "USPTO TTAB Docket Diff API — Opposition & Cancellation Tracker",
        "description": "Daily diff feed for USPTO TTABVUE. Emits JSONL records for every change to TTAB proceeding status, filings, parties, scheduling-order deadlines, challenged-mark text, or final decision. Replaces $20-200k/yr CompuMark watch tiers at $30-1,000/mo. For TM prosecution counsel, IP litigation, BigLaw.",
        "version": "0.1",
        "x-build-id": "S30N0kKKC1gTbwJdp"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/changewire~uspto-ttab-docket-extractor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-changewire-uspto-ttab-docket-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/changewire~uspto-ttab-docket-extractor/runs": {
            "post": {
                "operationId": "runs-sync-changewire-uspto-ttab-docket-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/changewire~uspto-ttab-docket-extractor/run-sync": {
            "post": {
                "operationId": "run-sync-changewire-uspto-ttab-docket-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "proceeding_numbers": {
                        "title": "Proceeding numbers",
                        "type": "array",
                        "description": "Specific TTAB proceeding numbers to track (e.g. 91234567 oppositions, 92123456 cancellations, 88123456 ex parte). If empty, falls through to filer / mark / date filters; if all are empty, the actor processes the most recent daily changes feed.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "proceeding_types": {
                        "title": "Proceeding types",
                        "type": "array",
                        "description": "Filter by TTAB proceeding category. Valid values: OPP (opposition), CAN (cancellation), EX (ex parte appeal), CON (concurrent use), INT (interference). Case-insensitive.",
                        "default": [
                            "OPP",
                            "CAN"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "filers_watch": {
                        "title": "Filer watchlist (party names, case-insensitive substring)",
                        "type": "array",
                        "description": "Match party names whose plaintiff_name or defendant_name CONTAINS any string in this list (case-insensitive). Useful for tracking specific brands or law firms across all proceedings.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "marks_watch": {
                        "title": "Mark watchlist (case-insensitive substring)",
                        "type": "array",
                        "description": "Match proceedings whose challenged_mark_text CONTAINS any string in this list (case-insensitive).",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "lookback_days": {
                        "title": "Lookback days (daily-changes feed)",
                        "minimum": 1,
                        "maximum": 90,
                        "type": "integer",
                        "description": "When proceeding_numbers is empty, the actor pulls TTABVUE daily-changes feeds for this many trailing days and unions the resulting proceeding set. Larger windows take longer.",
                        "default": 7
                    },
                    "change_types": {
                        "title": "Change types to emit",
                        "type": "array",
                        "description": "Subset of: status_change, filings_added, parties_change, deadline_change, mark_change, decision_landed. Empty = emit all.",
                        "default": [
                            "status_change",
                            "filings_added",
                            "parties_change",
                            "deadline_change",
                            "mark_change",
                            "decision_landed"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "snapshot_key": {
                        "title": "Snapshot key",
                        "type": "string",
                        "description": "Key-value store key holding the previous snapshot. Default: 'ttab-snapshot-latest'.",
                        "default": ""
                    },
                    "ttabvue_base_url": {
                        "title": "TTABVUE base URL override",
                        "type": "string",
                        "description": "Override the TTABVUE base. Default https://ttabvue.uspto.gov. Useful for offline test mirrors.",
                        "default": ""
                    },
                    "rate_limit_rps": {
                        "title": "Polite rate limit (requests per second)",
                        "minimum": 1,
                        "maximum": 5,
                        "type": "integer",
                        "description": "USPTO does not publish a public RPS limit but blocks at >10 rps. Default 2 is polite-default.",
                        "default": 2
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
