AI vendors and your data

146 vendors · 427 answers

For AI agents

Vendor data terms as data: 427 answers for 146 vendors so far, each quoting its clause, and every change to 289 watched pages. Checked weekly; new vendors and pages are added as they are found.

Point your agent here

https://terms.fru.dev/llms.txt
https://terms.fru.dev/llms-full.txt

Call the API

MethodPathParamsReturns
GET/api/vendorsnoneEvery vendor with its answers: stance, short answer, quoted clause, page URL, check state
GET/api/vendors/{slug}slugOne vendor: answers, watched pages, page changes, answer changes
GET/api/answerstopic (train_business, train_consumer, retention, opt_out, zdr, subprocessors, residency), vendor, stance (no, limited, yes)Answers across vendors for one question
GET/api/changessince (YYYY-MM-DD), vendor, limit (max 200), offsetPage changes (counts, first changed paragraph) and answer changes, newest first
GET/api/changes/{id}idOne page change with its added and removed paragraphs
GET/api/documentsvendorWatched pages: URL, kind, text hash, last checked, last changed
GET/api/companiessince (YYYY-MM-DD or datetime)Vendors keyed by companies.fru.dev slug, with dated page changes
GET/api/searchq, limit (max 20)Ranked vendors, questions and pages

/api/vendors

curl -s "https://terms.fru.dev/api/vendors"
{
 "count": 146,
 "vendors": [
  {
   "slug": "openai",
   "name": "OpenAI",
   "domain": "openai.com",
   "products": "Model APIs, ChatGPT",
   "answered": 7,
   "documents": 5,
   "lastChange": "2026-11-02",
   "answers": [
    {
     "vendor": "openai",
     "topic": "train_business",
     "stance": "no",
     "answer": "No, unless you opt in",
     "quote": "By default, we don't use inputs or outputs from ChatGPT Business, ChatGPT Enterprise, ChatGPT Edu, or our API to improve our models.",
     "doc": "openai-training-help",
     "sourceUrl": "https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance",
     "capturedAt": "2026-09-24",
     "checkState": "ok",
     "verifiedAt": "2026-10-26"
    }
   ]
  }
 ]
}

/api/vendors/{slug}

curl -s "https://terms.fru.dev/api/vendors/openai"
{
 "vendor": {
  "slug": "openai",
  "name": "OpenAI",
  "domain": "openai.com",
  "products": "Model APIs, ChatGPT",
  "answered": 7,
  "documents": 5,
  "lastChange": "2026-11-02"
 },
 "answers": [
  {
   "vendor": "openai",
   "topic": "train_business",
   "stance": "no",
   "answer": "No, unless you opt in",
   "quote": "By default, we don't use inputs or outputs from ChatGPT Business, ChatGPT Enterprise, ChatGPT Edu, or our API to improve our models.",
   "doc": "openai-training-help",
   "sourceUrl": "https://help.openai.com/en/articles/5722486-how-your-data-is-used-to-improve-model-performance",
   "capturedAt": "2026-09-24",
   "checkState": "ok",
   "verifiedAt": "2026-10-26"
  }
 ],
 "documents": [
  {
   "id": "openai-api-data",
   "vendor": "openai",
   "kind": "docs",
   "title": "Data controls in the OpenAI platform",
   "url": "https://platform.openai.com/docs/guides/your-
...

/api/answers

curl -s "https://terms.fru.dev/api/answers?topic=train_business"
{
 "count": 97,
 "answers": [
  {
   "vendor": "airbyte",
   "topic": "train_business",
   "stance": "no",
   "answer": "No, never trains",
   "quote": "Airbyte does not collect or use customer data to develop, improve, or train generalized artificial intelligence and/or machine learning models",
   "doc": "airbyte-privacy",
   "sourceUrl": "https://airbyte.com/company/privacy-policy",
   "capturedAt": "2026-09-25",
   "checkState": "ok",
   "verifiedAt": "2026-10-26"
  }
 ]
}

/api/changes

curl -s "https://terms.fru.dev/api/changes?since=2026-01-01"
{
 "count": 345,
 "changes": [
  {
   "id": 402,
   "doc": "sazabi-dpa",
   "vendor": "sazabi",
   "date": "2026-11-09",
   "oldHash": "a6e2fbbc28271245",
   "newHash": "c33754948b9d5b46",
   "added": 1,
   "removed": 0,
   "excerpt": "(b) Company configures its AI model Subprocessors so that they do not retain Customer Data after processing a request.",
   "source": "live",
   "sourceUrl": "https://www.sazabi.com/legal/website/data-processing-addendum",
   "archiveUrl": "",
   "affected": [
    "retention",
    "subprocessors"
   ]
  }
 ]
}

/api/changes/{id}

curl -s "https://terms.fru.dev/api/changes/1"
{
 "change": {
  "id": 402,
  "doc": "sazabi-dpa",
  "vendor": "sazabi",
  "date": "2026-11-09",
  "oldHash": "a6e2fbbc28271245",
  "newHash": "c33754948b9d5b46",
  "added": 1,
  "removed": 0,
  "excerpt": "(b) Company configures its AI model Subprocessors so that they do not retain Customer Data after processing a request.",
  "source": "live",
  "sourceUrl": "https://www.sazabi.com/legal/website/data-processing-addendum",
  "archiveUrl": "",
  "affected": [
   "retention",
   "subprocessors"
  ]
 },
 "lines": [
  {
   "op": "add",
   "text": "..."
  }
 ]
}

/api/documents

curl -s "https://terms.fru.dev/api/documents?vendor=anthropic"
{
 "count": 289,
 "documents": [
  {
   "id": "ai2-privacy",
   "vendor": "ai2",
   "kind": "privacy",
   "title": "Ai2 Privacy Policy",
   "url": "https://allenai.org/privacy-policy",
   "via": "live",
   "hash": "9b7f8ba784b3cd8d",
   "chars": 46273,
   "checkedAt": "2026-11-09 06:40:45",
   "changedAt": "",
   "state": "ok",
   "note": "",
   "changes": 0,
   "firstSeen": "2026-09-25",
   "quoted": 1
  }
 ]
}

/api/companies

curl -s "https://terms.fru.dev/api/companies?since=2026-09-01"
{
 "companies": [
  {
   "slug": "openai",
   "name": "OpenAI",
   "domain": "openai.com",
   "site": "terms",
   "url": "https://terms.fru.dev/vendors/openai",
   "items": [
    {
     "type": "terms:page-change",
     "date": "2026-06-02",
     "title": "...",
     "url": "..."
    }
   ]
  }
 ]
}

/api/search

curl -s "https://terms.fru.dev/api/search?q=retention"
{
 "q": "retention",
 "results": [
  {
   "id": "page:/questions/retention",
   "group": "pages",
   "title": "How long are API inputs kept?",
   "href": "/questions/retention"
  }
 ]
}

OpenAPI 3.1: /openapi.json. Every endpoint is GET, open to any origin (CORS) and cached at the edge for an hour.

Add to your agent

System prompt line

When asked whether an AI or data vendor trains on customer data, how long it keeps inputs, or how to opt out, look it up at https://terms.fru.dev/api/answers?vendor=<slug>&topic=<topic> and quote the clause with its page URL. Say it is not legal advice. Fetch https://terms.fru.dev/llms.txt for the vendor list.

Tool definition

{
  "name": "fru_terms_lookup",
  "description": "What an AI or data vendor says about your data: whether it trains on API or consumer data, retention, how to opt out, zero data retention, subprocessors and data residency. Each answer quotes the clause word for word with the page URL, checked weekly. Source: Terms (terms.fru.dev). Not legal advice.",
  "input_schema": {
    "type": "object",
    "properties": {
      "vendor": {
        "type": "string",
        "description": "Vendor slug (companies.fru.dev), e.g. openai, anthropic, google, microsoft, aws, mistral-ai, cohere. List them with GET /api/vendors."
      },
      "topic": {
        "type": "string",
        "enum": [
          "train_business",
          "train_consumer",
          "retention",
          "opt_out",
          "zdr",
          "subprocessors",
          "residency"
        ],
        "description": "The question."
      }
    }
  },
  "endpoint": "GET https://terms.fru.dev/api/answers?vendor={vendor}&topic={topic}"
}

Python

import json, urllib.request

def answers(vendor: str) -> list[dict]:
    """What one vendor says about training, retention, opt-out and more, with the quoted clause."""
    url = f"https://terms.fru.dev/api/answers?vendor={vendor}"
    with urllib.request.urlopen(url, timeout=20) as r:
        return json.load(r)["answers"]

for a in answers("openai"):
    print(a["topic"], a["answer"], a["sourceUrl"])

TypeScript

type Answer = { vendor: string; topic: string; stance: 'no' | 'limited' | 'yes'; answer: string; quote: string; sourceUrl: string }

async function whoTrains(): Promise<Answer[]> {
  const res = await fetch(`https://terms.fru.dev/api/answers?topic=train_business`)
  if (!res.ok) throw new Error(`terms ${res.status}`)
  const { answers } = (await res.json()) as { answers: Answer[] }
  return answers.filter((a) => a.stance !== 'no')
}

Terms

  • Free to read. Please cite "Terms (terms.fru.dev)" and the vendor's page. Not legal advice.
  • Responses are cached for an hour; pages are checked weekly. Keep to about 60 requests a minute.
  • An answer with checkState "missing" quotes a clause that was not on its page at the last check; a person is re-reading it.
  • Clauses are verbatim; one that ends with an ellipsis is part of a longer sentence.