{
  "openapi": "3.1.1",
  "info": {
    "title": "Paperwell API",
    "version": "1.0.0",
    "summary": "Deterministic tools for people and AI agents.",
    "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://paperwell.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/tools": {
      "get": {
        "operationId": "listTools",
        "summary": "Catalog of all tools",
        "responses": {
          "200": {
            "description": "Tool list.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/{id}": {
      "get": {
        "operationId": "getTool",
        "summary": "Definition of one tool",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "paperwell-notice-deadlines",
                "paperwell-page-plan",
                "paperwell-document-scan",
                "office-to-pdf-converter",
                "pdf-image-converter",
                "pdf-compressor",
                "pdf-form-signature-studio",
                "pdf-merge-split-reorder",
                "searchable-pdf-ocr",
                "secure-pdf-redactor",
                "form-translator",
                "privacy-policy-decoder",
                "before-you-sign",
                "what-changed-in-this-law",
                "compatibility-engine",
                "accessibility-fixer",
                "screenshot-to-steps",
                "file-format-doctor",
                "citeshape",
                "safe-markdown-preview"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "404": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tools/paperwell-notice-deadlines/calculate": {
      "post": {
        "operationId": "calculatePaperwellNoticeDeadlines",
        "summary": "Last day to cancel a contract: terms, renewals and notice deadlines, with a calendar file.",
        "description": "Computes the term table of a contract (initial term, automatic renewals) or the earliest end of an open-ended contract (notice on any day, to the end of a month, quarter or year), the last day your notice must arrive, the days left and an iCalendar file with reminders. The same engine powers the deadlines view of Paperwell.\n\nMethodology:\n- A term of N months that starts on 15 March runs up to and including 14 March of the following period (start + N months − 1 day). Month arithmetic clamps to the last day of shorter months (31 January + 1 month = 28/29 February).\n- Notice \"N before the end of the term\" must arrive at the latest on the last day of the term minus N: three months before 31 December is 30 September; 90 days before 31 December is 2 October, so the 90 days from 3 October to 31 December fit completely.\n- Open-ended contracts: notice on any day ends the contract after the notice period; with a month/quarter/year rule the contract ends on the first period end whose notice deadline is still ahead. A minimum term moves the earliest end to its last day.\n- Business days skip Saturdays and Sundays only; public holidays are not known. Past renewal cycles are skipped so the table starts at the current term.\n- The calendar file contains one all-day event per last notice day with reminder alarms; UIDs are stable, so re-importing updates the events instead of duplicating them.\n\nNot legal advice. Contracts, local law (e.g. consumer rules that shorten notice periods) and the way notice must be delivered can change the result; check the contract wording and keep proof of delivery.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "paperwell_notice_deadlines",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaperwellNoticeDeadlinesInput"
              },
              "examples": {
                "example1": {
                  "summary": "24-month software subscription, 12-month renewals, 90 days notice",
                  "value": {
                    "title": "Software subscription",
                    "startDate": "2026-11-01",
                    "anchor": "term-end",
                    "termValue": 24,
                    "termUnit": "month",
                    "renewalValue": 12,
                    "renewalUnit": "month",
                    "noticeValue": 90,
                    "noticeUnit": "day",
                    "asOf": "2026-10-26",
                    "cycles": 3,
                    "remind": "30, 7"
                  }
                },
                "example2": {
                  "summary": "Open-ended contract: 3 months to the end of a quarter",
                  "value": {
                    "title": "Insurance",
                    "startDate": "2024-04-01",
                    "anchor": "quarter-end",
                    "noticeValue": 3,
                    "noticeUnit": "month",
                    "asOf": "2026-10-26",
                    "cycles": 3,
                    "remind": "14"
                  }
                },
                "example3": {
                  "summary": "Gym: 12 months minimum, then one month notice any time",
                  "value": {
                    "title": "Gym",
                    "startDate": "2026-01-01",
                    "anchor": "any-time",
                    "termValue": 12,
                    "termUnit": "month",
                    "noticeValue": 1,
                    "noticeUnit": "month",
                    "asOf": "2026-10-26",
                    "cycles": 1,
                    "remind": ""
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaperwellNoticeDeadlinesResult"
                }
              }
            }
          },
          "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/tools/paperwell-page-plan/calculate": {
      "post": {
        "operationId": "calculatePaperwellPagePlan",
        "summary": "Plan a PDF merge, split, reorder, removal or rotation and see every resulting page first.",
        "description": "Resolves page selections such as \"1-3,5,8-end\", \"odd\" or \"10-1\" against the page counts of your PDFs and lists the exact output files and page sequences of a merge, split, reorder, removal or rotation — before any file is uploaded. It returns the parameters for the pdf-merge-split-reorder tool, so scripts and AI agents can check a plan first.\n\nMethodology:\n- Page selections use the syntax of the site’s PDF tools: numbers and ranges (\"1-3,5\"), \"end\"/\"last\", descending ranges (\"10-1\"), \"reverse\", \"odd\"/\"even\" and range filters (\"1-9:odd\"). Order and duplicates are kept for selecting/reordering; removal and rotation use the sorted set.\n- Merging appends whole files in the given order; file numbers not listed keep their original order after the listed ones.\n- Splitting creates one file per group of N pages or per range; output names follow the pdf-merge-split-reorder tool (\"report-part-2-p4-6.pdf\").\n- The plan is computed from page counts only; no PDF is opened. The real tool re-checks everything against the files.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "paperwell_page_plan",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaperwellPagePlanInput"
              },
              "examples": {
                "example1": {
                  "summary": "Merge three PDFs, appendix first",
                  "value": {
                    "mode": "merge",
                    "files": [
                      {
                        "name": "report.pdf",
                        "pages": 12
                      },
                      {
                        "name": "appendix.pdf",
                        "pages": 3
                      },
                      {
                        "name": "cover.pdf",
                        "pages": 1
                      }
                    ],
                    "order": "3,1,2"
                  }
                },
                "example2": {
                  "summary": "Split a 10-page scan into chapters",
                  "value": {
                    "mode": "split-ranges",
                    "files": [
                      {
                        "name": "scan.pdf",
                        "pages": 10
                      }
                    ],
                    "ranges": "1-2; 3-7; 8-end"
                  }
                },
                "example3": {
                  "summary": "Reverse a back-to-front scan",
                  "value": {
                    "mode": "pages",
                    "files": [
                      {
                        "name": "backwards.pdf",
                        "pages": 6
                      }
                    ],
                    "pages": "reverse"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaperwellPagePlanResult"
                }
              }
            }
          },
          "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/tools/paperwell-document-scan/calculate": {
      "post": {
        "operationId": "calculatePaperwellDocumentScan",
        "summary": "Full text of a PDF, DOCX or scan plus identifiers, personal data, dates and amounts in it.",
        "description": "Extracts the full plain text of a PDF (per page), DOCX, HTML, text file or photo/scan (OCR) and scans it for DOIs, ISBNs, ISSNs, ORCIDs, arXiv ids and PMIDs (with check-digit validation), personal data to redact (e-mail, IBAN, phone, payment card numbers), dates, amounts and periods. Paperwell uses it to make documents searchable, comparable and ready for redaction.\n\nMethodology:\n- Text comes from the pasted text or the uploaded file: PDFs through their text layer (pdftotext, one form feed per page; scanned PDFs need OCR first), DOCX from its document XML, HTML without tags, images through Tesseract OCR (English).\n- Identifiers are matched by pattern and validated by their check digits: ISBN-10 (mod 11), ISBN-13 (mod 10), ISSN (mod 11), ORCID (ISO 7064 MOD 11-2). DOIs, arXiv ids and PMIDs have no check digit and are reported as found.\n- Personal data candidates: e-mail addresses, IBANs (only with a valid mod-97 checksum), payment card numbers (only with a valid Luhn checksum) and phone numbers (7–15 digits starting with + or 0). They become exact search terms and presets for the secure-pdf-redactor tool.\n- Dates are recognised as 2026-03-12, 12.03.2026, 12 March 2026 / 12. März 2026 and March 12, 2026; slash dates like 03/04/2026 are reported without an ISO date because the order is ambiguous.\n\nPattern matching finds typical formats, not every personal detail: names, addresses and IDs in free text are not detected. Always review a document before sharing it.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "paperwell_document_scan",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaperwellDocumentScanInput"
              },
              "examples": {
                "example1": {
                  "summary": "Reading notes with DOIs, ISBNs and an ORCID",
                  "value": {
                    "text": "Little (1961), doi:10.1287/opre.9.3.383. Textbook ISBN 0-306-40615-2. Author ORCID 0000-0002-1825-0097. Slide typo: ISBN 978-3-16-148410-5.",
                    "includeText": false
                  }
                },
                "example2": {
                  "summary": "Letter with personal data to redact",
                  "value": {
                    "text": "Dear Ms Doe,\nyour refund of EUR 249.00 will be paid to IBAN DE89 3704 0044 0532 0130 00 within 14 days. Questions: billing@shop.example or +49 30 1234 5678.\nBerlin, 12.03.2026",
                    "includeText": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaperwellDocumentScanResult"
                }
              }
            }
          },
          "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/tools/office-to-pdf-converter/calculate": {
      "post": {
        "operationId": "calculateOfficeToPdfConverter",
        "summary": "Convert Word, Excel, PowerPoint, OpenDocument, RTF and CSV files to PDF with LibreOffice.",
        "description": "Converts DOCX, DOC, ODT, RTF, PPTX, PPT, ODP, XLSX, XLS, ODS and CSV files to PDF (optionally PDF/A-2b) with LibreOffice running headless on our server. Reports the page count and the fonts used in the PDF, so you can spot substituted fonts, and shows a preview of page 1.\n\nMethodology:\n- The file type is detected from the content (OLE2 stream names for DOC/XLS/PPT, the ZIP structure for DOCX/XLSX/PPTX and OpenDocument, the {\\rtf header for RTF). CSV is accepted as UTF-8 text with a .csv/.tsv name; the separator (comma, semicolon or tab) is taken from the first line.\n- LibreOffice converts the file headless with a fresh private profile per job and a 180-second limit. Macros are not executed. Spreadsheets export every sheet with its print ranges and page setup.\n- Fonts not installed on the server are substituted: Liberation fonts stand in for Arial, Times New Roman and Courier New with identical metrics, Carlito/Caladea (if installed) for Calibri/Cambria; other fonts fall back to similar ones, which can change line and page breaks.\n- The font list is read from the produced PDF (qpdf), so you can see exactly which fonts were used. Dates and random IDs are removed so the same input always gives the same PDF.\n\nLayout fidelity is good but not perfect: complex Word/PowerPoint layouts, SmartArt, some charts, embedded objects and missing fonts can render differently from Microsoft Office. Check the PDF before sending it.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "office_to_pdf_converter",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OfficeToPdfConverterInput"
              },
              "examples": {
                "example1": {
                  "summary": "RTF letter to PDF",
                  "value": {
                    "file": {
                      "filename": "notes.rtf",
                      "contentType": "application/rtf",
                      "contentBase64": "e1xydGYxXGFuc2lcZGVmZjB7XGZvbnR0Ymx7XGYwIExpYmVyYXRpb24gU2VyaWY7fXtcZjEgQ2FsaWJyaTt9fVxmMFxmczM2IE1lZXRpbmcgbm90ZXNccGFyXGZzMjQgQWdlbmRhOiBidWRnZXQsIHRpbWVsaW5lIGFuZCBuZXh0IHN0ZXBzLlxwYXJcZjEgVGhpcyBsaW5lIGFza3MgZm9yIENhbGlicmksIHdoaWNoIGlzIHJlcGxhY2VkIGJ5IGEgbWV0cmljLWNvbXBhdGlibGUgZm9udC5ccGFyfQ=="
                    }
                  }
                },
                "example2": {
                  "summary": "Semicolon CSV to a PDF table",
                  "value": {
                    "file": {
                      "filename": "prices.csv",
                      "contentType": "text/csv",
                      "contentBase64": "SXRlbTtRdHk7UHJpY2UKQ29mZmVlOzI7My41MApUZWE7MTsyLjgwCg=="
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OfficeToPdfConverterResult"
                }
              }
            }
          },
          "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/tools/pdf-image-converter/calculate": {
      "post": {
        "operationId": "calculatePdfImageConverter",
        "summary": "Turn PDF pages into PNG or JPG images, or combine images into a PDF without quality loss.",
        "description": "Renders the pages of a PDF as PNG or JPG at 72–300 DPI (one image, or a ZIP for several pages) with a preview of the first page. In the other direction it packs JPG, PNG, TIFF, GIF or WebP images into one PDF; JPG and PNG are embedded losslessly with img2pdf, and you choose page size, fit and order.\n\nMethodology:\n- PDF → images: the PDF is validated (qpdf), decrypted with your password if needed, and each selected page is rendered by Poppler (pdftoppm) at the chosen resolution with anti-aliasing. Several pages are delivered as a ZIP; one page as a single image.\n- Pixel size = page size in points × DPI ÷ 72 (an A4 page at 150 DPI is 1240 × 1754 px). Pages that would exceed 60 megapixels are refused.\n- Images → PDF: img2pdf embeds JPEG files byte for byte and PNG data without re-compression (lossless). TIFF, GIF and WebP are first converted to PNG by ImageMagick (lossless, first frame only). Transparency is kept as a soft mask.\n- \"Same as the image\" makes each page exactly as large as the image at its stored DPI (96 DPI if none is stored). Fixed page sizes place each image according to the fit option and margin.\n- File types are detected from the content, not the file name. Outputs are deterministic: dates are not written into the PDF.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "pdf_image_converter",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PdfImageConverterInput"
              },
              "examples": {
                "example1": {
                  "summary": "Two-page PDF to PNG at 72 DPI",
                  "value": {
                    "direction": "pdf-to-images",
                    "format": "png",
                    "dpi": 72,
                    "file": {
                      "filename": "slides.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA0MDAgMzAwXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAzOCA+PgpzdHJlYW0KQlQgL0YxIDI0IFRmIDcyIDIwMCBUZCAoU2xpZGUgMSkgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNDAwIDMwMF0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMzggPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiAyMDAgVGQgKFNsaWRlIDIpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9IZWx2ZXRpY2EgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDI1MyAwMDAwMCBuIAowMDAwMDAwMzQxIDAwMDAwIG4gCjAwMDAwMDA0NjcgMDAwMDAgbiAKMDAwMDAwMDU1NSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjY1MgolJUVPRgo="
                    }
                  }
                },
                "example2": {
                  "summary": "Two images into one A4 PDF",
                  "value": {
                    "direction": "images-to-pdf",
                    "pageSize": "a4",
                    "margin": 36,
                    "file": {
                      "filename": "red.png",
                      "contentType": "image/png",
                      "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAEUlEQVR42mO4o6aGFTEMLQkAF/tKAVIwUJgAAAAASUVORK5CYII="
                    },
                    "file2": {
                      "filename": "blue.png",
                      "contentType": "image/png",
                      "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAEUlEQVR42mMQC/qAFTEMLQkAZDdWAbDlhN4AAAAASUVORK5CYII="
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfImageConverterResult"
                }
              }
            }
          },
          "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/tools/pdf-compressor/calculate": {
      "post": {
        "operationId": "calculatePdfCompressor",
        "summary": "Make PDFs smaller with Ghostscript presets or custom image DPI and JPEG quality, with previews.",
        "description": "Re-writes a PDF with Ghostscript using the screen, e-book, printer or prepress preset, or your own image resolution and JPEG quality. Shows the size before and after, can compare up to three presets side by side, and renders page 1 before and after so you can judge the quality. If the result is not smaller, you get the original back.\n\nMethodology:\n- The PDF is validated with qpdf and decrypted with your password if needed. Ghostscript (pdfwrite) then rewrites it: images are downsampled to the preset resolution and re-compressed, fonts are subset and compressed, duplicate images are stored once.\n- Presets follow Ghostscript's -dPDFSETTINGS: screen ≈ 72 DPI images, ebook ≈ 150 DPI, printer and prepress ≈ 300 DPI (prepress keeps more colour information). Screen and e-book always re-encode colour and gray images as JPEG (Ghostscript would otherwise keep smooth images lossless, which can make them larger); printer and prepress let Ghostscript choose. Custom sets the colour/gray image resolution and the JPEG quality directly.\n- With comparison on, a warning appears if a smaller level still produced a larger file than a higher-quality level.\n- Savings = 1 − new size ÷ original size. When a level does not make the file smaller (common for text-only or already optimised PDFs), the original file is returned for that level instead.\n- Page 1 is rendered at the same size before and after (Poppler) so you can compare image quality and text sharpness.\n- Dates and random IDs are removed from the output so the same input always gives the same file. Document title/author are kept; XMP metadata is removed.\n\nGhostscript re-creates the PDF: interactive elements such as form fields usually survive, but digital signatures become invalid and some rare features may be lost. Keep your original.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "pdf_compressor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PdfCompressorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Text-only PDF with the e-book preset",
                  "value": {
                    "preset": "ebook",
                    "file": {
                      "filename": "report.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAxOTMgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFF1YXJ0ZXJseSByZXBvcnQpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKFJldmVudWUgZ3JldyAxMiBwZXJjZW50LikgVGogRVQKQlQgL0YxIDE0IFRmIDcyIDY4MiBUZCAoVGhpcyBzYW1wbGUgaGFzIG9ubHkgdGV4dCwgc28gdGhlcmUgaXMgbGl0dGxlIHRvIGNvbXByZXNzLikgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMzkgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgdHdvKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2NCAwMDAwMCBuIAowMDAwMDAwMTI3IDAwMDAwIG4gCjAwMDAwMDAyNTMgMDAwMDAgbiAKMDAwMDAwMDQ5NyAwMDAwMCBuIAowMDAwMDAwNjIzIDAwMDAwIG4gCjAwMDAwMDA3MTIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4IC9Sb290IDEgMCBSID4+CnN0YXJ0eHJlZgo4MDkKJSVFT0YK"
                    }
                  }
                },
                "example2": {
                  "summary": "Compare screen, e-book and printer",
                  "value": {
                    "preset": "screen",
                    "compare": true,
                    "file": {
                      "filename": "report.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAxOTMgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFF1YXJ0ZXJseSByZXBvcnQpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKFJldmVudWUgZ3JldyAxMiBwZXJjZW50LikgVGogRVQKQlQgL0YxIDE0IFRmIDcyIDY4MiBUZCAoVGhpcyBzYW1wbGUgaGFzIG9ubHkgdGV4dCwgc28gdGhlcmUgaXMgbGl0dGxlIHRvIGNvbXByZXNzLikgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMzkgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgdHdvKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2NCAwMDAwMCBuIAowMDAwMDAwMTI3IDAwMDAwIG4gCjAwMDAwMDAyNTMgMDAwMDAgbiAKMDAwMDAwMDQ5NyAwMDAwMCBuIAowMDAwMDAwNjIzIDAwMDAwIG4gCjAwMDAwMDA3MTIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4IC9Sb290IDEgMCBSID4+CnN0YXJ0eHJlZgo4MDkKJSVFT0YK"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfCompressorResult"
                }
              }
            }
          },
          "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/tools/pdf-form-signature-studio/calculate": {
      "post": {
        "operationId": "calculatePdfFormSignatureStudio",
        "summary": "List and fill PDF form fields, and place a visible signature image or typed name on a page.",
        "description": "Shows every field of a fillable PDF (name, type, value, options), fills text fields, checkboxes, radio buttons and drop-downs, and optionally flattens the form. It can also stamp a visible signature, from an uploaded PNG/JPG or a typed name in a script font, at an exact position on any page. This is a picture of a signature, not a cryptographic digital signature.\n\nMethodology:\n- Fields are read with qpdf's JSON view of the AcroForm (/AcroForm /Fields): full name, type (text, checkbox, radio, drop-down, list, signature), current value, options and page. XFA-only forms (dynamic Adobe forms) are not supported.\n- Values are written into the field objects (/V, and /AS for checkbox/radio widgets). /NeedAppearances is set to true so viewers redraw the fields, and qpdf --generate-appearances draws text and choice fields so they show up everywhere, including when flattened.\n- Checkboxes accept yes/no (or the on-state name), radio buttons and drop-downs one of their options. Read-only fields, unknown names and invalid options are skipped and listed, never guessed.\n- Visible signature: the image (or the typed name rendered in a handwriting-style font with ImageMagick) is placed on a transparent overlay page of exactly the target page size at 200 DPI, converted with img2pdf and laid over the page with qpdf --overlay. Positions are in points from the top-left corner.\n- This is NOT a cryptographic (digital) signature: it proves nothing about who signed or whether the document was changed. Use a qualified e-signature service when a legally binding electronic signature is required.\n\nA visible signature image is not a digital signature. Existing digital signatures in the PDF become invalid when you fill or stamp it.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "pdf_form_signature_studio",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PdfFormSignatureStudioInput"
              },
              "examples": {
                "example1": {
                  "summary": "List the fields of a registration form",
                  "value": {
                    "action": "list",
                    "file": {
                      "filename": "registration.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgL0Fjcm9Gb3JtIDw8IC9GaWVsZHMgWzUgMCBSIDYgMCBSIDcgMCBSXSAvREEgKC9IZWx2IDAgVGYgMCBnKSAvRFIgPDwgL0ZvbnQgPDwgL0hlbHYgOCAwIFIgL1phRGIgOSAwIFIgPj4gPj4gPj4gPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA4IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgL0Fubm90cyBbNSAwIFIgNiAwIFIgNyAwIFJdID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggMTcwID4+CnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzYwIFRkIChSZWdpc3RyYXRpb24gZm9ybSkgVGogRVQKQlQgL0YxIDEyIFRmIDcyIDcxMiBUZCAoRnVsbCBuYW1lOikgVGogRVQKQlQgL0YxIDEyIFRmIDcyIDY3MiBUZCAoSSBhZ3JlZTopIFRqIEVUCkJUIC9GMSAxMiBUZiA3MiA2MzIgVGQgKENvdW50cnk6KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL0Fubm90IC9TdWJ0eXBlIC9XaWRnZXQgL0ZUIC9UeCAvVCAoZnVsbF9uYW1lKSAvVFUgKEZ1bGwgbmFtZSkgL1JlY3QgWzE2MCA3MDUgNDIwIDcyNV0gL0YgNCAvUCAzIDAgUiAvREEgKC9IZWx2IDEyIFRmIDAgZykgL01LIDw8IC9CQyBbMCAwIDBdID4+ID4+CmVuZG9iago2IDAgb2JqCjw8IC9UeXBlIC9Bbm5vdCAvU3VidHlwZSAvV2lkZ2V0IC9GVCAvQnRuIC9UIChhZ3JlZSkgL1JlY3QgWzE2MCA2NjUgMTc2IDY4MV0gL0YgNCAvUCAzIDAgUiAvViAvT2ZmIC9BUyAvT2ZmIC9EQSAoL1phRGIgMCBUZiAwIGcpIC9NSyA8PCAvQkMgWzAgMCAwXSAvQ0EgKDQpID4+IC9BUCA8PCAvTiA8PCAvWWVzIDEwIDAgUiAvT2ZmIDExIDAgUiA+PiA+PiA+PgplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvQW5ub3QgL1N1YnR5cGUgL1dpZGdldCAvRlQgL0NoIC9GZiAxMzEwNzIgL1QgKGNvdW50cnkpIC9SZWN0IFsxNjAgNjI1IDMyMCA2NDVdIC9GIDQgL1AgMyAwIFIgL09wdCBbKEdlcm1hbnkpIChGcmFuY2UpIChTcGFpbildIC9WIChHZXJtYW55KSAvREEgKC9IZWx2IDEyIFRmIDAgZykgL01LIDw8IC9CQyBbMCAwIDBdID4+ID4+CmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSAvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9aYXBmRGluZ2JhdHMgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9Gb3JtIC9CQm94IFswIDAgMTYgMTZdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL1phRGIgOSAwIFIgPj4gPj4gL0xlbmd0aCAzOSA+PgpzdHJlYW0KcSAwIGcgQlQgL1phRGIgMTIgVGYgMiAzIFRkICg0KSBUaiBFVCBRCmVuZHN0cmVhbQplbmRvYmoKMTEgMCBvYmoKPDwgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0Zvcm0gL0JCb3ggWzAgMCAxNiAxNl0gL0xlbmd0aCAwID4+CnN0cmVhbQoKZW5kc3RyZWFtCmVuZG9iagp4cmVmCjAgMTIKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAxNzUgMDAwMDAgbiAKMDAwMDAwMDIzMiAwMDAwMCBuIAowMDAwMDAwMzg2IDAwMDAwIG4gCjAwMDAwMDA2MDcgMDAwMDAgbiAKMDAwMDAwMDc3OSAwMDAwMCBuIAowMDAwMDAwOTk5IDAwMDAwIG4gCjAwMDAwMDEyMTEgMDAwMDAgbiAKMDAwMDAwMTMwOCAwMDAwMCBuIAowMDAwMDAxMzgxIDAwMDAwIG4gCjAwMDAwMDE1NjAgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxMiAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKMTY1OAolJUVPRgo="
                    }
                  }
                },
                "example2": {
                  "summary": "Fill the form and flatten it",
                  "value": {
                    "action": "fill",
                    "flatten": true,
                    "values": [
                      {
                        "field": "full_name",
                        "value": "Jane Doe"
                      },
                      {
                        "field": "agree",
                        "value": "yes"
                      },
                      {
                        "field": "country",
                        "value": "France"
                      }
                    ],
                    "file": {
                      "filename": "registration.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgL0Fjcm9Gb3JtIDw8IC9GaWVsZHMgWzUgMCBSIDYgMCBSIDcgMCBSXSAvREEgKC9IZWx2IDAgVGYgMCBnKSAvRFIgPDwgL0ZvbnQgPDwgL0hlbHYgOCAwIFIgL1phRGIgOSAwIFIgPj4gPj4gPj4gPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA4IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgL0Fubm90cyBbNSAwIFIgNiAwIFIgNyAwIFJdID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggMTcwID4+CnN0cmVhbQpCVCAvRjEgMTggVGYgNzIgNzYwIFRkIChSZWdpc3RyYXRpb24gZm9ybSkgVGogRVQKQlQgL0YxIDEyIFRmIDcyIDcxMiBUZCAoRnVsbCBuYW1lOikgVGogRVQKQlQgL0YxIDEyIFRmIDcyIDY3MiBUZCAoSSBhZ3JlZTopIFRqIEVUCkJUIC9GMSAxMiBUZiA3MiA2MzIgVGQgKENvdW50cnk6KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL0Fubm90IC9TdWJ0eXBlIC9XaWRnZXQgL0ZUIC9UeCAvVCAoZnVsbF9uYW1lKSAvVFUgKEZ1bGwgbmFtZSkgL1JlY3QgWzE2MCA3MDUgNDIwIDcyNV0gL0YgNCAvUCAzIDAgUiAvREEgKC9IZWx2IDEyIFRmIDAgZykgL01LIDw8IC9CQyBbMCAwIDBdID4+ID4+CmVuZG9iago2IDAgb2JqCjw8IC9UeXBlIC9Bbm5vdCAvU3VidHlwZSAvV2lkZ2V0IC9GVCAvQnRuIC9UIChhZ3JlZSkgL1JlY3QgWzE2MCA2NjUgMTc2IDY4MV0gL0YgNCAvUCAzIDAgUiAvViAvT2ZmIC9BUyAvT2ZmIC9EQSAoL1phRGIgMCBUZiAwIGcpIC9NSyA8PCAvQkMgWzAgMCAwXSAvQ0EgKDQpID4+IC9BUCA8PCAvTiA8PCAvWWVzIDEwIDAgUiAvT2ZmIDExIDAgUiA+PiA+PiA+PgplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvQW5ub3QgL1N1YnR5cGUgL1dpZGdldCAvRlQgL0NoIC9GZiAxMzEwNzIgL1QgKGNvdW50cnkpIC9SZWN0IFsxNjAgNjI1IDMyMCA2NDVdIC9GIDQgL1AgMyAwIFIgL09wdCBbKEdlcm1hbnkpIChGcmFuY2UpIChTcGFpbildIC9WIChHZXJtYW55KSAvREEgKC9IZWx2IDEyIFRmIDAgZykgL01LIDw8IC9CQyBbMCAwIDBdID4+ID4+CmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSAvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9aYXBmRGluZ2JhdHMgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9UeXBlIC9YT2JqZWN0IC9TdWJ0eXBlIC9Gb3JtIC9CQm94IFswIDAgMTYgMTZdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL1phRGIgOSAwIFIgPj4gPj4gL0xlbmd0aCAzOSA+PgpzdHJlYW0KcSAwIGcgQlQgL1phRGIgMTIgVGYgMiAzIFRkICg0KSBUaiBFVCBRCmVuZHN0cmVhbQplbmRvYmoKMTEgMCBvYmoKPDwgL1R5cGUgL1hPYmplY3QgL1N1YnR5cGUgL0Zvcm0gL0JCb3ggWzAgMCAxNiAxNl0gL0xlbmd0aCAwID4+CnN0cmVhbQoKZW5kc3RyZWFtCmVuZG9iagp4cmVmCjAgMTIKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDAxNzUgMDAwMDAgbiAKMDAwMDAwMDIzMiAwMDAwMCBuIAowMDAwMDAwMzg2IDAwMDAwIG4gCjAwMDAwMDA2MDcgMDAwMDAgbiAKMDAwMDAwMDc3OSAwMDAwMCBuIAowMDAwMDAwOTk5IDAwMDAwIG4gCjAwMDAwMDEyMTEgMDAwMDAgbiAKMDAwMDAwMTMwOCAwMDAwMCBuIAowMDAwMDAxMzgxIDAwMDAwIG4gCjAwMDAwMDE1NjAgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAxMiAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKMTY1OAolJUVPRgo="
                    }
                  }
                },
                "example3": {
                  "summary": "Typed signature at the bottom of a letter",
                  "value": {
                    "action": "sign",
                    "signatureText": "Jane Doe",
                    "x": 72,
                    "y": 160,
                    "width": 160,
                    "file": {
                      "filename": "letter.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA1IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAxNjcgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKERlYXIgU2lyIG9yIE1hZGFtLCkgVGogRVQKQlQgL0YxIDE0IFRmIDcyIDcxMiBUZCAocGxlYXNlIGZpbmQgdGhlIHNpZ25lZCBhZ3JlZW1lbnQgYXR0YWNoZWQuKSBUaiBFVApCVCAvRjEgMTQgVGYgNzIgNjgyIFRkIChLaW5kIHJlZ2FyZHMpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKNSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9IZWx2ZXRpY2EgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KZW5kb2JqCnhyZWYKMCA2CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjEgMDAwMDAgbiAKMDAwMDAwMDI0NyAwMDAwMCBuIAowMDAwMDAwNDY1IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNiAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKNTYyCiUlRU9GCg=="
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfFormSignatureStudioResult"
                }
              }
            }
          },
          "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/tools/pdf-merge-split-reorder/calculate": {
      "post": {
        "operationId": "calculatePdfMergeSplitReorder",
        "summary": "Merge PDFs, split by page count or ranges, and reorder, remove, rotate or duplicate pages.",
        "description": "Combines several PDFs into one in the order you choose, splits a PDF every N pages or by page ranges (download as a ZIP), and rearranges pages with a simple page syntax such as \"1-3,5,8-end\", \"odd\" or \"reverse\". Shows page counts before and after and a preview of the first page.\n\nMethodology:\n- Every upload is checked by its content (it must start like a PDF) and by qpdf --check. Encrypted PDFs are opened with the password you give (passed to qpdf in a private file, never on a command line) and written without encryption.\n- Merge: qpdf copies all pages of each file, in the chosen order, into the first file. Bookmarks and document metadata come from the first file; form fields of all files are kept.\n- Split: each part is a separate PDF built from the selected pages; several parts are packed into one ZIP.\n- Select/reorder: the page list is taken literally, so \"3,1,2\" reorders, \"1,1,2\" duplicates page 1, and \"reverse\" reverses. Remove keeps every page not listed. Rotate adds the angle to the current rotation of the listed pages (lossless, no re-rendering).\n- Page contents are never re-encoded: text, fonts and images stay exactly as they were. qpdf writes a deterministic file ID, so the same input always gives the same file.\n\nDigital signatures in the input become invalid when pages are changed. Keep your originals.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "pdf_merge_split_reorder",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PdfMergeSplitReorderInput"
              },
              "examples": {
                "example1": {
                  "summary": "Merge two PDFs (6 pages)",
                  "value": {
                    "mode": "merge",
                    "file": {
                      "filename": "report.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUiA3IDAgUiA5IDAgUl0gL0NvdW50IDQgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDQgMCBSID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggNTEgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMTogSW50cm9kdWN0aW9uKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggNDYgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMjogTWV0aG9kcykgVGogRVQKZW5kc3RyZWFtCmVuZG9iago3IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMTEgMCBSID4+ID4+IC9Db250ZW50cyA4IDAgUiA+PgplbmRvYmoKOCAwIG9iago8PCAvTGVuZ3RoIDQ2ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDM6IFJlc3VsdHMpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9NZWRpYUJveCBbMCAwIDU5NSA4NDJdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL0YxIDExIDAgUiA+PiA+PiAvQ29udGVudHMgMTAgMCBSID4+CmVuZG9iagoxMCAwIG9iago8PCAvTGVuZ3RoIDQ3ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDQ6IEFwcGVuZGl4KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSAvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgplbmRvYmoKeHJlZgowIDEyCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMzkgMDAwMDAgbiAKMDAwMDAwMDI2NiAwMDAwMCBuIAowMDAwMDAwMzY3IDAwMDAwIG4gCjAwMDAwMDA0OTQgMDAwMDAgbiAKMDAwMDAwMDU5MCAwMDAwMCBuIAowMDAwMDAwNzE3IDAwMDAwIG4gCjAwMDAwMDA4MTMgMDAwMDAgbiAKMDAwMDAwMDk0MSAwMDAwMCBuIAowMDAwMDAxMDM5IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMTIgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjExMzcKJSVFT0YK"
                    },
                    "file2": {
                      "filename": "annex.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAzOCA+PgpzdHJlYW0KQlQgL0YxIDI0IFRmIDcyIDc0MiBUZCAoQW5uZXggQSkgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMzggPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKEFubmV4IEIpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKNyAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9IZWx2ZXRpY2EgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcgPj4KZW5kb2JqCnhyZWYKMCA4CjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMjcgMDAwMDAgbiAKMDAwMDAwMDI1MyAwMDAwMCBuIAowMDAwMDAwMzQxIDAwMDAwIG4gCjAwMDAwMDA0NjcgMDAwMDAgbiAKMDAwMDAwMDU1NSAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDggL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjY1MgolJUVPRgo="
                    }
                  }
                },
                "example2": {
                  "summary": "Split every 2 pages into a ZIP",
                  "value": {
                    "mode": "split-every",
                    "everyN": 2,
                    "file": {
                      "filename": "report.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUiA3IDAgUiA5IDAgUl0gL0NvdW50IDQgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDQgMCBSID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggNTEgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMTogSW50cm9kdWN0aW9uKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggNDYgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMjogTWV0aG9kcykgVGogRVQKZW5kc3RyZWFtCmVuZG9iago3IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMTEgMCBSID4+ID4+IC9Db250ZW50cyA4IDAgUiA+PgplbmRvYmoKOCAwIG9iago8PCAvTGVuZ3RoIDQ2ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDM6IFJlc3VsdHMpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9NZWRpYUJveCBbMCAwIDU5NSA4NDJdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL0YxIDExIDAgUiA+PiA+PiAvQ29udGVudHMgMTAgMCBSID4+CmVuZG9iagoxMCAwIG9iago8PCAvTGVuZ3RoIDQ3ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDQ6IEFwcGVuZGl4KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSAvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgplbmRvYmoKeHJlZgowIDEyCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMzkgMDAwMDAgbiAKMDAwMDAwMDI2NiAwMDAwMCBuIAowMDAwMDAwMzY3IDAwMDAwIG4gCjAwMDAwMDA0OTQgMDAwMDAgbiAKMDAwMDAwMDU5MCAwMDAwMCBuIAowMDAwMDAwNzE3IDAwMDAwIG4gCjAwMDAwMDA4MTMgMDAwMDAgbiAKMDAwMDAwMDk0MSAwMDAwMCBuIAowMDAwMDAxMDM5IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMTIgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjExMzcKJSVFT0YK"
                    }
                  }
                },
                "example3": {
                  "summary": "Cover page, then all pages in reverse order",
                  "value": {
                    "mode": "pages",
                    "pages": "1,reverse",
                    "file": {
                      "filename": "report.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUiA3IDAgUiA5IDAgUl0gL0NvdW50IDQgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDQgMCBSID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggNTEgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMTogSW50cm9kdWN0aW9uKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSAxMSAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggNDYgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKFBhZ2UgMjogTWV0aG9kcykgVGogRVQKZW5kc3RyZWFtCmVuZG9iago3IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgMTEgMCBSID4+ID4+IC9Db250ZW50cyA4IDAgUiA+PgplbmRvYmoKOCAwIG9iago8PCAvTGVuZ3RoIDQ2ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDM6IFJlc3VsdHMpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9NZWRpYUJveCBbMCAwIDU5NSA4NDJdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL0YxIDExIDAgUiA+PiA+PiAvQ29udGVudHMgMTAgMCBSID4+CmVuZG9iagoxMCAwIG9iago8PCAvTGVuZ3RoIDQ3ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDQ6IEFwcGVuZGl4KSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjw8IC9UeXBlIC9Gb250IC9TdWJ0eXBlIC9UeXBlMSAvQmFzZUZvbnQgL0hlbHZldGljYSAvRW5jb2RpbmcgL1dpbkFuc2lFbmNvZGluZyA+PgplbmRvYmoKeHJlZgowIDEyCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDY0IDAwMDAwIG4gCjAwMDAwMDAxMzkgMDAwMDAgbiAKMDAwMDAwMDI2NiAwMDAwMCBuIAowMDAwMDAwMzY3IDAwMDAwIG4gCjAwMDAwMDA0OTQgMDAwMDAgbiAKMDAwMDAwMDU5MCAwMDAwMCBuIAowMDAwMDAwNzE3IDAwMDAwIG4gCjAwMDAwMDA4MTMgMDAwMDAgbiAKMDAwMDAwMDk0MSAwMDAwMCBuIAowMDAwMDAxMDM5IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgMTIgL1Jvb3QgMSAwIFIgPj4Kc3RhcnR4cmVmCjExMzcKJSVFT0YK"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PdfMergeSplitReorderResult"
                }
              }
            }
          },
          "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/tools/searchable-pdf-ocr/calculate": {
      "post": {
        "operationId": "calculateSearchablePdfOcr",
        "summary": "Make scanned PDFs searchable and copyable with OCRmyPDF and Tesseract, optionally as PDF/A.",
        "description": "Adds an invisible, selectable text layer to scanned PDFs (or a scanned JPG/PNG) using OCRmyPDF and Tesseract. Choose the document languages, straighten crooked scans, fix upside-down pages and optionally create a PDF/A for archiving. Reports how many pages were recognised and shows a sample of the extracted text.\n\nMethodology:\n- Images (JPG/PNG/TIFF) are first wrapped into a PDF with img2pdf. PDFs are validated with qpdf and decrypted with your password if needed.\n- OCRmyPDF renders each page, lets Tesseract recognise the text in the chosen languages and lays the words as invisible text exactly over the image, so the page looks unchanged but can be searched and copied.\n- \"Leave them as they are\" skips pages that already have text (born-digital pages stay untouched). \"OCR every page\" rasterises such pages too, which replaces their vector text with an image plus OCR text.\n- Pages processed = pages without extractable text before (or all pages when forcing OCR). The text sample and character count are read back from the result with pdftotext.\n- Without OCRmyPDF the server falls back to Tesseract alone: every page is rendered at 300 DPI in grayscale and rebuilt as image + text (deskew, rotation and PDF/A are then unavailable).\n- Random internal names, dates and IDs are normalised so the same input gives the same file; PDF/A keeps its XMP metadata with the timestamps set to 2000-01-01.\n\nOCR is not perfect: handwriting, low-resolution scans, unusual fonts and complex layouts produce errors. Check important text against the image.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "searchable_pdf_ocr",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchablePdfOcrInput"
              },
              "examples": {
                "example1": {
                  "summary": "Scanned line of text (PNG) to a searchable PDF",
                  "value": {
                    "file": {
                      "filename": "scan.png",
                      "contentType": "image/png",
                      "contentBase64": "iVBORw0KGgoAAAANSUhEUgAAAggAAABGAQAAAACBSlH7AAABvklEQVRYw+3UMUvEMBQH8MgVM+bGG4QMfgkn47dx1V2aA4eO/UonGfoxbMngaLpFCHm+l1ZUUNOeIAh5w5+jvfy45N4Lg98WK0IRilCEIvydYL/+RtDw9LMQ1WchcnAKI4hjBXcCvcBwm2OFnukDx+jXC2+Q102HYd4frRQgKGEx2hXCmexA9trCCRzoKJW0GHiQ4UZ7GfQhK2y5iWovbWCaqSSMFChcyQMPen+dExi3UVXC+m1d4bp4mYSdhFCJh/ugK54TuLG4qrVu2n24VCN+2mJLyPZxCLVscoKwY6hVZ3GdJqEmoWYbZBqgV1lBonCnOzuAhw7Ak+BrbhDs4IVeZYWRBGPtJLiIgotiSIJfJngftCWB4aENJAxR0qY6x44QDAlmEmxPQrYfUHCzQI8aEppZMAt3EW4/CIIWC5h20a4QzCxEiYtTrBHieZj+TU2DBdjg6k1wS4U4dxSQgg2uoR2oo1BY0lFj3MS5q5/B4Vl2FIa6uumXdDX+Xg7TZJ0KvKMU3VEYabLYkslKwjzdSehFCprufrdkupMw3zCKBKcwvKQbxl3kb5gfig42W0X4J8KiKkIRilCE7+oV25/CiYnY+pIAAAAASUVORK5CYII="
                    },
                    "languages": [
                      "eng"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchablePdfOcrResult"
                }
              }
            }
          },
          "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/tools/secure-pdf-redactor/calculate": {
      "post": {
        "operationId": "calculateSecurePdfRedactor",
        "summary": "Black out names, numbers or areas in a PDF for real: the text is removed, not just covered.",
        "description": "Finds words, phrases, regular expressions or typical personal data (e-mails, phone numbers, IBANs, card numbers) and any rectangles you specify, then rebuilds the affected pages as images with black boxes so the hidden text is truly gone. Optionally re-runs OCR so the rest of the page stays searchable, strips metadata, and proves the result with a text search of the output.\n\nMethodology:\n- Word positions come from Poppler (pdftotext -bbox-layout). Each text line is searched for your words/phrases (spaces may vary), regular expressions and the chosen patterns; every word that overlaps a match gets a black box with 1.5 pt padding. A match that wraps onto the next line is not found as one phrase; the final check reports it.\n- Pages with at least one box are rendered to an image at the chosen DPI, the boxes are painted black into the pixels, and the page is rebuilt from that image. The original text, fonts and vector content of those pages are discarded — covering text with a black rectangle (the common mistake) would leave it copyable.\n- With OCR on, Tesseract re-recognises the remaining visible text of rebuilt pages, so they stay searchable without the redacted words. Pages without hits are copied unchanged (text stays selectable).\n- The document is reassembled with qpdf from scratch, which drops: Document information (title, author, subject, keywords, creator, producer, creation and modification dates); XMP metadata stream; Bookmarks (outline), named destinations and page labels; Attachments (embedded files) and document-level JavaScript; Interactive form (AcroForm) definitions; Page-level metadata and application data (/Metadata, /PieceInfo). With \"Remove comments…\" on, all annotations (comments, links, form widgets) are removed from every page.\n- Patterns: phone numbers must start with +, 00 or a 0 trunk prefix, have 7–15 digits with the usual separators and are skipped when they are a date or part of an IBAN; card numbers must pass the Luhn checksum and are skipped inside IBANs.\n- Verification: the text of the finished PDF is extracted again with pdftotext and every term and pattern is searched; the report lists matches before and after. Only \"0 after\" for every row means the text-level redaction succeeded.\n\nText inside images (scans, screenshots) and text drawn as outlines cannot be found by search; use areas for those, and always review the redacted pages visually before sharing.",
        "tags": [
          "documents"
        ],
        "x-mcp-tool": "secure_pdf_redactor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SecurePdfRedactorInput"
              },
              "examples": {
                "example1": {
                  "summary": "Redact a name and e-mail addresses",
                  "value": {
                    "terms": [
                      "Alice Smith"
                    ],
                    "presets": [
                      "email"
                    ],
                    "file": {
                      "filename": "contract.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAyMTcgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKEVtcGxveW1lbnQgY29udHJhY3QpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKEVtcGxveWVlOiBBbGljZSBTbWl0aCkgVGogRVQKQlQgL0YxIDE0IFRmIDcyIDY4MiBUZCAoQ29udGFjdDogYWxpY2Uuc21pdGhAZXhhbXBsZS5jb20pIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA2NTIgVGQgKFNhbGFyeTogNTIsMDAwIEVVUikgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMTA0ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDIpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKFNpZ25lZCBieSBBbGljZSBTbWl0aCBhbmQgQm9iIEpvbmVzKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2NCAwMDAwMCBuIAowMDAwMDAwMTI3IDAwMDAwIG4gCjAwMDAwMDAyNTMgMDAwMDAgbiAKMDAwMDAwMDUyMSAwMDAwMCBuIAowMDAwMDAwNjQ3IDAwMDAwIG4gCjAwMDAwMDA4MDIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4IC9Sb290IDEgMCBSID4+CnN0YXJ0eHJlZgo4OTkKJSVFT0YK"
                    }
                  }
                },
                "example2": {
                  "summary": "Black out a fixed area on page 1",
                  "value": {
                    "areas": "1, 72, 160, 300, 30",
                    "ocr": false,
                    "file": {
                      "filename": "contract.pdf",
                      "contentType": "application/pdf",
                      "contentBase64": "JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA1IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA1OTUgODQyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA3IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgPj4KZW5kb2JqCjQgMCBvYmoKPDwgL0xlbmd0aCAyMTcgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3NDIgVGQgKEVtcGxveW1lbnQgY29udHJhY3QpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKEVtcGxveWVlOiBBbGljZSBTbWl0aCkgVGogRVQKQlQgL0YxIDE0IFRmIDcyIDY4MiBUZCAoQ29udGFjdDogYWxpY2Uuc21pdGhAZXhhbXBsZS5jb20pIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA2NTIgVGQgKFNhbGFyeTogNTIsMDAwIEVVUikgVGogRVQKZW5kc3RyZWFtCmVuZG9iago1IDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMiAwIFIgL01lZGlhQm94IFswIDAgNTk1IDg0Ml0gL1Jlc291cmNlcyA8PCAvRm9udCA8PCAvRjEgNyAwIFIgPj4gPj4gL0NvbnRlbnRzIDYgMCBSID4+CmVuZG9iago2IDAgb2JqCjw8IC9MZW5ndGggMTA0ID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzQyIFRkIChQYWdlIDIpIFRqIEVUCkJUIC9GMSAxNCBUZiA3MiA3MTIgVGQgKFNpZ25lZCBieSBBbGljZSBTbWl0aCBhbmQgQm9iIEpvbmVzKSBUaiBFVAplbmRzdHJlYW0KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0ZvbnQgL1N1YnR5cGUgL1R5cGUxIC9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nID4+CmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2NCAwMDAwMCBuIAowMDAwMDAwMTI3IDAwMDAwIG4gCjAwMDAwMDAyNTMgMDAwMDAgbiAKMDAwMDAwMDUyMSAwMDAwMCBuIAowMDAwMDAwNjQ3IDAwMDAwIG4gCjAwMDAwMDA4MDIgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSA4IC9Sb290IDEgMCBSID4+CnN0YXJ0eHJlZgo4OTkKJSVFT0YK"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SecurePdfRedactorResult"
                }
              }
            }
          },
          "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/tools/form-translator/calculate": {
      "post": {
        "operationId": "calculateFormTranslator",
        "summary": "Plain-language help for confusing forms: field-by-field hints and jargon explained.",
        "description": "Paste or upload (incl. photo/OCR) an official, insurance or tax form in English or German. Form Translator detects the fields, recognises what kind of entry each needs (date, signature, checkbox, IBAN, tax ID …), explains jargon from a curated glossary of 160 terms and lists the documents you will probably need.\n\nMethodology:\n- Lines are scanned for field labels: \"Label:\" followed by blanks, labels next to fill lines (____ or ....), checkbox options (☐, □, [ ], ( )) and short label-only lines that contain a field keyword.\n- Each label is classified with keyword rules into field types (date, signature, checkbox, IBAN/bank, tax ID, ID/reference number, e-mail, phone, address, name, amount, marital status, nationality, place+date), each with a fixed fill-in hint.\n- Jargon is matched against an editorial glossary (160 English and German admin, tax, insurance, benefits, banking and legal terms incl. inflected German forms). Explanations are written by usefulweb.site editors, not generated.\n- Documents are listed when a sentence asks to attach/enclose/provide proof (beifügen, Nachweis, Kopie, Bescheinigung …), quoted verbatim, plus documents commonly requested for recognised glossary terms (marked as such).\n- IBANs found in the text are checked with the ISO 13616 mod-97 checksum (German IBANs must have 22 characters). A valid checksum does not prove the account exists.\n\nNot legal, tax or insurance advice. Explanations are editorial plain-language summaries for orientation and may not match the exact legal meaning in your country, contract or authority. The detection is rule-based and never complete; when in doubt, ask the issuing office.",
        "tags": [
          "everyday"
        ],
        "x-mcp-tool": "form_translator",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FormTranslatorInput"
              },
              "examples": {
                "example1": {
                  "summary": "German Kindergeld-style application",
                  "value": {
                    "text": "Antrag auf Kindergeld\n\n1. Angaben zur antragstellenden Person\nName, Vorname: ______________________\nGeburtsdatum (TT.MM.JJJJ): __________\nSteuer-ID: ___________\nAnschrift (Straße, Hausnummer, PLZ, Ort): ____________________\nFamilienstand:\n☐ ledig ☐ verheiratet ☐ geschieden ☐ verwitwet\n\n2. Angaben zum Ehegatten / eingetragenen Lebenspartner\nName, Vorname: ______________\n\n3. Bankverbindung\nIBAN: DE89 3704 0044 0532 0130 00\nKontoinhaber: ______________\n\nBitte fügen Sie eine Kopie der Geburtsurkunde und ggf. eine Schulbescheinigung bei.\nIch versichere, dass meine Angaben vollständig und richtig sind.\nOrt, Datum: ____________   Unterschrift: ________________"
                  }
                },
                "example2": {
                  "summary": "US health insurance enrollment",
                  "value": {
                    "text": "Health Plan Enrollment Form\n\nPolicyholder name: ____________\nDate of birth (MM/DD/YYYY): ________\nSocial Security Number: ___-__-____\nMarital status: [ ] Single [ ] Married [ ] Divorced\nDependents (name, DOB, relationship): ______________\nPrimary beneficiary: ______________\n\nPlan options: The Silver plan has a $2,000 deductible, 20% coinsurance and a $30 copay for primary care visits.\nDo you have a pre-existing condition? [ ] Yes [ ] No\n\nPlease attach a copy of your ID and proof of address.\nSignature of applicant: ______________ Date: ________"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormTranslatorResult"
                }
              }
            }
          },
          "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/tools/privacy-policy-decoder/calculate": {
      "post": {
        "operationId": "calculatePrivacyPolicyDecoder",
        "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 (incl. German separable verbs such as \"bewahren … auf\"); 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/tools/before-you-sign/calculate": {
      "post": {
        "operationId": "calculateBeforeYouSign",
        "summary": "Spot risky contract clauses (renewal, notice, liability, non-compete…) before you sign.",
        "description": "Paste, upload or link a contract, terms of service, lease or employment agreement in English or German. Before You Sign flags 19 kinds of clauses — auto-renewal, notice periods, minimum terms, termination fees, liability limits, indemnities, arbitration, non-competes, IP assignment, price escalation, penalties, guarantees, data sharing and unilateral changes — quotes each clause, extracts durations and amounts, and lists questions to ask.\n\nMethodology:\n- The contract is split into sentences (numbered clauses, bullets and § headings start new units).\n- Each sentence is tested against 19 clause categories, each with English and German regular-expression patterns (e.g. \"automatically renew\", \"verlängert sich stillschweigend\", \"Kündigungsfrist\", \"Vertragsstrafe\", \"hold harmless\").\n- Parameters are extracted from the matched sentence: durations (numbers or number words, incl. \"three months\"/\"drei Monate\"), percentages, money amounts, radius (km/miles), governing law and court venue.\n- Severity comes from a fixed, documented rule per category (e.g. notice period ≥ 3 months = high; non-compete ≥ 12 months or ≥ 50 km = high). It signals how much attention a clause deserves, not whether it is legal or enforceable.\n- Each category has fixed questions to ask before signing. Categories without any match are listed as \"not detected\" — absence of a match is not proof the clause is absent.\n\nNot legal advice. This is an automated, rule-based text analysis that can miss or misread clauses; it never claims completeness. For decisions with legal or financial consequences, ask a qualified professional (e.g. a lawyer, tax adviser or consumer advice centre).",
        "tags": [
          "high-value"
        ],
        "x-mcp-tool": "before_you_sign",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BeforeYouSignInput"
              },
              "examples": {
                "example1": {
                  "summary": "SaaS subscription terms (English)",
                  "value": {
                    "text": "1. Term. The initial term of this Agreement is 24 months. Thereafter, this Agreement shall automatically renew for successive 12-month periods unless either party provides at least 90 days' prior written notice of non-renewal.\n2. Fees. Provider may increase the fees at any time at its sole discretion. Overdue amounts bear interest at 1.5% per month.\n3. Early termination. If Customer terminates before the end of the initial term, all remaining fees for the term become immediately due.\n4. Liability. In no event shall Provider be liable for any indirect or consequential damages; Provider's aggregate liability is limited to the fees paid in the last 3 months.\n5. Customer shall indemnify and hold harmless Provider from any and all claims arising from Customer's use of the service.\n6. Disputes. Any dispute shall be resolved by binding arbitration, and Customer waives any right to participate in a class action. This Agreement is governed by the laws of the State of Delaware.\n7. Provider reserves the right to modify these terms at any time; continued use constitutes acceptance."
                  }
                },
                "example2": {
                  "summary": "Arbeitsvertrag mit Wettbewerbsverbot (Deutsch)",
                  "value": {
                    "text": "§ 2 Vertragsdauer\nDas Arbeitsverhältnis wird auf unbestimmte Zeit geschlossen. Die Kündigungsfrist beträgt drei Monate zum Quartalsende.\n§ 7 Wettbewerbsverbot\nDer Arbeitnehmer verpflichtet sich, für die Dauer von 24 Monaten nach Beendigung des Arbeitsverhältnisses in einem Umkreis von 100 km nicht für ein Konkurrenzunternehmen tätig zu werden. Für jeden Fall der Zuwiderhandlung ist eine Vertragsstrafe in Höhe von 10.000 EUR zu zahlen.\n§ 8 Verschwiegenheit\nDer Arbeitnehmer ist verpflichtet, über alle Betriebsgeheimnisse auch nach Beendigung des Arbeitsverhältnisses zeitlich unbegrenzt Stillschweigen zu bewahren.\n§ 9 Arbeitsergebnisse\nDer Arbeitnehmer überträgt dem Arbeitgeber sämtliche Nutzungsrechte an allen Arbeitsergebnissen zeitlich und räumlich unbeschränkt.\n§ 12 Schlussbestimmungen\nEs gilt deutsches Recht. Gerichtsstand ist München."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BeforeYouSignResult"
                }
              }
            }
          },
          "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/tools/what-changed-in-this-law/calculate": {
      "post": {
        "operationId": "calculateWhatChangedInThisLaw",
        "summary": "Compare two versions of a law or regulation section by section, with changed numbers and deadlines.",
        "description": "Paste (or link) the old and new versions of a law, regulation, terms of service or policy. The text is split at §, Art. and Section headings, sections are aligned by their number, and every added, removed or modified section is shown with a word-level diff and the numbers, durations and obligation words (must/may/muss/kann…) that changed.\n\nMethodology:\n- Sections start at lines beginning with §, Art./Artikel/Article, Section/Sec. or Paragraph followed by a number; text before the first heading is the preamble.\n- Sections are aligned by their normalised number (LCS over section ids), so renumbered sections show as removed + added.\n- Inside a changed section a word-level LCS diff is computed; numbers, money amounts, percentages, durations and obligation words (must/shall/may, muss/kann/soll/darf…) present in only one version are listed.\n- Whitespace-only differences are ignored.\n\nNot legal advice. This is an automated, rule-based text analysis that can miss or misread clauses; it never claims completeness. For decisions with legal or financial consequences, ask a qualified professional (e.g. a lawyer, tax adviser or consumer advice centre). Always check the official consolidated text and the amending act for transitional provisions.",
        "tags": [
          "high-value"
        ],
        "x-mcp-tool": "what_changed_in_this_law",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WhatChangedInThisLawInput"
              },
              "examples": {
                "example1": {
                  "summary": "Notice period shortened",
                  "value": {
                    "oldText": "§ 1 Scope\nThis act applies to consumer contracts.\n§ 2 Notice\nThe customer must give notice of termination at least 3 months before the end of the term.\n§ 3 Fees\nA processing fee of 25 EUR may be charged.",
                    "newText": "§ 1 Scope\nThis act applies to consumer contracts.\n§ 2 Notice\nThe customer may give notice of termination at any time with a notice period of 1 month.\n§ 3 Fees\nA processing fee of 25 EUR may be charged.\n§ 4 Online cancellation\nProviders must offer a cancellation button on their website.",
                    "citation": "Example amendment act",
                    "effectiveDate": "2026-12-01"
                  }
                },
                "example2": {
                  "summary": "German: Frist geändert",
                  "value": {
                    "oldText": "§ 5 Frist\nDer Antrag ist innerhalb von 14 Tagen zu stellen.\n§ 6 Gebühr\nDie Gebühr beträgt 50 Euro.",
                    "newText": "§ 5 Frist\nDer Antrag ist innerhalb von 30 Tagen zu stellen.\n§ 6 Gebühr\nDie Gebühr beträgt 50 Euro."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WhatChangedInThisLawResult"
                }
              }
            }
          },
          "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/tools/compatibility-engine/calculate": {
      "post": {
        "operationId": "calculateCompatibilityEngine",
        "summary": "Will this charger, cable, version or PC part work together? Rule-based checks with margins.",
        "description": "Three deterministic checks: (1) USB-C charging – the real maximum power from charger, cable and device per the USB Power Delivery rules; (2) software versions – whether versions satisfy an npm-style semver range (^, ~, x-ranges, hyphen ranges, ||); (3) PC builds – CPU socket, RAM generation, slots and power-supply headroom.\n\nMethodology:\n- Charging: with USB PD on both sides the standard power range allows 5/9/15/20 V at 3 A (≤ 60 W with a standard cable) and 20 V at 5 A (≤ 100 W) with a 5 A e-marked cable; above 100 W (28/36/48 V, ≤ 240 W) needs charger, device AND cable to support PD 3.1 EPR. Without PD on both sides the assumed ceiling is USB-C 5 V / 3 A = 15 W. Expected maximum = minimum of charger, device and that limit.\n- Semver: npm range semantics (^ caret, ~ tilde, x-ranges, hyphen ranges, || alternatives, comparator sets); prereleases only match ranges that mention a prerelease of the same version.\n- PC: sockets must match exactly (case-insensitive); RAM generation must match; modules ≤ slots; recommended PSU = (CPU + GPU + other) × (1 + headroom%).",
        "tags": [
          "high-value"
        ],
        "x-mcp-tool": "compatibility_engine",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompatibilityEngineInput"
              },
              "examples": {
                "example1": {
                  "summary": "140 W laptop on a 100 W charger",
                  "value": {
                    "mode": "charging",
                    "chargerW": 100,
                    "chargerPd": true,
                    "deviceW": 140,
                    "devicePd": true,
                    "deviceEpr": true,
                    "cable": "usb-c-3a"
                  }
                },
                "example2": {
                  "summary": "Node.js engine range",
                  "value": {
                    "mode": "semver",
                    "range": "^18.17.0 || >=20.5.0",
                    "versions": [
                      "18.16.1",
                      "18.20.4",
                      "20.4.0",
                      "20.11.1",
                      "22.0.0-rc.1",
                      "22.1.0"
                    ]
                  }
                },
                "example3": {
                  "summary": "AM5 gaming PC",
                  "value": {
                    "mode": "pc",
                    "cpuSocket": "AM5",
                    "boardSocket": "AM5",
                    "ramType": "DDR5",
                    "boardRamType": "DDR5",
                    "ramModules": 2,
                    "boardSlots": 4,
                    "cpuW": 120,
                    "gpuW": 285,
                    "otherW": 75,
                    "psuW": 650
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompatibilityEngineResult"
                }
              }
            }
          },
          "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/tools/accessibility-fixer/calculate": {
      "post": {
        "operationId": "calculateAccessibilityFixer",
        "summary": "Turn WCAG 2.2 problems in your HTML into concrete code fixes, grouped by effort.",
        "description": "Paste HTML or enter a URL and get a fix list: for every detected accessibility problem the tool shows the offending element, a corrected version generated from it (alt text, labels, lang, names, heading levels, table headers…) and how much work it is. Placeholders that need human judgement are marked TODO, and a patch-style diff is included.\n\nMethodology:\n- Runs the same static rule set as Accessibility Snapshot (WCAG 2.2 mapping verified against the W3C Recommendation).\n- Each fix is generated from the actual element: the original start tag is re-serialised with the needed attribute added, changed or removed (e.g. alt, aria-label, lang, id + <label for>, th scope, tabindex).\n- Text the tool cannot know — what an image shows, what a field means, the page language — is never guessed: it is inserted as a TODO placeholder (lang=\"en\" is only a placeholder).\n- Fixes are grouped by effort: quick = attribute change, moderate = markup change that may affect styling, involved = structural or content work.\n\nAutomated static checks can only detect some failures. They cannot establish WCAG 2.2 conformance: conformance requires a full manual review of every page state (WCAG 2.2 §5.2), including rendered contrast, keyboard operation and assistive-technology testing.",
        "tags": [
          "high-value"
        ],
        "x-mcp-tool": "accessibility_fixer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccessibilityFixerInput"
              },
              "examples": {
                "example1": {
                  "summary": "Checkout form with missing labels and alt text",
                  "value": {
                    "html": "<html>\n<head><title>Shop</title></head>\n<body>\n<header><a href=\"/\"><img src=\"/img/logo.svg\"></a></header>\n<main>\n<h1>Checkout</h1>\n<h4>Delivery address</h4>\n<form action=\"/pay\">\n  <input type=\"text\" name=\"fullname\" placeholder=\"Full name\">\n  <select name=\"country\"><option>Germany</option><option>France</option></select>\n  <button type=\"submit\"><i class=\"icon-arrow\"></i></button>\n</form>\n<img src=\"/img/IMG_2041.jpg\" alt=\"IMG_2041.jpg\">\n</main>\n</body>\n</html>",
                    "includeBestPractice": true,
                    "maxFixes": 80
                  }
                },
                "example2": {
                  "summary": "Pricing table, autoplay video and fake button",
                  "value": {
                    "html": "<!doctype html><html lang=\"de\"><head><title>Preise</title></head><body><main id=\"main\">\n<h1>Preise</h1>\n<table><tr><td>Tarif</td><td>Preis</td></tr><tr><td>Basis</td><td>9 €</td></tr><tr><td>Pro</td><td>19 €</td></tr></table>\n<video src=\"/promo.mp4\" autoplay></video>\n<div role=\"button\" class=\"buy\">Jetzt kaufen</div>\n</main></body></html>",
                    "includeBestPractice": false,
                    "maxFixes": 40
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessibilityFixerResult"
                }
              }
            }
          },
          "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/tools/screenshot-to-steps/calculate": {
      "post": {
        "operationId": "calculateScreenshotToSteps",
        "summary": "Turn a screenshot of an app or website into numbered steps for what you want to do.",
        "description": "Upload a screenshot (or paste the visible labels) and say what you want to achieve. The text on screen is read with OCR, each label is classified as button, input field, navigation, link, checkbox or heading with its position, and the elements relevant to your goal are turned into numbered instructions.\n\nMethodology:\n- OCR: tesseract (English) with word positions; words with confidence below 30 are dropped; words on one line are split into separate elements at gaps wider than 1.8× the text height.\n- Roles are assigned by rules: known action words → button; trailing colon or known field names → input field; short labels in the top 12% or known section names → navigation; URLs/\"forgot…\" → link; ☐/[ ] → checkbox; text 1.5× taller than median → heading.\n- Your goal is split into keywords and expanded with synonyms (e.g. password → security, login). Steps: open the best-matching navigation item (if no matching field is visible), fill the input fields that match the goal (all visible fields only when none matches and no matching navigation item exists, e.g. a login form), tick relevant checkboxes, then click the primary button (Save/Continue/OK…). Other fields are listed as not needed.\n- Position is reported as a 3×3 grid region (top/middle/bottom × left/center/right).\n\nSteps are derived only from text visible in the screenshot; icons without labels and hidden menus cannot be seen. Never upload screenshots that show passwords or card numbers.",
        "tags": [
          "internet"
        ],
        "x-mcp-tool": "screenshot_to_steps",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScreenshotToStepsInput"
              },
              "examples": {
                "example1": {
                  "summary": "Change password (labels pasted)",
                  "value": {
                    "goal": "Change my password",
                    "uiText": "Account settings\nProfile\nSecurity\nNotifications\nCurrent password:\nNew password:\nConfirm password:\n[ ] Sign out of all other devices\nCancel\nSave"
                  }
                },
                "example2": {
                  "summary": "Find the settings",
                  "value": {
                    "goal": "turn off notifications",
                    "uiText": "Home\nSearch\nNotifications\nMessages\nSettings\nWhat is happening?\nPost"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreenshotToStepsResult"
                }
              }
            }
          },
          "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/tools/file-format-doctor/calculate": {
      "post": {
        "operationId": "calculateFileFormatDoctor",
        "summary": "Find out what a file really is from its bytes, why it will not open and how to convert it.",
        "description": "Upload a file (or paste its first bytes as hex) and the doctor reads its magic number against a table of 74 formats, looks inside ZIP containers (DOCX, XLSX, ODT, EPUB, JAR, APK), and diagnoses wrong extensions, truncated or encrypted files, text encoding problems and disguised executables — with offline conversion commands.\n\nMethodology:\n- Magic numbers are matched at their documented offsets for 74 formats (e.g. \"%PDF-\" at 0, \"ustar\" at 257, \"CD001\" at 0x8001, \"ftyp\" brands at 4).\n- ISO-BMFF files are told apart by their ftyp brands (heic/heix → HEIC, mif1 → HEIF, avif → AVIF, qt → QuickTime, M4A → audio, isom/mp42 → MP4).\n- ZIP files are opened by reading the central directory (or local file headers in a sample): [Content_Types].xml + word/ → DOCX, xl/ → XLSX, ppt/ → PPTX, the stored \"mimetype\" entry → ODT/ODS/ODP/EPUB, AndroidManifest.xml → APK, META-INF/MANIFEST.MF → JAR. General-purpose bit 0 marks encrypted entries.\n- Without a binary signature the bytes are checked for BOMs, UTF-16 patterns, strict UTF-8 validity and typical mojibake sequences (e.g. \"Ã©\", \"â€™\"), then for SVG/HTML/XML/JSON/CSV structure.\n- Truncation checks (uploads only): PDF must end with %%EOF, PNG with IEND, JPEG with FF D9, GIF with 3B, ZIP must have an end-of-central-directory record, RIFF/BMP declared sizes must fit.\n- Conversion suggestions use free, offline tools (LibreOffice, ImageMagick, FFmpeg, 7-Zip, iconv) with the exact command for your file name.\n\nDetection reads bytes only; it does not scan for malware. Never run an executable you did not expect to receive.",
        "tags": [
          "internet"
        ],
        "x-mcp-tool": "file_format_doctor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileFormatDoctorInput"
              },
              "examples": {
                "example1": {
                  "summary": "iPhone photo renamed to .jpg (HEIC inside)",
                  "value": {
                    "filename": "IMG_0420.jpg",
                    "hexBytes": "00 00 00 18 66 74 79 70 68 65 69 63 00 00 00 00 6d 69 66 31 68 65 69 63"
                  }
                },
                "example2": {
                  "summary": "Invoice that is really a Windows program",
                  "value": {
                    "filename": "invoice_2026.pdf.exe",
                    "hexBytes": "4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00"
                  }
                },
                "example3": {
                  "summary": "Word document (ZIP local header with word/ entry)",
                  "value": {
                    "filename": "contract.zip",
                    "hexBytes": "50 4B 03 04 14 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 00 00 00 77 6F 72 64 2F 64 6F 63 75 6D 65 6E 74 2E 78 6D 6C"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileFormatDoctorResult"
                }
              }
            }
          },
          "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/tools/citeshape/calculate": {
      "post": {
        "operationId": "calculateCiteshape",
        "summary": "Paste a DOI, ORCID iD, ISBN or arXiv ID: validated, resolved, and formatted as APA, BibTeX and RIS.",
        "description": "CiteShape finds the identifier in whatever you paste (URL, \"doi:\", reference text), normalises it, validates check digits (ORCID ISO 7064, ISBN-10/13), resolves authoritative metadata from Crossref, ORCID and arXiv, and emits APA-style, BibTeX and RIS citations. Retrieved facts are kept separate from your input, and nothing missing is guessed.\n\nMethodology:\n- Detection order: DOI (10.prefix/suffix, also in doi.org URLs) → ORCID iD → arXiv ID → ISBN. DOIs are lower-cased (DOIs are case-insensitive).\n- ORCID: ISO 7064 MOD 11-2 check digit. ISBN-10: weighted sum mod 11; ISBN-13: alternating 1/3 weights mod 10. ISBN-10 is converted to ISBN-13 with prefix 978.\n- Resolution: DOI → api.crossref.org/works/{doi}; ORCID → pub.orcid.org/v3.0/{id}/record (JSON); arXiv → export.arxiv.org/api/query. ISBN metadata is not resolved (no open authoritative registry).\n- Citations are generated only from retrieved metadata; APA output follows APA 7 reference structure for author list, year, title, container, volume(issue), pages and DOI link.",
        "tags": [
          "developer"
        ],
        "x-mcp-tool": "citeshape",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CiteshapeInput"
              },
              "examples": {
                "example1": {
                  "summary": "ORCID check digit (offline)",
                  "value": {
                    "identifier": "https://orcid.org/0000-0002-1825-0097",
                    "resolve": false
                  }
                },
                "example2": {
                  "summary": "ISBN-10 → ISBN-13 (offline)",
                  "value": {
                    "identifier": "ISBN 0-306-40615-2",
                    "resolve": false
                  }
                },
                "example3": {
                  "summary": "Invalid ORCID (offline)",
                  "value": {
                    "identifier": "0000-0002-1825-0098",
                    "resolve": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CiteshapeResult"
                }
              }
            }
          },
          "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/tools/safe-markdown-preview/calculate": {
      "post": {
        "operationId": "calculateSafeMarkdownPreview",
        "summary": "Render Markdown with GFM tables and footnotes to sanitised HTML and see what was removed.",
        "description": "Renders Markdown with headings, emphasis, lists, task lists, code, GFM tables, links, images, blockquotes and footnotes into HTML built from a strict allow-list. Raw HTML can be escaped, stripped or sanitised; scripts, event handlers, style attributes and javascript:/vbscript:/data: URLs are removed and listed in a security report. Shows a preview, the sanitised HTML source and a plain-text version.\n\nMethodology:\n- A two-pass parser written for this tool: link-reference and footnote definitions are collected first, then blocks (ATX/setext headings, fenced and indented code, blockquotes, nested bullet/ordered lists with task items, GFM tables with alignment, thematic breaks, HTML blocks, paragraphs) and inline syntax (code spans, emphasis, strikethrough, links, images, autolinks, hard breaks, backslash escapes). It follows CommonMark closely but is not a full conformance implementation; rare edge cases (complex emphasis nesting, lazy continuation inside nested lists) can differ.\n- All output HTML is generated by the renderer from an allow-list (p, h1–h6, lists, tables, code, a, img, blockquote, …). Text and attribute values are always escaped. Raw HTML is escaped, stripped or passed through a tokenizer that rebuilds only allow-listed tags with allow-listed attributes; script/style/iframe/object/svg and similar elements are removed with their content; on* handlers, style, id and class attributes are dropped.\n- URLs (Markdown links, images, href/src attributes) are decoded (entities, escapes) and stripped of control and whitespace characters before the scheme check, so obfuscations like “java&#x09;script:” are caught. Allowed: http, https, mailto, tel and relative URLs; data: only for base64 raster images when enabled. Links get rel=\"nofollow noopener noreferrer\".\n- Finally the HTML is balanced (stray closing tags dropped, open tags closed) so raw HTML cannot break out of the preview container. The page’s Content-Security-Policy blocks scripts and external images anyway; the preview is rendered in the browser from the sanitised HTML only.",
        "tags": [
          "developer"
        ],
        "x-mcp-tool": "safe_markdown_preview",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SafeMarkdownPreviewInput"
              },
              "examples": {
                "example1": {
                  "summary": "Release notes with table, tasks and footnote",
                  "value": {
                    "markdown": "# Release notes\n\nVersion **2.4** brings _faster_ parsing, `inline code` and ~~old bugs~~ fixes.[^perf]\n\n- [x] Tables (GFM)\n- [ ] Footnotes\n- Links: [docs](https://example.com/docs \"Documentation\") and <https://usefulweb.site>\n\n| Feature | Status | Notes |\n|:--------|:------:|------:|\n| Tables  | ✓      | GFM   |\n| Images  | ✓      | allow-listed |\n\n> Quote with a [reference link][ref].\n\n```js\nconsole.log(\"code is escaped: <b>\");\n```\n\n[ref]: https://commonmark.org/\n[^perf]: Measured on a 1 MB document.\n"
                  }
                },
                "example2": {
                  "summary": "XSS attempts are removed and reported",
                  "value": {
                    "markdown": "# Hello <img src=x onerror=alert(1)>\n\n<script>alert('xss')</script>\n\nClick [me](javascript:alert(document.cookie)) or [this](JaVaScRiPt&#58;alert(1)) or ![pixel](data:image/svg+xml;base64,PHN2Zz4=).\n\n<div onclick=\"steal()\" style=\"position:fixed\">A <b>bold</b> div with <a href=\"vbscript:msgbox(1)\">a link</a></div>\n\n<iframe src=\"https://evil.example\"></iframe>\n\n<a href=\"https://example.com\" onmouseover=\"x()\">safe link, unsafe handler</a>\n"
                  }
                },
                "example3": {
                  "summary": "Same input with raw HTML escaped",
                  "value": {
                    "markdown": "# Hello <img src=x onerror=alert(1)>\n\n<script>alert('xss')</script>\n\nClick [me](javascript:alert(document.cookie)) or [this](JaVaScRiPt&#58;alert(1)) or ![pixel](data:image/svg+xml;base64,PHN2Zz4=).\n\n<div onclick=\"steal()\" style=\"position:fixed\">A <b>bold</b> div with <a href=\"vbscript:msgbox(1)\">a link</a></div>\n\n<iframe src=\"https://evil.example\"></iframe>\n\n<a href=\"https://example.com\" onmouseover=\"x()\">safe link, unsafe handler</a>\n",
                    "rawHtml": "escape"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SafeMarkdownPreviewResult"
                }
              }
            }
          },
          "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/workflows": {
      "get": {
        "operationId": "listWorkflows",
        "summary": "Multi-tool workflows",
        "responses": {
          "200": {
            "description": "Workflow list.",
            "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"
                }
              }
            }
          }
        }
      },
      "PaperwellNoticeDeadlinesInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "title": {
            "title": "Contract name",
            "type": "string",
            "maxLength": 160
          },
          "startDate": {
            "title": "Start date of the contract",
            "type": "string",
            "format": "date"
          },
          "anchor": {
            "title": "Kind of contract",
            "type": "string",
            "enum": [
              "term-end",
              "any-time",
              "month-end",
              "quarter-end",
              "year-end"
            ],
            "default": "term-end"
          },
          "termValue": {
            "title": "Initial (minimum) term",
            "description": "Required for fixed terms. For open-ended contracts an optional minimum term.",
            "type": "integer",
            "minimum": 1,
            "maximum": 600
          },
          "termUnit": {
            "title": "Unit of the initial term",
            "type": "string",
            "enum": [
              "day",
              "business-day",
              "week",
              "month",
              "year"
            ],
            "default": "month"
          },
          "renewalValue": {
            "title": "Automatic renewal period",
            "description": "Empty = the contract ends after the initial term.",
            "type": "integer",
            "minimum": 1,
            "maximum": 600
          },
          "renewalUnit": {
            "title": "Unit of the renewal period",
            "type": "string",
            "enum": [
              "day",
              "business-day",
              "week",
              "month",
              "year"
            ],
            "default": "month"
          },
          "noticeValue": {
            "title": "Notice period",
            "type": "integer",
            "minimum": 1,
            "maximum": 20000
          },
          "noticeUnit": {
            "title": "Unit of the notice period",
            "type": "string",
            "enum": [
              "day",
              "business-day",
              "week",
              "month",
              "year"
            ],
            "default": "month"
          },
          "asOf": {
            "title": "Reference day (today)",
            "description": "Empty = today.",
            "type": "string",
            "format": "date"
          },
          "cycles": {
            "title": "Terms to list",
            "type": "integer",
            "minimum": 1,
            "maximum": 20,
            "default": 4
          },
          "remind": {
            "title": "Reminders (days before the last notice day)",
            "description": "Comma-separated, e.g. \"30, 7\". Used for the calendar file.",
            "type": "string",
            "maxLength": 40,
            "default": "30, 7"
          }
        },
        "required": [
          "startDate",
          "noticeValue"
        ]
      },
      "PaperwellNoticeDeadlinesResult": {
        "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": [
              "title",
              "anchor",
              "asOf",
              "terms",
              "nextNoticeDay",
              "endsIfNoticeGiven",
              "daysLeft",
              "endsWithoutNotice",
              "messages",
              "ics"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "anchor": {
                "type": "string",
                "enum": [
                  "term-end",
                  "any-time",
                  "month-end",
                  "quarter-end",
                  "year-end"
                ]
              },
              "asOf": {
                "type": "string"
              },
              "terms": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "index",
                    "start",
                    "end",
                    "lastNoticeDay",
                    "renews",
                    "status"
                  ],
                  "properties": {
                    "index": {
                      "type": "integer"
                    },
                    "start": {
                      "type": "string"
                    },
                    "end": {
                      "type": "string"
                    },
                    "lastNoticeDay": {
                      "type": "string"
                    },
                    "renews": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "past",
                        "current",
                        "future"
                      ]
                    }
                  }
                }
              },
              "nextNoticeDay": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "endsIfNoticeGiven": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "daysLeft": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "endsWithoutNotice": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "messages": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "ics": {
                "type": "string",
                "description": "iCalendar file (RFC 5545) with the notice deadlines and reminders."
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "PaperwellPagePlanInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "mode": {
            "title": "Operation",
            "type": "string",
            "enum": [
              "merge",
              "split-every",
              "split-ranges",
              "pages",
              "remove",
              "rotate"
            ],
            "default": "merge"
          },
          "files": {
            "title": "PDFs (name and page count)",
            "type": "array",
            "minItems": 1,
            "maxItems": 25,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "name": {
                  "title": "File name",
                  "type": "string",
                  "maxLength": 160
                },
                "pages": {
                  "title": "Pages",
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 2000
                }
              },
              "required": [
                "name",
                "pages"
              ]
            }
          },
          "order": {
            "title": "Merge order",
            "description": "File numbers, e.g. \"2,1,3\". Files not listed follow in their original order.",
            "type": "string",
            "maxLength": 200
          },
          "pages": {
            "title": "Pages",
            "description": "Page numbers start at 1. Examples: \"1-3,5,8-end\", \"odd\", \"even\", \"reverse\", \"10-1\" (descending), \"1-9:odd\". Leave empty for all pages.",
            "type": "string",
            "maxLength": 2000
          },
          "everyN": {
            "title": "Pages per part (split every N)",
            "type": "integer",
            "minimum": 1,
            "maximum": 2000,
            "default": 1
          },
          "ranges": {
            "title": "Ranges (split by ranges)",
            "description": "One part per range, separated by \";\" or new lines, e.g. \"1-3; 4-end\".",
            "type": "string",
            "maxLength": 4000
          },
          "angle": {
            "title": "Rotation",
            "type": "string",
            "enum": [
              "90",
              "180",
              "270"
            ],
            "default": "90"
          }
        },
        "required": []
      },
      "PaperwellPagePlanResult": {
        "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": [
              "mode",
              "pagesBefore",
              "pagesAfter",
              "outputs",
              "rotated",
              "removed",
              "toolInput",
              "notes"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "merge",
                  "split-every",
                  "split-ranges",
                  "pages",
                  "remove",
                  "rotate"
                ]
              },
              "pagesBefore": {
                "type": "integer"
              },
              "pagesAfter": {
                "type": "integer"
              },
              "outputs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "pages",
                    "sources",
                    "sequence"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "sources": {
                      "type": "string"
                    },
                    "sequence": {
                      "type": "array",
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "integer"
                        },
                        "minItems": 2,
                        "maxItems": 2
                      }
                    }
                  }
                }
              },
              "rotated": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "removed": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "toolInput": {
                "type": "object",
                "description": "Parameters for pdf-merge-split-reorder (add the files as file, file2 … in the same order)."
              },
              "notes": {
                "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"
              }
            }
          }
        }
      },
      "PaperwellDocumentScanInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "title": "Text",
            "description": "Paste text, or upload a file below (exactly one).",
            "type": "string",
            "maxLength": 400000
          },
          "file": {
            "title": "Or upload a file",
            "description": "PDF (text layer), DOCX, HTML, text or a photo/scan (PNG/JPG, read with OCR). Max 10 MiB. Read in memory and not stored. Upload as {filename, contentType?, contentBase64}. Max 10240 KiB. Accepts .txt,.md,.pdf,.docx,.png,.jpg,.jpeg,.html,.htm.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "includeText": {
            "title": "Include the full text in the result",
            "type": "boolean",
            "default": true
          }
        },
        "required": []
      },
      "PaperwellDocumentScanResult": {
        "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": [
              "source",
              "method",
              "stats",
              "pages",
              "identifiers",
              "pii",
              "dates",
              "amounts",
              "periods",
              "redactionTerms",
              "redactionPresets",
              "text",
              "truncated"
            ],
            "properties": {
              "source": {
                "type": "string",
                "enum": [
                  "text",
                  "file"
                ]
              },
              "method": {
                "type": "string",
                "description": "How the text was read: text, pdftotext, tesseract-ocr, docx, html."
              },
              "stats": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "characters",
                  "words",
                  "lines",
                  "pages",
                  "sentences",
                  "readingMinutes"
                ],
                "properties": {
                  "characters": {
                    "type": "integer"
                  },
                  "words": {
                    "type": "integer"
                  },
                  "lines": {
                    "type": "integer"
                  },
                  "pages": {
                    "type": "integer"
                  },
                  "sentences": {
                    "type": "integer"
                  },
                  "readingMinutes": {
                    "type": "integer"
                  }
                }
              },
              "pages": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "page",
                    "characters",
                    "words"
                  ],
                  "properties": {
                    "page": {
                      "type": "integer"
                    },
                    "characters": {
                      "type": "integer"
                    },
                    "words": {
                      "type": "integer"
                    }
                  }
                }
              },
              "identifiers": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "value",
                    "normalized",
                    "valid",
                    "count"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    },
                    "normalized": {
                      "type": "string"
                    },
                    "valid": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "pii": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "value",
                    "count",
                    "valid"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "valid": {
                      "type": [
                        "boolean",
                        "null"
                      ]
                    }
                  }
                }
              },
              "dates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "text",
                    "iso",
                    "count"
                  ],
                  "properties": {
                    "text": {
                      "type": "string"
                    },
                    "iso": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "amounts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "text",
                    "count"
                  ],
                  "properties": {
                    "text": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "periods": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "text",
                    "count"
                  ],
                  "properties": {
                    "text": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                }
              },
              "redactionTerms": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "redactionPresets": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "text": {
                "type": "string",
                "description": "The full plain text (form feeds separate PDF pages); empty when includeText is false."
              },
              "truncated": {
                "type": "boolean"
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "OfficeToPdfConverterInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "Office document",
            "description": "Max 100 MB. Macros are never run. Processed on our server and deleted; the PDF can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .docx,.doc,.odt,.rtf,.pptx,.ppt,.odp,.xlsx,.xls,.ods,.csv,.tsv.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "pdfa": {
            "title": "Create PDF/A-2b (for archiving)",
            "description": "Embeds all fonts and adds archival metadata; files can be slightly larger.",
            "type": "boolean",
            "default": false
          }
        },
        "required": [
          "file"
        ]
      },
      "OfficeToPdfConverterResult": {
        "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": [
              "inputType",
              "inputBytes",
              "pages",
              "outputBytes",
              "pdfa",
              "fonts",
              "artifact"
            ],
            "properties": {
              "inputType": {
                "type": "string",
                "enum": [
                  "docx",
                  "doc",
                  "odt",
                  "rtf",
                  "pptx",
                  "ppt",
                  "odp",
                  "xlsx",
                  "xls",
                  "ods",
                  "csv"
                ]
              },
              "inputBytes": {
                "type": "integer"
              },
              "pages": {
                "type": "integer"
              },
              "outputBytes": {
                "type": "integer"
              },
              "pdfa": {
                "type": "boolean"
              },
              "fonts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "embedded"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "embedded": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "csvSeparator": {
                "type": "string"
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "PdfImageConverterInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "direction": {
            "title": "Conversion",
            "type": "string",
            "enum": [
              "pdf-to-images",
              "images-to-pdf"
            ],
            "default": "pdf-to-images"
          },
          "file": {
            "title": "PDF or image",
            "description": "Max 100 MB in total. Processed on our server and deleted; results can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,.jpg,.jpeg,.png,.tif,.tiff,.gif,.webp,application/pdf,image/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file2": {
            "title": "Image 2 (images to PDF)",
            "description": "Optional additional image. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .jpg,.jpeg,.png,.tif,.tiff,.gif,.webp,image/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file3": {
            "title": "Image 3 (images to PDF)",
            "description": "Optional additional image. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .jpg,.jpeg,.png,.tif,.tiff,.gif,.webp,image/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file4": {
            "title": "Image 4 (images to PDF)",
            "description": "Optional additional image. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .jpg,.jpeg,.png,.tif,.tiff,.gif,.webp,image/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file5": {
            "title": "Image 5 (images to PDF)",
            "description": "Optional additional image. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .jpg,.jpeg,.png,.tif,.tiff,.gif,.webp,image/*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "zip": {
            "title": "ZIP with more images (images to PDF)",
            "description": "Optional: up to 25 images in total, added after the single files in file-name order. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .zip,application/zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "format": {
            "title": "Image format (PDF to images)",
            "type": "string",
            "enum": [
              "png",
              "jpeg"
            ],
            "default": "png"
          },
          "dpi": {
            "title": "Resolution (PDF to images)",
            "description": "72 = screen size, 150 = good for reading, 300 = print quality.",
            "type": "integer",
            "minimum": 72,
            "maximum": 300,
            "default": 150,
            "x-unit": "DPI"
          },
          "pages": {
            "title": "Pages (PDF to images)",
            "description": "Page numbers start at 1. Examples: \"1-3,5,8-end\", \"odd\", \"even\", \"reverse\", \"10-1\" (descending), \"1-9:odd\". Leave empty for all pages. At most 100 pages per run.",
            "type": "string",
            "maxLength": 2000
          },
          "jpegQuality": {
            "title": "JPG quality",
            "type": "integer",
            "minimum": 30,
            "maximum": 100,
            "default": 90
          },
          "pageSize": {
            "title": "Page size (images to PDF)",
            "type": "string",
            "enum": [
              "image",
              "a4",
              "a4-landscape",
              "letter",
              "letter-landscape"
            ],
            "default": "image"
          },
          "fit": {
            "title": "Fit on the page (images to PDF)",
            "type": "string",
            "enum": [
              "into",
              "fill",
              "exact"
            ],
            "default": "into"
          },
          "margin": {
            "title": "Margin (images to PDF, fixed page sizes)",
            "description": "72 pt = 1 inch = 25.4 mm.",
            "type": "number",
            "minimum": 0,
            "maximum": 144,
            "default": 0,
            "x-unit": "pt"
          },
          "order": {
            "title": "Image order",
            "description": "Numbers of the images in the order to use, e.g. \"2,1,3\". Empty = upload order.",
            "type": "string",
            "maxLength": 200
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "PdfImageConverterResult": {
        "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": [
              "direction",
              "inputPages",
              "outputCount",
              "outputBytes",
              "artifact",
              "items"
            ],
            "properties": {
              "direction": {
                "type": "string",
                "enum": [
                  "pdf-to-images",
                  "images-to-pdf"
                ]
              },
              "inputPages": {
                "type": "integer",
                "description": "Pages of the input PDF, or number of input images."
              },
              "outputCount": {
                "type": "integer",
                "description": "Images written, or pages of the new PDF."
              },
              "outputBytes": {
                "type": "integer"
              },
              "format": {
                "type": "string"
              },
              "dpi": {
                "type": "integer"
              },
              "pageSize": {
                "type": "string"
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "width",
                    "height",
                    "bytes"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "width": {
                      "type": "integer"
                    },
                    "height": {
                      "type": "integer"
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "kind": {
                      "type": "string"
                    },
                    "embedding": {
                      "type": "string"
                    }
                  }
                }
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "PdfCompressorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "PDF",
            "description": "Max 100 MB. Processed on our server and deleted; results can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "preset": {
            "title": "Compression level",
            "type": "string",
            "enum": [
              "screen",
              "ebook",
              "printer",
              "prepress",
              "custom"
            ],
            "default": "ebook"
          },
          "compare": {
            "title": "Compare up to three levels (slower)",
            "description": "Also runs the next levels so you can download and compare each.",
            "type": "boolean",
            "default": false
          },
          "imageDpi": {
            "title": "Image resolution (custom)",
            "type": "integer",
            "minimum": 36,
            "maximum": 600,
            "default": 120,
            "x-unit": "DPI"
          },
          "jpegQuality": {
            "title": "JPEG quality (custom)",
            "type": "integer",
            "minimum": 10,
            "maximum": 95,
            "default": 70
          },
          "grayscale": {
            "title": "Convert to grayscale",
            "type": "boolean",
            "default": false
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "PdfCompressorResult": {
        "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": [
              "originalBytes",
              "pages",
              "preset",
              "outputBytes",
              "savingsPercent",
              "keptOriginal",
              "variants",
              "artifact"
            ],
            "properties": {
              "originalBytes": {
                "type": "integer"
              },
              "pages": {
                "type": "integer"
              },
              "preset": {
                "type": "string"
              },
              "outputBytes": {
                "type": "integer"
              },
              "savingsPercent": {
                "type": "number",
                "description": "Positive = smaller than the original."
              },
              "keptOriginal": {
                "type": "boolean",
                "description": "True when compression did not make the file smaller and the original is returned."
              },
              "variants": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "preset",
                    "label",
                    "bytes",
                    "savingsPercent",
                    "keptOriginal",
                    "artifact"
                  ],
                  "properties": {
                    "preset": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "savingsPercent": {
                      "type": "number"
                    },
                    "keptOriginal": {
                      "type": "boolean"
                    },
                    "artifact": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "artifactId",
                        "filename",
                        "mime",
                        "bytes",
                        "sha256",
                        "path"
                      ],
                      "properties": {
                        "artifactId": {
                          "type": "string"
                        },
                        "filename": {
                          "type": "string"
                        },
                        "mime": {
                          "type": "string"
                        },
                        "bytes": {
                          "type": "integer"
                        },
                        "sha256": {
                          "type": "string"
                        },
                        "path": {
                          "type": "string",
                          "description": "Download path on the same site (valid for about 2 hours)."
                        }
                      }
                    }
                  }
                }
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "previewBefore": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "previewAfter": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "PdfFormSignatureStudioInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "PDF",
            "description": "Max 100 MB. Processed on our server and deleted; the result can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "action": {
            "title": "What to do",
            "type": "string",
            "enum": [
              "list",
              "fill",
              "sign",
              "fill-sign"
            ],
            "default": "list"
          },
          "values": {
            "title": "Field values",
            "description": "Field name exactly as listed. Checkboxes: yes/no. Radio buttons and drop-downs: one of the listed options. Multi-select lists: options separated by \";\".",
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "field": {
                  "title": "Field name",
                  "type": "string",
                  "maxLength": 300
                },
                "value": {
                  "title": "Value",
                  "type": "string",
                  "maxLength": 2000
                }
              },
              "required": [
                "field"
              ]
            }
          },
          "valuesText": {
            "title": "More values as text",
            "description": "Optional: one \"field name = value\" per line (useful for long forms).",
            "type": "string",
            "maxLength": 50000
          },
          "flatten": {
            "title": "Flatten the form (values become part of the page and can no longer be edited)",
            "type": "boolean",
            "default": false
          },
          "signatureImage": {
            "title": "Signature image",
            "description": "PNG with a transparent background works best. A white JPG background is made transparent. Max 5 MB. Upload as {filename, contentType?, contentBase64}. Max 5120 KiB. Accepts .png,.jpg,.jpeg,image/png,image/jpeg.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "signatureText": {
            "title": "Or type your name",
            "description": "Rendered in a handwriting-style font when no image is uploaded.",
            "type": "string",
            "maxLength": 60
          },
          "signatureColor": {
            "title": "Ink colour (typed name)",
            "type": "string",
            "enum": [
              "blue",
              "black"
            ],
            "default": "blue"
          },
          "page": {
            "title": "Signature page",
            "type": "integer",
            "minimum": 1,
            "maximum": 100000,
            "default": 1
          },
          "x": {
            "title": "Distance from the left edge",
            "description": "72 pt = 1 inch = 25.4 mm. An A4 page is 595 × 842 pt, US Letter 612 × 792 pt.",
            "type": "number",
            "minimum": 0,
            "maximum": 20000,
            "default": 72,
            "x-unit": "pt"
          },
          "y": {
            "title": "Distance from the top edge",
            "type": "number",
            "minimum": 0,
            "maximum": 20000,
            "default": 700,
            "x-unit": "pt"
          },
          "width": {
            "title": "Signature width",
            "description": "The height follows from the image proportions.",
            "type": "number",
            "minimum": 20,
            "maximum": 2000,
            "default": 180,
            "x-unit": "pt"
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "PdfFormSignatureStudioResult": {
        "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": [
              "action",
              "pages",
              "hasForm",
              "fieldCount",
              "fields",
              "filled",
              "skipped",
              "flattened",
              "isDigitalSignature"
            ],
            "properties": {
              "action": {
                "type": "string",
                "enum": [
                  "list",
                  "fill",
                  "sign",
                  "fill-sign"
                ]
              },
              "pages": {
                "type": "integer"
              },
              "hasForm": {
                "type": "boolean"
              },
              "xfa": {
                "type": "boolean"
              },
              "fieldCount": {
                "type": "integer"
              },
              "fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "type",
                    "value",
                    "options",
                    "page",
                    "readOnly",
                    "required"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    },
                    "options": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "page": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "readOnly": {
                      "type": "boolean"
                    },
                    "required": {
                      "type": "boolean"
                    },
                    "tooltip": {
                      "type": "string"
                    }
                  }
                }
              },
              "filled": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "type",
                    "value"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "value": {
                      "type": "string"
                    }
                  }
                }
              },
              "skipped": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "reason"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              },
              "flattened": {
                "type": "boolean"
              },
              "signature": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "page",
                  "x",
                  "y",
                  "width",
                  "height",
                  "source"
                ],
                "properties": {
                  "page": {
                    "type": "integer"
                  },
                  "x": {
                    "type": "number"
                  },
                  "y": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "image",
                      "typed"
                    ]
                  },
                  "font": {
                    "type": "string"
                  }
                }
              },
              "isDigitalSignature": {
                "type": "boolean",
                "const": false,
                "description": "Always false: the stamp is a visible image, not a cryptographic signature."
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "PdfMergeSplitReorderInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "mode": {
            "title": "What to do",
            "type": "string",
            "enum": [
              "merge",
              "split-every",
              "split-ranges",
              "pages",
              "remove",
              "rotate"
            ],
            "default": "merge"
          },
          "file": {
            "title": "PDF",
            "description": "Max 100 MB in total. Processed on our server and deleted; results can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file2": {
            "title": "PDF 2 (merge only)",
            "description": "Optional additional PDF for merging. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file3": {
            "title": "PDF 3 (merge only)",
            "description": "Optional additional PDF for merging. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file4": {
            "title": "PDF 4 (merge only)",
            "description": "Optional additional PDF for merging. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "file5": {
            "title": "PDF 5 (merge only)",
            "description": "Optional additional PDF for merging. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "zip": {
            "title": "ZIP with more PDFs (merge only)",
            "description": "Optional: up to 25 PDFs in total, added after the single files in file-name order. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .zip,application/zip.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "order": {
            "title": "File order (merge)",
            "description": "Numbers of the files in the order to merge, e.g. \"2,1,3\". Files not listed follow in upload order. Empty = upload order.",
            "type": "string",
            "maxLength": 200
          },
          "pages": {
            "title": "Pages",
            "description": "For select/reorder, remove and rotate. Page numbers start at 1. Examples: \"1-3,5,8-end\", \"odd\", \"even\", \"reverse\", \"10-1\" (descending), \"1-9:odd\". Leave empty for all pages. For select/reorder, repeated pages are duplicated.",
            "type": "string",
            "maxLength": 2000
          },
          "everyN": {
            "title": "Pages per part (split every N pages)",
            "type": "integer",
            "minimum": 1,
            "maximum": 10000,
            "default": 1
          },
          "ranges": {
            "title": "Ranges (split by ranges)",
            "description": "One part per range, separated by \";\" or new lines. Each range uses the page syntax above.",
            "type": "string",
            "maxLength": 4000
          },
          "angle": {
            "title": "Rotation (clockwise)",
            "type": "string",
            "enum": [
              "90",
              "180",
              "270"
            ],
            "default": "90"
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "PdfMergeSplitReorderResult": {
        "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": [
              "mode",
              "inputs",
              "pagesBefore",
              "pagesAfter",
              "outputs",
              "artifact"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "merge",
                  "split-every",
                  "split-ranges",
                  "pages",
                  "remove",
                  "rotate"
                ]
              },
              "inputs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "position",
                    "name",
                    "pages",
                    "bytes",
                    "encrypted"
                  ],
                  "properties": {
                    "position": {
                      "type": "integer"
                    },
                    "name": {
                      "type": "string"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "encrypted": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "pagesBefore": {
                "type": "integer",
                "description": "Total pages of all inputs."
              },
              "pagesAfter": {
                "type": "integer",
                "description": "Total pages of all outputs."
              },
              "pageOrder": {
                "type": "string",
                "description": "Resulting page sequence in range syntax (select/remove/rotate)."
              },
              "rotated": {
                "type": "string"
              },
              "outputs": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "filename",
                    "pages",
                    "bytes",
                    "sourcePages"
                  ],
                  "properties": {
                    "filename": {
                      "type": "string"
                    },
                    "pages": {
                      "type": "integer"
                    },
                    "bytes": {
                      "type": "integer"
                    },
                    "sourcePages": {
                      "type": "string"
                    }
                  }
                }
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "SearchablePdfOcrInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "Scanned PDF or image",
            "description": "Max 100 MB and 60 pages. Processed on our server and deleted; the result can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,.jpg,.jpeg,.png,.tif,.tiff,application/pdf,image/jpeg,image/png,image/tiff.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "languages": {
            "title": "Document languages",
            "description": "Pick every language that appears. Only languages installed on the server can be used; the result lists them.",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "eng",
                "deu",
                "fra",
                "spa",
                "ita",
                "nld",
                "por",
                "pol"
              ]
            },
            "default": [
              "eng"
            ]
          },
          "mode": {
            "title": "Pages that already contain text",
            "type": "string",
            "enum": [
              "skip-text",
              "force-ocr"
            ],
            "default": "skip-text"
          },
          "deskew": {
            "title": "Straighten crooked scans (deskew)",
            "type": "boolean",
            "default": false
          },
          "rotatePages": {
            "title": "Fix sideways or upside-down pages",
            "type": "boolean",
            "default": false
          },
          "pdfa": {
            "title": "Save as PDF/A-2b (archiving)",
            "type": "boolean",
            "default": false
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "SearchablePdfOcrResult": {
        "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": [
              "engine",
              "languages",
              "installedLanguages",
              "pages",
              "pagesOcrd",
              "pagesWithTextBefore",
              "charactersAfter",
              "textSample",
              "outputBytes",
              "pdfa",
              "artifact"
            ],
            "properties": {
              "engine": {
                "type": "string",
                "enum": [
                  "ocrmypdf",
                  "tesseract-fallback"
                ]
              },
              "languages": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "installedLanguages": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "pages": {
                "type": "integer"
              },
              "pagesOcrd": {
                "type": "integer",
                "description": "Pages that went through OCR."
              },
              "pagesWithTextBefore": {
                "type": "integer"
              },
              "charactersAfter": {
                "type": "integer",
                "description": "Non-space characters of extractable text in the result."
              },
              "textSample": {
                "type": "string"
              },
              "outputBytes": {
                "type": "integer"
              },
              "pdfa": {
                "type": "boolean"
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "SecurePdfRedactorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "PDF",
            "description": "Max 100 MB and 500 pages. Processed on our server and deleted; the result can be downloaded for about 2 hours. Upload as {filename, contentType?, contentBase64}. Max 102400 KiB. Accepts .pdf,application/pdf.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "terms": {
            "title": "Words or phrases to redact",
            "description": "One per line, e.g. a name or an account number. Matching ignores upper/lower case unless you turn it on below.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 200
          },
          "patterns": {
            "title": "Regular expressions (advanced)",
            "description": "One JavaScript regular expression per line, e.g. \\bDE\\d{20}\\b.",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 50
          },
          "presets": {
            "title": "Also find",
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "email",
                "phone",
                "iban",
                "card",
                "date"
              ]
            }
          },
          "caseSensitive": {
            "title": "Match upper/lower case exactly",
            "type": "boolean",
            "default": false
          },
          "areas": {
            "title": "Areas to black out",
            "description": "One per line: page (or \"all\"), x, y, width, height, in points from the top-left corner (72 pt = 1 inch) or in % of the page.",
            "type": "string",
            "maxLength": 20000
          },
          "dpi": {
            "title": "Resolution of redacted pages",
            "description": "Redacted pages become images. 150 DPI is readable; 300 DPI is sharper but larger.",
            "type": "integer",
            "minimum": 72,
            "maximum": 300,
            "default": 150,
            "x-unit": "DPI"
          },
          "ocr": {
            "title": "Make redacted pages searchable again (OCR of the remaining text)",
            "type": "boolean",
            "default": true
          },
          "ocrLanguage": {
            "title": "OCR language",
            "type": "string",
            "enum": [
              "eng",
              "deu"
            ],
            "default": "eng"
          },
          "removeAnnotations": {
            "title": "Remove comments, links and form fields from all pages",
            "type": "boolean",
            "default": true
          },
          "password": {
            "title": "PDF password (only if the file is protected)",
            "description": "Used only to open the file for this conversion; it is written to a private temporary file, never to a command line, and deleted with the job.",
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "file"
        ]
      },
      "SecurePdfRedactorResult": {
        "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": [
              "pages",
              "redactedPages",
              "boxes",
              "terms",
              "verified",
              "remainingMatches",
              "ocrApplied",
              "metadataRemoved",
              "outputBytes",
              "artifact"
            ],
            "properties": {
              "pages": {
                "type": "integer"
              },
              "redactedPages": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "boxes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "page",
                    "x",
                    "y",
                    "width",
                    "height",
                    "reason"
                  ],
                  "properties": {
                    "page": {
                      "type": "integer"
                    },
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    },
                    "width": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              },
              "terms": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "term",
                    "matchesBefore",
                    "matchesAfter"
                  ],
                  "properties": {
                    "term": {
                      "type": "string"
                    },
                    "matchesBefore": {
                      "type": "integer"
                    },
                    "matchesAfter": {
                      "type": "integer"
                    }
                  }
                }
              },
              "verified": {
                "type": "boolean",
                "description": "True when no search term or pattern occurs in the text of the output (pdftotext)."
              },
              "remainingMatches": {
                "type": "integer"
              },
              "ocrApplied": {
                "type": "boolean"
              },
              "dpi": {
                "type": "integer"
              },
              "metadataRemoved": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "metadataAfter": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Document-level metadata tags still present according to exiftool (if installed)."
              },
              "outputBytes": {
                "type": "integer"
              },
              "artifact": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              },
              "preview": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "artifactId",
                  "filename",
                  "mime",
                  "bytes",
                  "sha256",
                  "path"
                ],
                "properties": {
                  "artifactId": {
                    "type": "string"
                  },
                  "filename": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "bytes": {
                    "type": "integer"
                  },
                  "sha256": {
                    "type": "string"
                  },
                  "path": {
                    "type": "string",
                    "description": "Download path on the same site (valid for about 2 hours)."
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "FormTranslatorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "title": "Form text",
            "description": "Paste the form text (labels and instructions), or upload a PDF/DOCX/photo below.",
            "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"
              }
            }
          }
        },
        "required": []
      },
      "FormTranslatorResult": {
        "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": [
              "disclaimer",
              "editorialNote",
              "confidence",
              "fields",
              "glossaryHits",
              "documentsNeeded",
              "ibanChecks",
              "glossarySize"
            ],
            "properties": {
              "disclaimer": {
                "type": "string"
              },
              "editorialNote": {
                "type": "string"
              },
              "confidence": {
                "type": "string",
                "const": "pattern-match"
              },
              "glossarySize": {
                "type": "integer",
                "minimum": 0
              },
              "fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "label",
                    "line",
                    "fieldTypes",
                    "hint",
                    "glossaryTerms"
                  ],
                  "properties": {
                    "label": {
                      "type": "string",
                      "description": "Field label exactly as found in the form text."
                    },
                    "line": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "fieldTypes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "hint": {
                      "type": "string",
                      "description": "Editorial fill-in hint."
                    },
                    "glossaryTerms": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "glossaryHits": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "term",
                    "matched",
                    "language",
                    "domain",
                    "explanation",
                    "occurrences"
                  ],
                  "properties": {
                    "term": {
                      "type": "string"
                    },
                    "matched": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "language": {
                      "type": "string",
                      "enum": [
                        "en",
                        "de"
                      ]
                    },
                    "domain": {
                      "type": "string"
                    },
                    "explanation": {
                      "type": "string",
                      "description": "Editorial plain-language explanation."
                    },
                    "hint": {
                      "type": "string"
                    },
                    "occurrences": {
                      "type": "integer",
                      "minimum": 1
                    }
                  }
                }
              },
              "documentsNeeded": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "item",
                    "basis",
                    "rule"
                  ],
                  "properties": {
                    "item": {
                      "type": "string"
                    },
                    "basis": {
                      "type": "string",
                      "enum": [
                        "quoted from form",
                        "commonly requested (glossary)"
                      ]
                    },
                    "rule": {
                      "type": "string"
                    }
                  }
                }
              },
              "ibanChecks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "iban",
                    "checksumValid"
                  ],
                  "properties": {
                    "iban": {
                      "type": "string"
                    },
                    "checksumValid": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "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"
              }
            }
          }
        }
      },
      "BeforeYouSignInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "text": {
            "title": "Contract 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 fetch public terms from a URL",
            "description": "A public http(s) address. The page text is fetched once and analysed.",
            "type": "string",
            "format": "uri"
          }
        },
        "required": []
      },
      "BeforeYouSignResult": {
        "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": [
              "disclaimer",
              "confidence",
              "counts",
              "findings",
              "categoriesFound",
              "notDetected"
            ],
            "properties": {
              "disclaimer": {
                "type": "string"
              },
              "confidence": {
                "type": "string",
                "const": "pattern-match"
              },
              "counts": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "high",
                  "medium",
                  "low",
                  "total",
                  "sentences"
                ],
                "properties": {
                  "high": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "medium": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "low": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "total": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "sentences": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "findings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "category",
                    "label",
                    "severity",
                    "severityRule",
                    "rule",
                    "clause",
                    "parameters",
                    "questions"
                  ],
                  "properties": {
                    "category": {
                      "type": "string",
                      "enum": [
                        "auto-renewal",
                        "notice-period",
                        "minimum-term",
                        "termination-rights",
                        "early-termination-fee",
                        "liability-limitation",
                        "indemnification",
                        "arbitration",
                        "governing-law",
                        "non-compete",
                        "confidentiality",
                        "ip-assignment",
                        "price-changes",
                        "late-payment-interest",
                        "penalties",
                        "personal-guarantee",
                        "exclusivity",
                        "data-sharing",
                        "unilateral-changes"
                      ]
                    },
                    "label": {
                      "type": "string"
                    },
                    "severity": {
                      "type": "string",
                      "enum": [
                        "high",
                        "medium",
                        "low"
                      ]
                    },
                    "severityRule": {
                      "type": "string",
                      "description": "The fixed rule that determined the severity."
                    },
                    "rule": {
                      "type": "string",
                      "description": "Id of the text pattern that matched."
                    },
                    "clause": {
                      "type": "string",
                      "description": "Exact sentence quoted from the contract."
                    },
                    "parameters": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "name",
                          "value"
                        ],
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "value": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "questions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "categoriesFound": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "notDetected": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "Clause categories no pattern matched (they may still exist in other wording)."
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "WhatChangedInThisLawInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "oldText": {
            "title": "Old version (text)",
            "type": "string",
            "maxLength": 400000
          },
          "newText": {
            "title": "New version (text)",
            "type": "string",
            "maxLength": 400000
          },
          "oldUrl": {
            "title": "Or: URL of the old version",
            "description": "Official source (e.g. gesetze-im-internet.de, eur-lex.europa.eu, legislation.gov.uk).",
            "type": "string",
            "format": "uri"
          },
          "newUrl": {
            "title": "Or: URL of the new version",
            "type": "string",
            "format": "uri"
          },
          "citation": {
            "title": "Citation / amending act (optional)",
            "type": "string",
            "maxLength": 500
          },
          "effectiveDate": {
            "title": "Effective date of the new version (optional)",
            "type": "string",
            "format": "date"
          }
        },
        "required": []
      },
      "WhatChangedInThisLawResult": {
        "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": [
              "citation",
              "effectiveDate",
              "sectionsBefore",
              "sectionsAfter",
              "counts",
              "changes",
              "sources"
            ],
            "properties": {
              "citation": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "effectiveDate": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "sectionsBefore": {
                "type": "integer"
              },
              "sectionsAfter": {
                "type": "integer"
              },
              "counts": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "added",
                  "removed",
                  "modified",
                  "headingOnly"
                ],
                "properties": {
                  "added": {
                    "type": "integer"
                  },
                  "removed": {
                    "type": "integer"
                  },
                  "modified": {
                    "type": "integer"
                  },
                  "headingOnly": {
                    "type": "integer"
                  }
                }
              },
              "sources": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "side",
                    "label",
                    "fetchedAt"
                  ],
                  "properties": {
                    "side": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "fetchedAt": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "changes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "section",
                    "heading",
                    "before",
                    "after",
                    "wordDiff",
                    "similarity",
                    "numbersChanged",
                    "durationsChanged",
                    "modalChanged"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "section-added",
                        "section-removed",
                        "section-modified",
                        "heading-changed"
                      ]
                    },
                    "section": {
                      "type": "string"
                    },
                    "heading": {
                      "type": "string"
                    },
                    "before": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "after": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "wordDiff": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "kept [-removed-] {+added+}"
                    },
                    "similarity": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "numbersChanged": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "removed",
                        "added"
                      ],
                      "properties": {
                        "removed": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "added": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "durationsChanged": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "removed",
                        "added"
                      ],
                      "properties": {
                        "removed": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "added": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "modalChanged": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "removed",
                        "added"
                      ],
                      "properties": {
                        "removed": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "added": {
                          "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"
              }
            }
          }
        }
      },
      "CompatibilityEngineInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "mode": {
            "title": "What do you want to check?",
            "type": "string",
            "enum": [
              "charging",
              "semver",
              "pc"
            ],
            "default": "charging"
          },
          "chargerW": {
            "title": "Charger maximum output",
            "description": "Charging mode.",
            "type": "number",
            "minimum": 1,
            "maximum": 1000,
            "x-unit": "W"
          },
          "chargerPd": {
            "title": "Charger supports USB Power Delivery (USB PD)",
            "type": "boolean",
            "default": true
          },
          "chargerEpr": {
            "title": "Charger supports PD 3.1 EPR (above 100 W)",
            "type": "boolean",
            "default": false
          },
          "deviceW": {
            "title": "Device maximum charging input",
            "type": "number",
            "minimum": 1,
            "maximum": 1000,
            "x-unit": "W"
          },
          "devicePd": {
            "title": "Device charges via USB PD",
            "type": "boolean",
            "default": true
          },
          "deviceEpr": {
            "title": "Device supports PD 3.1 EPR",
            "type": "boolean",
            "default": false
          },
          "cable": {
            "title": "USB-C cable",
            "type": "string",
            "enum": [
              "usb-c-3a",
              "usb-c-5a",
              "usb-c-epr"
            ],
            "default": "usb-c-3a"
          },
          "range": {
            "title": "Required version range",
            "description": "Semver mode. npm syntax.",
            "type": "string"
          },
          "versions": {
            "title": "Installed / candidate versions (one per line)",
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 50
          },
          "cpuSocket": {
            "title": "CPU socket",
            "description": "PC mode.",
            "type": "string"
          },
          "boardSocket": {
            "title": "Motherboard socket",
            "type": "string"
          },
          "ramType": {
            "title": "RAM type",
            "type": "string",
            "enum": [
              "DDR3",
              "DDR4",
              "DDR5"
            ],
            "default": "DDR5"
          },
          "boardRamType": {
            "title": "Motherboard RAM type",
            "type": "string",
            "enum": [
              "DDR3",
              "DDR4",
              "DDR5"
            ],
            "default": "DDR5"
          },
          "ramModules": {
            "title": "RAM modules",
            "type": "integer",
            "minimum": 1,
            "maximum": 16
          },
          "boardSlots": {
            "title": "Motherboard RAM slots",
            "type": "integer",
            "minimum": 1,
            "maximum": 16
          },
          "cpuW": {
            "title": "CPU power (TDP/PPT)",
            "type": "number",
            "minimum": 0,
            "maximum": 1000,
            "x-unit": "W"
          },
          "gpuW": {
            "title": "Graphics card power",
            "type": "number",
            "minimum": 0,
            "maximum": 2000,
            "x-unit": "W"
          },
          "otherW": {
            "title": "Everything else",
            "type": "number",
            "minimum": 0,
            "maximum": 1000,
            "default": 75,
            "x-unit": "W"
          },
          "psuW": {
            "title": "Power supply rating",
            "type": "number",
            "minimum": 100,
            "maximum": 3000,
            "x-unit": "W"
          },
          "headroomPercent": {
            "title": "Desired PSU headroom",
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 30,
            "x-unit": "%"
          }
        },
        "required": []
      },
      "CompatibilityEngineResult": {
        "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": [
              "mode",
              "compatible",
              "checks"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "charging",
                  "semver",
                  "pc"
                ]
              },
              "compatible": {
                "type": "boolean"
              },
              "checks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "check",
                    "pass",
                    "detail"
                  ],
                  "properties": {
                    "check": {
                      "type": "string"
                    },
                    "pass": {
                      "type": "boolean"
                    },
                    "detail": {
                      "type": "string"
                    },
                    "marginW": {
                      "type": "number"
                    }
                  }
                }
              },
              "charging": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "expectedMaxW",
                  "bottleneck",
                  "usbPd",
                  "epr",
                  "limits"
                ],
                "properties": {
                  "expectedMaxW": {
                    "type": "number"
                  },
                  "bottleneck": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "usbPd": {
                    "type": "boolean"
                  },
                  "epr": {
                    "type": "boolean"
                  },
                  "limits": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "part",
                        "watts"
                      ],
                      "properties": {
                        "part": {
                          "type": "string"
                        },
                        "watts": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              },
              "semver": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "range",
                  "results",
                  "highestSatisfying"
                ],
                "properties": {
                  "range": {
                    "type": "string"
                  },
                  "highestSatisfying": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "results": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "satisfies"
                      ],
                      "properties": {
                        "version": {
                          "type": "string"
                        },
                        "satisfies": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              },
              "pc": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "estimatedLoadW",
                  "recommendedPsuW"
                ],
                "properties": {
                  "estimatedLoadW": {
                    "type": "number"
                  },
                  "recommendedPsuW": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "AccessibilityFixerInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "title": "Page URL",
            "description": "Static HTML only; JavaScript is not executed.",
            "type": "string",
            "format": "uri"
          },
          "html": {
            "title": "Or paste HTML",
            "description": "Takes precedence over the URL.",
            "type": "string",
            "maxLength": 500000
          },
          "includeBestPractice": {
            "title": "Include best-practice and review items",
            "type": "boolean",
            "default": true
          },
          "maxFixes": {
            "title": "Max fixes",
            "type": "integer",
            "minimum": 5,
            "maximum": 300,
            "default": 80
          }
        },
        "required": []
      },
      "AccessibilityFixerResult": {
        "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": [
              "origin",
              "totalFixes",
              "byEffort",
              "needsHumanInput",
              "fixes",
              "truncated",
              "patch",
              "conformanceStatement"
            ],
            "properties": {
              "origin": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "truncated"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "url",
                      "pasted"
                    ]
                  },
                  "requestedUrl": {
                    "type": "string"
                  },
                  "finalUrl": {
                    "type": "string"
                  },
                  "status": {
                    "type": "integer"
                  },
                  "contentType": {
                    "type": "string"
                  },
                  "fetchedAt": {
                    "type": "string"
                  },
                  "truncated": {
                    "type": "boolean"
                  }
                }
              },
              "totalFixes": {
                "type": "integer"
              },
              "byEffort": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "quick",
                  "moderate",
                  "involved"
                ],
                "properties": {
                  "quick": {
                    "type": "integer"
                  },
                  "moderate": {
                    "type": "integer"
                  },
                  "involved": {
                    "type": "integer"
                  }
                }
              },
              "needsHumanInput": {
                "type": "integer",
                "description": "Fixes that contain TODO placeholders (e.g. alt text, label wording, language code)."
              },
              "fixes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "ruleId",
                    "wcag",
                    "kind",
                    "severity",
                    "effort",
                    "line",
                    "selector",
                    "problem",
                    "description",
                    "before",
                    "after",
                    "needsHumanInput"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "ruleId": {
                      "type": "string"
                    },
                    "wcag": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "failure",
                        "best-practice",
                        "needs-review"
                      ]
                    },
                    "severity": {
                      "type": "string",
                      "enum": [
                        "critical",
                        "serious",
                        "moderate",
                        "minor"
                      ]
                    },
                    "effort": {
                      "type": "string",
                      "enum": [
                        "quick",
                        "moderate",
                        "involved"
                      ]
                    },
                    "line": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "selector": {
                      "type": "string"
                    },
                    "problem": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "before": {
                      "type": "string"
                    },
                    "after": {
                      "type": "string"
                    },
                    "needsHumanInput": {
                      "type": "boolean"
                    }
                  }
                }
              },
              "truncated": {
                "type": "boolean"
              },
              "patch": {
                "type": "string",
                "description": "Unified-diff style suggestion list keyed by source line."
              },
              "conformanceStatement": {
                "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"
              }
            }
          }
        }
      },
      "ScreenshotToStepsInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "goal": {
            "title": "What do you want to do?",
            "type": "string",
            "maxLength": 300
          },
          "file": {
            "title": "Screenshot",
            "description": "PNG or JPG, max 5 MiB. Read with OCR on our server; not stored. Upload as {filename, contentType?, contentBase64}. Max 5120 KiB. Accepts .png,.jpg,.jpeg.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "uiText": {
            "title": "Or: visible labels, one per line (top to bottom)",
            "type": "string",
            "maxLength": 20000
          }
        },
        "required": [
          "goal"
        ]
      },
      "ScreenshotToStepsResult": {
        "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": [
              "goal",
              "method",
              "matchedGoal",
              "goalTerms",
              "steps",
              "elements"
            ],
            "properties": {
              "goal": {
                "type": "string"
              },
              "method": {
                "type": "string",
                "enum": [
                  "tesseract-ocr",
                  "pasted-labels"
                ]
              },
              "matchedGoal": {
                "type": "boolean"
              },
              "goalTerms": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "steps": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "n",
                    "action",
                    "elementId"
                  ],
                  "properties": {
                    "n": {
                      "type": "integer"
                    },
                    "action": {
                      "type": "string"
                    },
                    "elementId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              },
              "elements": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "text",
                    "role",
                    "region",
                    "box",
                    "confidence"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "text": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "button",
                        "field",
                        "navigation",
                        "heading",
                        "link",
                        "checkbox",
                        "text"
                      ]
                    },
                    "region": {
                      "type": "string"
                    },
                    "box": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": false,
                      "required": [
                        "left",
                        "top",
                        "width",
                        "height"
                      ],
                      "properties": {
                        "left": {
                          "type": "number"
                        },
                        "top": {
                          "type": "number"
                        },
                        "width": {
                          "type": "number"
                        },
                        "height": {
                          "type": "number"
                        }
                      }
                    },
                    "confidence": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "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"
              }
            }
          }
        }
      },
      "FileFormatDoctorInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "file": {
            "title": "File",
            "description": "Analysed in memory and not stored. Max 10 MiB. Upload as {filename, contentType?, contentBase64}. Max 10240 KiB. Accepts */*.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "filename": {
            "title": "File name (for hex input)",
            "description": "Used to compare the extension with the detected format. Ignored when a file is uploaded.",
            "type": "string",
            "maxLength": 255
          },
          "hexBytes": {
            "title": "Or: first bytes as hex",
            "description": "E.g. from `xxd -l 512 file` or `Format-Hex`. At least 16 bytes recommended; 512+ for ZIP-based formats.",
            "type": "string",
            "maxLength": 140000
          }
        },
        "required": []
      },
      "FileFormatDoctorResult": {
        "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": [
              "input",
              "detected",
              "alternatives",
              "extensionMatches",
              "encrypted",
              "executable",
              "container",
              "text",
              "diagnoses",
              "conversions"
            ],
            "properties": {
              "input": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "mode",
                  "filename",
                  "extension",
                  "bytesAnalyzed",
                  "completeFile"
                ],
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "upload",
                      "hex"
                    ]
                  },
                  "filename": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "extension": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "bytesAnalyzed": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "completeFile": {
                    "type": "boolean",
                    "description": "True for uploads (truncation checks possible); false for hex samples."
                  }
                }
              },
              "detected": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "id",
                  "name",
                  "mime",
                  "category",
                  "extensions",
                  "confidence",
                  "evidence"
                ],
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "mime": {
                    "type": "string"
                  },
                  "category": {
                    "type": "string"
                  },
                  "extensions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "confidence": {
                    "type": "string",
                    "enum": [
                      "high",
                      "medium",
                      "low"
                    ]
                  },
                  "evidence": {
                    "type": "string"
                  }
                }
              },
              "alternatives": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "name",
                    "evidence"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "evidence": {
                      "type": "string"
                    }
                  }
                }
              },
              "extensionMatches": {
                "type": [
                  "boolean",
                  "null"
                ]
              },
              "encrypted": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "null = cannot be determined from the bytes provided."
              },
              "executable": {
                "type": "boolean"
              },
              "container": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "entries",
                  "sampleEntries",
                  "encryptedEntries",
                  "hasEndRecord",
                  "mimetype"
                ],
                "properties": {
                  "entries": {
                    "type": "integer"
                  },
                  "sampleEntries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 20
                  },
                  "encryptedEntries": {
                    "type": "integer"
                  },
                  "hasEndRecord": {
                    "type": "boolean"
                  },
                  "mimetype": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "text": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "encoding",
                  "bom",
                  "mojibake"
                ],
                "properties": {
                  "encoding": {
                    "type": "string"
                  },
                  "bom": {
                    "type": "boolean"
                  },
                  "mojibake": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              },
              "diagnoses": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "severity",
                    "message",
                    "evidence"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "severity": {
                      "type": "string",
                      "enum": [
                        "critical",
                        "warning",
                        "info",
                        "ok"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "evidence": {
                      "type": "string"
                    }
                  }
                }
              },
              "conversions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "goal",
                    "tool",
                    "command",
                    "note"
                  ],
                  "properties": {
                    "goal": {
                      "type": "string"
                    },
                    "tool": {
                      "type": "string"
                    },
                    "command": {
                      "type": "string"
                    },
                    "note": {
                      "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"
              }
            }
          }
        }
      },
      "CiteshapeInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "identifier": {
            "title": "DOI, ORCID iD, ISBN or arXiv ID",
            "type": "string",
            "maxLength": 500
          },
          "resolve": {
            "title": "Look up metadata online (Crossref / ORCID / arXiv)",
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "identifier"
        ]
      },
      "CiteshapeResult": {
        "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": [
              "kind",
              "id",
              "valid",
              "problem",
              "canonicalUrl",
              "resolved",
              "resolver",
              "work",
              "person",
              "citations"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "doi",
                  "orcid",
                  "isbn",
                  "arxiv"
                ]
              },
              "id": {
                "type": "string"
              },
              "valid": {
                "type": "boolean"
              },
              "problem": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "canonicalUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "resolved": {
                "type": "boolean"
              },
              "resolver": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "work": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "type",
                  "title",
                  "authors",
                  "container",
                  "publisher",
                  "year",
                  "month",
                  "day",
                  "volume",
                  "issue",
                  "pages",
                  "doi",
                  "url"
                ],
                "properties": {
                  "type": {
                    "type": "string"
                  },
                  "title": {
                    "type": "string"
                  },
                  "authors": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "given",
                        "family",
                        "orcid"
                      ],
                      "properties": {
                        "given": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "family": {
                          "type": "string"
                        },
                        "orcid": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  },
                  "container": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "publisher": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "year": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "month": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "day": {
                    "type": [
                      "integer",
                      "null"
                    ]
                  },
                  "volume": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "issue": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "pages": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "doi": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "url": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "person": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "name",
                  "works"
                ],
                "properties": {
                  "name": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "works": {
                    "type": "integer"
                  }
                }
              },
              "citations": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "apa",
                  "bibtex",
                  "ris"
                ],
                "properties": {
                  "apa": {
                    "type": "string"
                  },
                  "bibtex": {
                    "type": "string"
                  },
                  "ris": {
                    "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"
              }
            }
          }
        }
      },
      "SafeMarkdownPreviewInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "markdown": {
            "title": "Markdown",
            "type": "string",
            "maxLength": 1000000
          },
          "file": {
            "title": "Or upload a Markdown file",
            "type": "object",
            "description": "Upload as {filename, contentType?, contentBase64}. Max 977 KiB. Accepts .md,.markdown,.txt,text/markdown,text/plain.",
            "additionalProperties": false,
            "required": [
              "filename",
              "contentBase64"
            ],
            "properties": {
              "filename": {
                "type": "string"
              },
              "contentType": {
                "type": "string"
              },
              "contentBase64": {
                "type": "string"
              }
            }
          },
          "rawHtml": {
            "title": "Raw HTML in the Markdown",
            "type": "string",
            "enum": [
              "sanitize",
              "escape",
              "strip"
            ],
            "default": "sanitize"
          },
          "gfm": {
            "title": "GitHub extensions (tables, task lists, strikethrough, bare URLs)",
            "type": "boolean",
            "default": true
          },
          "footnotes": {
            "title": "Footnotes ([^1])",
            "type": "boolean",
            "default": true
          },
          "allowDataImages": {
            "title": "Allow base64 data: images (PNG/JPEG/GIF/WebP/AVIF; never SVG)",
            "type": "boolean",
            "default": false
          }
        },
        "required": []
      },
      "SafeMarkdownPreviewResult": {
        "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": [
              "html",
              "text",
              "removed",
              "removedCounts",
              "stats",
              "toc",
              "policy"
            ],
            "properties": {
              "html": {
                "type": "string",
                "description": "Sanitised HTML (allow-listed elements and attributes only)"
              },
              "text": {
                "type": "string"
              },
              "removed": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "detail"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              },
              "removedCounts": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "stats": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                }
              },
              "toc": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "level",
                    "text",
                    "id"
                  ],
                  "properties": {
                    "level": {
                      "type": "integer"
                    },
                    "text": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string"
                    }
                  }
                }
              },
              "policy": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "rawHtml",
                  "gfm",
                  "footnotes",
                  "allowDataImages",
                  "allowedTags"
                ],
                "properties": {
                  "rawHtml": {
                    "type": "string"
                  },
                  "gfm": {
                    "type": "boolean"
                  },
                  "footnotes": {
                    "type": "boolean"
                  },
                  "allowDataImages": {
                    "type": "boolean"
                  },
                  "allowedTags": {
                    "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"
              }
            }
          }
        }
      }
    }
  }
}