clause-radar
Every silent ToS edit your AI vendor hopes you didn't read.
clause-radar is a public, append-only audit log of every Terms of Service,
Privacy Policy, Acceptable Use Policy and Data Processing Addendum published
by the major AI providers. Every six hours we re-fetch each document,
normalize the rendered text, hash it, and — when anything substantive has
changed — store the new version and surface a word-level diff.
Live: https://holyai.me/clause-radar/
Why this exists
Silent ToS edits are now the default in AI. Vendors tweak data-use,
indemnification, IP-ownership, and arbitration clauses without notifying
users. Procurement teams, lawyers and journalists need a single timeline to
monitor that drift. ToS;DR's coverage of AI products is thin and lags;
Internet Archive snapshots but doesn't diff. clause-radar is the dashboard
that should exist.
What it does
- Snapshots every doc in the catalog every 6 hours (node-cron
0 /6). - Strips nav / footer / script and converts the body to plain text.
- Normalizes the text for hashing — wipes years, ISO timestamps, long
- hex/base64 blobs, and rotating "Last updated" date values — so we never
- false-diff on a copyright footer flip.
- SHA-256 hashes the normalized text. If it matches the last snapshot, just
- update
last_checked. If it differs, store a newversionsrow and - compute a word-level diff (using jsdiff) against the previous version.
- Exposes a clean SPA with three tabs: Recent changes (newest diffs,
- grouped by ISO week), Catalog (all 30 docs with status + last-changed),
- and Document viewer (latest text on the left, version history on the
- right, side-by-side diff between any two versions).
What it does NOT do
- No authentication. Every endpoint is public — including
POST /api/refresh. - No mock data. If a vendor's page is unreachable for 3 consecutive cycles
- the policy is marked
brokenand surfaced as such. We do not invent - content.
- No LLM "summaries" of clauses in the MVP. The raw diff is the truth.
- No email / Slack notifications yet. RSS feed comes next.
- No headless browser. If a page returns no legal text on a bare
fetch, - we mark it
unsupportedand surface it.
Data sources (real public URLs, fetched every 6h)
| Vendor | Document | URL |
|--------------|---------------------------|-----|
| OpenAI | Terms of Use | https://openai.com/policies/row-terms-of-use/ |
| OpenAI | Service Terms | https://openai.com/policies/service-terms/ |
| OpenAI | Privacy Policy | https://openai.com/policies/row-privacy-policy/ |
| OpenAI | Usage Policies | https://openai.com/policies/usage-policies/ |
| OpenAI | DPA | https://openai.com/policies/data-processing-addendum/ |
| Anthropic | Consumer Terms | https://www.anthropic.com/legal/consumer-terms |
| Anthropic | Commercial Terms | https://www.anthropic.com/legal/commercial-terms |
| Anthropic | Usage Policy | https://www.anthropic.com/legal/aup |
| Anthropic | Privacy Policy | https://www.anthropic.com/legal/privacy |
| Google | Generative AI Terms | https://policies.google.com/terms/generative-ai |
| Google | Privacy Policy | https://policies.google.com/privacy |
| Microsoft | Services Agreement | https://www.microsoft.com/en-us/servicesagreement |
| Microsoft | Privacy Statement | https://privacy.microsoft.com/en-us/privacystatement |
| Cursor | Terms of Service | https://cursor.com/terms-of-service |
| Cursor | Privacy Policy | https://cursor.com/privacy |
| GitHub | Additional Product Terms | https://docs.github.com/en/site-policy/github-terms/github-terms-for-additional-products-and-features |
| GitHub | Privacy Statement | https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement |
| Replit | Terms of Service | https://replit.com/site/terms |
| Replit | Privacy Policy | https://replit.com/site/privacy |
| Lovable | Terms | https://lovable.dev/terms |
| Lovable | Privacy Policy | https://lovable.dev/privacy |
| Mistral | Terms of Service | https://mistral.ai/terms |
| Mistral | Privacy Policy | https://mistral.ai/terms#privacy-policy |
| xAI | Terms of Service | https://x.ai/legal/terms-of-service |
| xAI | Privacy Policy | https://x.ai/legal/privacy-policy |
| Perplexity | Terms of Service | https://www.perplexity.ai/hub/legal/terms-of-service |
| Perplexity | Privacy Policy | https://www.perplexity.ai/hub/legal/privacy-policy |
| Hugging Face | Terms of Service | https://huggingface.co/terms-of-service |
| Hugging Face | Privacy Policy | https://huggingface.co/privacy |
| OpenRouter | Terms of Service | https://openrouter.ai/terms |
Fetch frequency: every 6 hours, plus a startup backfill if the last full
refresh was more than 6h ago. Manual triggers are available viaPOST /clause-radar/api/refresh or POST /clause-radar/api/refresh/:slug.
API
All endpoints are public, no auth required.
GET /clause-radar/health
GET /clause-radar/api/policies
GET /clause-radar/api/policies/:slug
GET /clause-radar/api/policies/:slug/versions
GET /clause-radar/api/policies/:slug/versions/:id
GET /clause-radar/api/diffs[?vendor=&limit=]
GET /clause-radar/api/diffs/:id
GET /clause-radar/api/stats
POST /clause-radar/api/refresh
POST /clause-radar/api/refresh/:slug
Local dev
npm install
node server.js
# open http://localhost:4796/clause-radar/
To serve at root for testing without nginx in front:
BASE_PATH= node server.js
The first run kicks off a startup backfill — the dashboard goes from empty
to populated within a few minutes.
License
MIT.