{
  "openapi": "3.1.1",
  "info": {
    "title": "Privacy Policy Decoder API",
    "version": "1.0.0",
    "summary": "What a privacy policy says it collects, shares, sells and keeps — with quoted evidence.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://privacypolicydecoder.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "What a privacy policy says it collects, shares, sells and keeps — with quoted evidence.",
        "description": "Give the URL of a privacy policy or paste/upload its text (English or German). The decoder lists which data categories, purposes, sharing and sale practices, retention periods, user rights, laws (GDPR, CCPA/CPRA …), international transfer mechanisms and contacts the policy mentions, quotes the sentences, and points out topics it does not mention.\n\nMethodology:\n- The policy is split into sentences; every sentence is tested against fixed English and German keyword patterns for 7 sections: data collected, purposes, sharing & selling, rights, laws, international transfers and contact.\n- An item is \"mentioned\" when at least one sentence matches; up to 3 matching sentences are quoted. If every matching sentence contains a negation (\"we do not\", \"nicht\", \"keine\"), the item is marked as negated.\n- Sale of data is classified from sentences with sell/sale/verkaufen: negated sentences count as \"does not sell\", others as \"sells or may sell\"; both present = \"mixed statements\".\n- Retention periods are durations (e.g. \"7 years\", \"nach 7 Tagen\") found in sentences about retaining, storing or deleting data; open-ended phrases like \"as long as necessary\" are flagged as vague.\n- Children's age thresholds are numbers in phrases like \"under the age of 13\" / \"unter 16 Jahren\". \"Not mentioned\" means no pattern matched — not that the practice does not happen.\n\nRule-based keyword analysis of the policy text, not legal advice and not a compliance audit. A policy can describe practices in wording these patterns miss, and what a company does may differ from what its policy says.",
        "tags": [
          "internet"
        ],
        "x-mcp-tool": "privacy_policy_decoder",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PrivacyPolicyDecoderInput"
              },
              "examples": {
                "example1": {
                  "summary": "App privacy policy (English)",
                  "value": {
                    "text": "Privacy Policy\nWe collect your name, email address and phone number when you register. We also collect your precise location, IP address and advertising ID, and we use cookies and tracking pixels.\nWe use your information to provide our services, for analytics and for personalized advertising. We may share your information with advertising partners and data brokers. We may sell your personal information; California residents can opt out via the \"Do Not Sell or Share My Personal Information\" link (CCPA/CPRA).\nWe retain your data for as long as necessary to provide our services. Payment records are kept for 7 years.\nYou have the right to access, delete and correct your personal information. Our services are not directed to children under the age of 13.\nYour data may be transferred to the United States under Standard Contractual Clauses.\nContact: privacy@example-app.com"
                  }
                },
                "example2": {
                  "summary": "Datenschutzerklärung (Deutsch)",
                  "value": {
                    "text": "Datenschutzerklärung\nVerantwortlicher im Sinne der DSGVO ist die Beispiel GmbH. Unseren Datenschutzbeauftragten erreichen Sie unter datenschutz@beispiel.de.\nWir verarbeiten Ihre E-Mail-Adresse, Ihre Anschrift und Zahlungsdaten zur Vertragserfüllung. Beim Besuch unserer Website wird Ihre IP-Adresse gespeichert und nach 7 Tagen gelöscht.\nWir setzen Cookies nur mit Ihrer Einwilligung ein. Eine Weitergabe an Dritte erfolgt nur an Dienstleister im Rahmen der Auftragsverarbeitung. Wir verkaufen Ihre Daten nicht.\nRechnungsdaten bewahren wir aufgrund gesetzlicher Pflichten 10 Jahre auf.\nSie haben das Recht auf Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung, Datenübertragbarkeit und Widerspruch. Sie können Ihre Einwilligung jederzeit widerrufen und sich bei einer Aufsichtsbehörde beschweren."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PrivacyPolicyDecoderResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "PrivacyPolicyDecoderInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "title": "Privacy policy text",
            "description": "Paste the text here, or use one of the other options below (exactly one).",
            "type": "string",
            "maxLength": 200000
          },
          "file": {
            "title": "Or upload a file",
            "description": "TXT, PDF, DOCX, HTML or a photo/scan (PNG/JPG, read with OCR). Max 5 MiB. Upload as {filename, contentType?, contentBase64}. Max 5120 KiB. Accepts .txt,.pdf,.docx,.png,.jpg,.jpeg,.html.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "url": {
            "title": "Or the privacy policy URL",
            "description": "A public http(s) address. The page text is fetched once and analysed.",
            "type": "string",
            "format": "uri"
          }
        },
        "required": []
      },
      "PrivacyPolicyDecoderResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "confidence",
              "sections",
              "sale",
              "retention",
              "childrenAgeThresholds",
              "contactEmails",
              "flags",
              "gaps",
              "sentences"
            ],
            "properties": {
              "confidence": {
                "type": "string",
                "const": "pattern-match"
              },
              "sentences": {
                "type": "integer",
                "minimum": 0
              },
              "sections": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "title",
                    "items"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "label",
                          "status",
                          "negated",
                          "evidence"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "mentioned",
                              "not mentioned"
                            ]
                          },
                          "negated": {
                            "type": "boolean",
                            "description": "All evidence sentences contain a negation (e.g. \"we do not …\")."
                          },
                          "evidence": {
                            "type": "array",
                            "maxItems": 3,
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "quote",
                                "rule"
                              ],
                              "properties": {
                                "quote": {
                                  "type": "string"
                                },
                                "rule": {
                                  "type": "string"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              },
              "sale": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "status",
                  "evidence"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "says it sells or may sell",
                      "says it does not sell",
                      "mixed statements",
                      "not mentioned"
                    ]
                  },
                  "evidence": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "retention": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "periods",
                  "vague",
                  "evidence"
                ],
                "properties": {
                  "periods": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "duration",
                        "approxDays",
                        "evidence"
                      ],
                      "properties": {
                        "duration": {
                          "type": "string"
                        },
                        "approxDays": {
                          "type": "number"
                        },
                        "evidence": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "vague": {
                    "type": "boolean",
                    "description": "Uses open-ended wording such as \"as long as necessary\"."
                  },
                  "evidence": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "childrenAgeThresholds": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "contactEmails": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "flags": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "flag",
                    "rule"
                  ],
                  "properties": {
                    "flag": {
                      "type": "string"
                    },
                    "rule": {
                      "type": "string"
                    }
                  }
                }
              },
              "gaps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}