---
title: "List every sale and every share · Agent Wranglers"
url: https://agentwranglers.se/playbook/compliance/us-state-privacy-laws/sales-and-sharing-inventory
updated: 2026-10-20
licence: "All rights reserved"
---

# List every sale and every share

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [US state privacy laws](https://agentwranglers.se/playbook/compliance/us-state-privacy-laws)
- Rule: List every flow of personal data to another company that could count as a sale or targeted advertising. Offer an opt-out that stops each one.
- How: US laws often treat any transfer for something of value as a sale. Ad pixels, ad SDKs and data partnerships usually count, even without money changing hands. California calls ads based on activity across sites sharing. Give each flow an entry with its host and its legal label. Offer a clear opt-out link, and treat a browser privacy signal as an opt-out, as the [privacy signal rule](https://agentwranglers.se/playbook/website/privacy/global-privacy-control) describes.
- Check: A browser test loads the main pages and lists every third-party host. It fails on a host without an inventory entry. With the `Sec-GPC: 1` header, no host labelled sale or sharing is called. The same holds without the header after a click on the opt-out link.

Example:

```js
import { readFileSync } from 'node:fs';
import { chromium } from 'playwright';

const inventory = JSON.parse(readFileSync('compliance/third-parties.json', 'utf8'));

const browser = await chromium.launch();
const page = await browser.newPage({ extraHTTPHeaders: { 'Sec-GPC': '1' } });
const thirdPartyHosts = new Set();
page.on('request', request => {
  const host = new URL(request.url()).hostname;
  if (host !== 'example.com' && !host.endsWith('.example.com')) thirdPartyHosts.add(host);
});
await page.goto('https://www.example.com/');
const blockedLabels = ['sale', 'sharing'];
const leaks = [...thirdPartyHosts].filter(host => blockedLabels.includes(inventory[host]?.label) || !inventory[host]);
await browser.close();
if (leaks.length) throw new Error(`Hosts called despite opt-out or missing from inventory: ${leaks.join(', ')}`);
```

```python
import json
from urllib.parse import urlparse
from playwright.sync_api import sync_playwright

inventory = json.load(open("compliance/third-parties.json"))

BLOCKED_LABELS = {"sale", "sharing"}
with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(extra_http_headers={"Sec-GPC": "1"})
    hosts = set()
    page.on("request", lambda request: hosts.add(urlparse(request.url).hostname))
    page.goto("https://www.example.com/")
    browser.close()
third_party = {h for h in hosts if h != "example.com" and not h.endswith(".example.com")}
leaks = [h for h in third_party if h not in inventory or inventory[h]["label"] in BLOCKED_LABELS]
if leaks:
    raise SystemExit(f"Hosts called despite opt-out or missing from inventory: {', '.join(leaks)}")
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers compliance playbook: https://agentwranglers.se/playbook/compliance/us-state-privacy-laws/sales-and-sharing-inventory`.

- Previous: [Compute which state laws apply](https://agentwranglers.se/playbook/compliance/us-state-privacy-laws/us-state-scope)
- Next: [Ask before using sensitive data](https://agentwranglers.se/playbook/compliance/us-state-privacy-laws/us-sensitive-data-consent)
- [US state privacy laws](https://agentwranglers.se/playbook/compliance/us-state-privacy-laws)
