{
  "openapi": "3.1.1",
  "info": {
    "title": "PDF & documents 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://documents.usefulweb.site"
    }
  ],
  "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": [
                "office-to-pdf-converter",
                "pdf-image-converter",
                "pdf-compressor",
                "pdf-form-signature-studio",
                "pdf-merge-split-reorder",
                "searchable-pdf-ocr",
                "secure-pdf-redactor"
              ]
            }
          }
        ],
        "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/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). Custom sets the colour/gray image resolution and the JPEG quality directly.\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- 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/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"
                }
              }
            }
          }
        }
      },
      "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"
              }
            }
          }
        }
      }
    }
  }
}