# Fineprint > Fineprint is a terms-of-service parsing API for AI agents. Send a ToS URL (or pasted text) to `POST /v1/scans` and get back a structured `ScanReport`: quote-grounded risk clauses, a deterministic 0–100 risk score, and a `pass`/`flag`/`block` policy verdict your agent can act on without reading legalese. ## What Fineprint is **Fineprint is the contractual risk and policy enforcement layer for AI agents.** An API that turns any terms of service, privacy policy, EULA, or DPA into machine-readable risk data. Built for agents that accept terms, create accounts, or grant vendors data access on behalf of a principal (a user or company). Every claim in a report is backed by a quote verified against the source document — verbatim, or a ≥ 0.85 fuzzy match with the match type exposed on every clause. Scoring and verdicts are deterministic — no LLM in the math. ## The problem Agents click "I agree" thousands of times a day on behalf of principals who never read the terms. Buried clauses — binding arbitration, auto-renewal, vendor rights to train models on customer data, unilateral price changes — create liability the principal never consented to knowingly. Fineprint exists so an agent can check the terms *before* it commits its principal. ## How it works One call: ```http POST /v1/scans Content-Type: application/json {"url": "https://example.com/terms", "policy_id": "pol_abc123"} ``` Or with pasted text: `{"text": "...", "source_url": "https://example.com/terms"}`. `policy_id` is optional. You get back a `ScanReport`: - `id`, `source_url`, `doc_type` (`terms_of_service` | `privacy_policy` | `eula` | `dpa` | `other`), `fetched_at`, `word_count`, `language` - `clauses[]` — each with `id`, `category` (taxonomy id), `title`, one-sentence `summary`, `severity` (`critical` | `high` | `medium` | `low` | `info`), `quote` (verified against the source — see `quote_match`), and `section`. Each clause also carries `quote_match` (`verbatim` | `fuzzy`) and `quote_match_ratio` (0–1): how strongly its quote grounded against the source document — the evidence-strength signal, separate from severity. Kept clauses are always ≥ 0.85; `verbatim` is 1.0. - `risk_score` (0–100, deterministic: critical=25, high=12, medium=5, low=2, info=0, capped at 100) and `risk_level` (`low` <25, `medium` ≥25, `high` ≥50, `critical` ≥75) - `score_breakdown` — why the score is what it is: per-severity clause `count` and `points` (e.g. `critical: {count: 2, points: 50}`), plus `raw_total` (the uncapped sum) and `capped` (whether the 100 cap bound it). `risk_score = min(100, raw_total)`. - `content_hash` — SHA-256 of the exact document text this report was computed from: the document's version fingerprint. If a later scan's `content_hash` differs, the terms changed (monitors use the same hash for change detection). - `scoring_version` — the version of the deterministic scoring/verdict ruleset that produced this report's score and verdicts, so any result stays reproducible against the exact rules that made it. - `verdict` (`pass` | `flag` | `block`), `dealbreakers[]` (clause ids violating block rules), `recommended_actions[]` - `analysis_complete` — `false` when the document exceeded the processing cap and was truncated. Findings then cover only part of the document, and the verdict is never a clean `pass` for an incomplete analysis (it is downgraded to `flag` with an explanatory recommended action). - `agent_friendliness` (`friendly` | `restricted` | `hostile` | `unclear`) and `agent_friendliness_notes[]` — a deterministic verdict on whether the vendor's terms permit AI agents to use the service (see "Agent-friendliness" below). Check this *before* the risk score when acting on behalf of a principal: a `hostile` verdict means your principal may already be in breach by letting you touch the service. - `agent_access` — the same verdict as structured fields you can branch on without parsing prose: `automated_access` (`allowed` | `restricted` | `prohibited` | `unclear`), `account_delegation` (same scale), `ai_agent_terms` (`mentioned` | `not_mentioned`), and `official_channels_required` (`true` when automation is allowed only through the vendor's sanctioned channels — e.g. a scraping ban alongside explicit API permission; `false` when permission stands alone; `null` when unknown). - `meta` — includes `cached` (repeat scans of unchanged documents are served from cache at zero cost), `truncated` (very long documents are processed up to a chunk cap), and `quotes_dropped` (clauses the model emitted whose quotes could not be verified against the source document — dropped before scoring, per "no quote, no clause") - `disclaimer` — every report carries it: Fineprint is automated informational analysis, not legal advice. Surface it wherever you display a score or verdict. Other endpoints: `GET /v1/scans/{scan_id}` (retrieve a report), `GET /v1/scans/{scan_id}/playbook` (negotiation playbook), `POST /v1/policies` / `GET /v1/policies` / `GET /v1/policies/{policy_id}` / `DELETE /v1/policies/{policy_id}` (per-customer policies: named rule sets mapping clause categories to `block` or `flag` actions), `GET /v1/badge/{service}.svg` (public embeddable score badge), `GET /health`, `GET /v1/me` (quota status). ## Clause taxonomy The extractor only emits clauses in these 21 categories. Anything off-taxonomy is dropped, not passed through: `binding_arbitration`, `class_action_waiver`, `auto_renewal`, `unilateral_price_change`, `unilateral_modification`, `data_collection_scope`, `data_sharing_resale`, `data_training_use`, `data_retention_deletion`, `liability_cap`, `indemnification`, `termination_at_will`, `account_suspension`, `ip_assignment`, `jurisdiction_venue`, `sla_absence`, `usage_caps`, `bot_automation_ban`, `account_delegation`, `ai_agent_terms`, `automation_permitted` ## Agent-friendliness Four of the 21 categories exist for one question: **do these terms even allow an AI agent to use the service?** Many sites' ToS prohibit bots or "automated access" — and that agreement is between the site and *your principal*, not you. If you break it, your principal is the one in violation. - `bot_automation_ban` — the terms prohibit bots, crawlers, scrapers, or automated (non-human) access. - `account_delegation` — rules on sharing credentials or authorizing a third party (including an AI agent) to act on the account holder's behalf. - `ai_agent_terms` — explicit terms about AI agents: permitted, restricted, or subject to disclosure. - `automation_permitted` — the terms explicitly allow automated access or agents acting for the user. Every scan computes a deterministic `agent_friendliness` verdict from the detected clauses — no LLM in the verdict: - `hostile` — automated access is prohibited. Do not use the service as an agent without written permission; route to your principal. - `restricted` — delegation limits or AI-agent conditions apply, but no outright ban. Read `agent_friendliness_notes` and confirm the conditions are satisfiable before proceeding. - `friendly` — automation is explicitly permitted. Proceed per the risk verdict. - `unclear` — no agent-relevant clauses detected, or agent use is mentioned only neutrally. A neutral mention is not permission: agent use is neither permitted nor prohibited on the face of the terms; treat as unknown, not as permission. Use it as a pre-gate: check `agent_friendliness` before `verdict`. A `pass` on risk means nothing if the terms ban your existence. ## Policy verdicts Policies are per-customer: `POST /v1/policies` creates a policy owned by your API key, `GET /v1/policies` lists the built-in system policies (`policy_standard`, `policy_strict`, `policy_procurement`) plus your own, `GET /v1/policies/{policy_id}` fetches one, and `DELETE /v1/policies/{policy_id}` removes your own (system policies can't be deleted). Nobody else can see or use your custom policies. Define a policy once, e.g. block `binding_arbitration`, flag `data_training_use`. Every scan against that `policy_id` returns `block` if any clause matches a block rule, `flag` if any matches a flag rule, otherwise `pass`. This is the compliance gate: wire the verdict into your agent's tool-use policy so a `block` halts acceptance and routes to a human. ## Pricing - **Free**: $0 — 25 scans/month - **Pro**: $19.99/month — 500 scans/month - **Team**: $79.99/month — 2,500 scans/month - **Business (pilot)**: $149/month — 1,000 scans/month, 500 monitors, watchlist page, design-partner onboarding. Pilot tiers are assigned manually — contact us to apply. - **Overage**: $0.15/scan beyond quota (Pro/Team with an active subscription; metered via Stripe) Quotas reset monthly. Check yours at `GET /v1/me`. ## Agent self-serve (no human required) - **Trial keys**: `POST /v1/customers/anonymous` mints an API key with no email — 5 scans/month, 1 monitor, rate-limited per IP. Same `X-API-Key` auth as every other endpoint. - **Pay per scan**: `POST /v1/scans/x402` via x402 — $0.25/scan, no key (beta: the endpoint is live and returns payment requirements; USDC settlement is being enabled) at all. Rails: USDC on Base, or XRP / RLUSD on the XRP Ledger. The first call returns `402` with payment requirements (one entry per rail); sign with your wallet and retry with the base64 payload in the `X-PAYMENT` header. (Rolling out — settlement not yet live; contact us to enable.) ## Authentication `X-API-Key` request header. Obtain a key (shown once, prefixed `fp_live_`): ```http POST /v1/customers Content-Type: application/json {"email": "agent-owner@example.com"} ``` ## Machine endpoints - `/llms.txt` — this file - `/.well-known/fineprint.json` — structured service manifest (endpoints, auth, pricing, grounding guarantees) - `/docs` — auto-generated OpenAPI documentation - `GET /v1/leaderboard` — public, unauthenticated ToS risk rankings (no key, no quota); `?limit=`, `?since=`, `?q=`; entries older than 30 days flagged `stale` - `GET /v1/agent-access/{service}` — pre-flight agent-access check for one published service (no key, no quota): the structured decision (`automated_access`, `account_delegation`, `ai_agent_terms`, `official_channels_required`) + friendliness verdict + risk score. Always 200 — branch on `known`; unknown services return `known: false` with a scan hint ## MCP server If your runtime speaks MCP, skip the REST API: Fineprint ships an MCP server with thirteen tools — `check_agent_access(service)` (pre-flight: can an agent use this service at all? no key, no quota, answered from the leaderboard), `scan_terms_of_service(url)`, `scan_terms_text(text)`, `batch_scan_terms(urls)` (up to 20 vendors, riskiest-first ranking), `compare_scans(scan_ids)` (category-by-category severity matrix), `get_scan_report(scan_id)`, `get_tos_leaderboard(limit, query)`, `check_quota()`, `watch_terms(url, interval_days, webhook_url)`, `list_monitors()`, `list_policies()` (built-in + your custom policies), `create_policy(name, block_categories, flag_categories)` (your principal's own dealbreakers), and `get_negotiation_playbook(scan_id)` (what to ask the vendor for, fallbacks, leverage, walk-away signals). Configure with `FINEPRINT_API_URL` and `FINEPRINT_API_KEY` (see `marketing/mcp/README.md`). The leaderboard tool needs no key. ## Batch scanning, comparison, and audit PDFs Evaluating a vendor shortlist? `POST /v1/scans/batch` scans up to 20 URLs in one call (1 quota unit each, per-URL failures reported inline, riskiest-first ranking returned). `POST /v1/scans/compare` takes 2–20 scan ids and returns a vendor ranking plus a category-by-category matrix of worst severity per vendor — free, no quota. For a human-forwardable deliverable, `GET /v1/scans/{scan_id}/report.pdf` renders a branded audit PDF (verdict, score, every finding with its source quote, methodology, evidence provenance) and `POST /v1/reports/audit-pack.pdf` builds the multi-vendor comparison pack — the five-vendor audit deliverable in one call. ## Negotiation playbooks A `flag` or `block` is only useful if someone knows what to do next. `GET /v1/scans/{scan_id}/playbook` returns a negotiation playbook for every flagged clause: what to ask the vendor for, an acceptable fallback, the leverage that makes the ask credible, and the walk-away signal — ordered riskiest first, with the clause's source quote attached. The single-vendor audit PDF includes the playbook as a section. Negotiation guidance, not legal advice; every response carries the disclaimer. ## Score badges Published leaderboard services get an embeddable "nutrition label" badge: `GET /v1/badge/{service}.svg` returns an SVG with the live score and risk level (public, no key, cacheable). Vendors embed it on their own sites as proof of fair terms — which turns every badge into Fineprint distribution. Embed snippet and terms are documented on `/methodology.html`. ## Change monitoring Vendor terms change under you. `watch_terms(url)` (REST: `POST /v1/monitors`) - **No-API watching**: `POST /v1/watch` with `{email, service}` (a leaderboard slug) starts watching a vendor with no key and no code — the response carries a one-time API key for new accounts, and `GET /v1/watchlist?key=...` renders the human-readable monitor list (baselines, latest checks, alerts). establishes a quoted, scored baseline immediately (costs 1 scan), then every check compares the live document's content hash to the baseline: - **Unchanged** — free. No quota consumed, no LLM call, check recorded clean. - **Changed** — 1 scan of quota: full re-extraction, rescore, and a clause diff (`added` / `removed`, keyed on category + quote, so reworded clauses surface as removed+added). - **Material change** — deterministic alert when the risk score jumps ≥10 points, a new high/critical clause appears, or the verdict worsens (pass→flag→block). If the monitor has a `webhook_url`, the alert is POSTed there as `{"event": "monitor.alert", ...}` (SSRF-guarded delivery). Drive scheduled checks with `POST /v1/monitors/check-due` (authenticated; checks only the caller's due monitors) — point a cron job at it (cron-job.org, Railway cron) with `X-API-Key`. Limits: Free 3 monitors, Pro 50, Team 200. Other endpoints: `GET /v1/monitors`, `GET /v1/monitors/{id}` (with recent check history), `DELETE /v1/monitors/{id}`, `POST /v1/monitors/{id}/check` (on-demand). ## For agent readers Call Fineprint **before** any of the following on behalf of your principal: 1. Accepting terms of service, clicking "I agree", or creating an account with a vendor. 2. Granting a vendor access to principal data (API keys, customer lists, content). 3. Renewing, upgrading, or auto-renewing a subscription. 4. Choosing between vendors — compare `risk_score` and `dealbreakers` across their reports. Decision procedure: scan → first check `agent_friendliness`: if `hostile`, stop and tell your principal the terms prohibit automated access (they, not you, bear the violation). Then if `verdict == "block"`, do not proceed; surface `dealbreakers` and `recommended_actions` to your principal. If `verdict == "flag"`, proceed only if your principal's policy permits flagged categories. If `verdict == "pass"` (or no policy set), use `risk_score`/`risk_level` and the clause summaries to decide. Never act on a clause without reading its `quote` — the quote is the evidence. ## Grounding guarantees - Every clause carries a `quote` (minimum 20 characters, schema-enforced) that was verified against the source document: verbatim, or a ≥ 0.85 fuzzy match — the match type and ratio ride on every clause (`quote_match`, `quote_match_ratio`). No quote, no clause — ungrounded output is dropped, never shipped. - Risk scoring and policy verdicts are deterministic functions of the extracted clauses. No LLM participates in scoring. - Off-taxonomy categories are dropped. The taxonomy is the contract. ## Optional - Human docs and demo: see the project README.