> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pinakelai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Portfolio watch

> Track every mark filed by a client, a competitor or your own firm, and spot new filings.

A portfolio watch answers two questions about a company or a firm: which marks does it hold, and what has it filed since the last check? The answer is a set of record ids that you compare from one run to the next.

## 1. Find the company's name keys

Companies appear under several spellings, legal forms and scripts. Start with a phrase search in the registers you care about, and collect the `name_key` values of the owners that are the company:

```bash theme={null}
curl -G "https://api.pinakelai.com/v1/trademarks" \
  -H "Authorization: Bearer $PINAKEL_API_KEY" \
  --data-urlencode "owner_name_phrase=galenic" \
  --data-urlencode "jurisdiction=AD,AL,EM,FR" \
  --data-urlencode "limit=100"
```

Summaries carry the primary owner's name. Retrieve a few full records (or [batch](https://docs.pinakelai.com/api-reference/trademarks/batch.md) them) to read each owner's `name_key`. Keep a reviewed list of keys per company, such as:

```json theme={null}
{
  "company": "Galenic",
  "owner_keys": ["GALENIC COSMETICS LABORATORY"]
}
```

Name keys group spellings of one name, not different names: a subsidiary, a former name or a name in another script each needs its own key. See [Parties and name keys](https://docs.pinakelai.com/concepts/parties.md).

## 2. List the portfolio

Choose the filter by how complete the list must be:

| Goal | Filter |
| - | - |
| A fast overview across every register | `primary_owner_key` (first owner only), no `jurisdiction` needed |
| A complete list in the registers that matter | `owner_key`, which covers every current owner, holder and applicant, with up to 5 `jurisdiction` codes per request |

```python Python theme={null}
def portfolio(owner_keys: list[str], jurisdictions: list[str]) -> dict[str, dict]:
    """Every record in `jurisdictions` with a current owner in `owner_keys`, by id."""
    found: dict[str, dict] = {}
    for i in range(0, len(jurisdictions), 5):          # owner_key: at most 5 registers
        params = {"owner_key": owner_keys, "jurisdiction": ",".join(jurisdictions[i:i + 5]),
                  "limit": 100}
        while True:
            resp = session.get(f"{API}/trademarks", params=params, timeout=60)
            resp.raise_for_status()
            page = resp.json()
            found.update({tm["id"]: tm for tm in page["data"]})
            if not page["has_more"]:
                break
            params["cursor"] = page["next_cursor"]
    return found
```

`requests` sends a list value as a repeated parameter, so several keys are combined with OR.

## 3. Detect new filings

Store the set of ids from each run. On the next run, new ids are new filings or newly published records; ids that disappeared were transferred away, or removed by the office.

```python Python theme={null}
previous = load_ids("galenic")                 # your storage
current = portfolio(["GALENIC COSMETICS LABORATORY"], ["AD", "AL", "EM", "FR"])
new_ids = current.keys() - previous
gone_ids = previous - current.keys()
save_ids("galenic", set(current))
```

Why not filter on `application_date_from` since the last run? Offices publish filings late, some weeks or months after the filing date, so a record that appears today can carry an application date well before your last run. Comparing id sets catches it; a date filter would not.

## 4. Watch changes to the marks you found

To follow status and deadline changes in the portfolio, treat its ids like a docket: poll them in batches, or follow the changes feed for the registers involved. See [Docketing sync](https://docs.pinakelai.com/use-cases/docketing-sync.md).

## Watching a law firm

The same steps work for representatives, which helps a firm check that its own portfolio is recorded correctly at each office. Use `representative_name_phrase` to find the firm's keys and `representative_key` (with up to 5 `jurisdiction` codes) to list its marks. Some offices record the attorney as the correspondent, which the representative filters include, and self-filed marks may list the owner itself as correspondent.

## Cost

A run costs one call per page of up to 100 records, for each group of up to 5 registers. Watching a 2,000-mark portfolio in 10 registers daily costs about 22 calls a day (2,000 ÷ 100 full pages, plus a partial last page per group), plus batch retrieves for the records you need in full.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.