# QuickPDFHubPro — Backend API Contract This document specifies the REST API that the 8 backend-dependent tool pages already call. Their frontends (upload UI, progress states, success/error handling) are complete and production-ready — nothing here is a mockup. What's missing is a server implementing this contract. Deploy one, point `window.QPHP_API_BASE` (in `assets/js/config.js`) at its origin, and every tool below starts working immediately with no frontend changes. **Why these 8 tools need a backend at all:** every other tool on this site (JPG/PNG↔PDF, merge, split, compress, rotate, crop, image conversions, QR, ZIP, etc.) runs entirely client-side using pdf-lib, pdf.js, jsPDF, JSZip and the Canvas API — no upload, no server. The 8 tools below genuinely can't: faithfully rendering a `.docx`/`.xlsx`/`.pptx` to PDF (and the reverse) requires a real document/spreadsheet/presentation engine, and real PDF password protection/removal requires a PDF security library that performs actual encryption — none of that exists as an in-browser library. Rather than fake these conversions, the frontend is honest: until `QPHP_API_BASE` is set, each page reports that no backend is connected. --- ## Conventions - **Base URL**: all endpoints are relative to `QPHP_API_BASE`, e.g. `https://api.quickpdfhubpro.com/v1/convert/word-to-pdf`. - **Method**: `POST`, `multipart/form-data` for every endpoint. - **Auth**: none required for anonymous use. If you add API keys or rate limiting, send the key as `Authorization: Bearer `; the frontend already sends this header if `window.QPHP_API_KEY` is set (optional — add this variable to `config.js` if needed; it is not required today). - **File size limit**: the frontend advertises 50 MB per upload; the backend should enforce and return `413` with a JSON error if exceeded. - **Response — success**: either 1. the converted file returned directly as the response body, with `Content-Type` set to the correct MIME type and `Content-Disposition: attachment; filename="result.pdf"`, **or** 2. a JSON body `{ "download_url": "https://...", "filename": "result.pdf" }` pointing to a (short-lived, ideally signed) URL the frontend fetches immediately after. The frontend auto-detects which form you use via the response's `Content-Type` header. - **Response — error**: any non-2xx status with a JSON body `{ "error": "Human-readable message" }`. The frontend displays this message directly in the error state, so keep it user-facing. - **File lifecycle**: uploaded files and generated outputs should be deleted from server storage promptly after the response is sent (or after the signed download URL expires) — no long-term retention, consistent with this site's "your files aren't stored" privacy promise elsewhere on the site. --- ## Endpoints ### `POST /v1/convert/word-to-pdf` Converts a `.doc`/`.docx` file to PDF. - **Form fields**: `file` (the Word document). - **Success**: PDF file or `download_url` pointing to one. ### `POST /v1/convert/pdf-to-word` Converts a PDF into an editable `.docx`. - **Form fields**: `file` (the PDF). - **Success**: `.docx` file or `download_url` pointing to one. - **Notes**: reconstruction quality depends on whether the source PDF is text-based or scanned; scanned PDFs should ideally be OCR'd server-side first (out of scope for this contract's v1, but a natural extension). ### `POST /v1/convert/excel-to-pdf` Converts an `.xls`/`.xlsx` file to a print-accurate PDF. - **Form fields**: `file` (the spreadsheet). Optional `sheets` field (comma-separated sheet names or indices; omit to convert all sheets). - **Success**: PDF file or `download_url` pointing to one. ### `POST /v1/convert/pdf-to-excel` Extracts tabular data from a PDF into an editable `.xlsx`. - **Form fields**: `file` (the PDF). - **Success**: `.xlsx` file or `download_url` pointing to one. ### `POST /v1/convert/ppt-to-pdf` Converts a `.ppt`/`.pptx` deck to PDF, one slide per page. - **Form fields**: `file` (the presentation). Optional `include_notes` field (`"true"`/`"false"`, default `"false"`) to append speaker notes. - **Success**: PDF file or `download_url` pointing to one. ### `POST /v1/convert/pdf-to-ppt` Converts PDF pages into editable PowerPoint slides. - **Form fields**: `file` (the PDF). - **Success**: `.pptx` file or `download_url` pointing to one. ### `POST /v1/security/unlock-pdf` Removes password protection from a PDF, given the correct existing password. - **Form fields**: `file` (the encrypted PDF), `password` (the current password). - **Success**: decrypted PDF file or `download_url` pointing to one. - **Error case**: wrong password should return `422` with `{ "error": "Incorrect password." }` — the frontend surfaces this text as-is. ### `POST /v1/security/protect-pdf` Adds password encryption to a PDF. - **Form fields**: `file` (the PDF), `password` (the new password to set). - **Success**: encrypted PDF file or `download_url` pointing to one. - **Notes**: use standard, widely-compatible PDF encryption (e.g. AES-256 per the PDF 2.0 / ISO 32000-2 spec, or AES-128 for maximum reader compatibility) so the result opens in any standard PDF viewer. --- ## Frontend integration reference All 8 pages share one controller, `assets/js/tools/backend-tool.js` (`window.QPHPBackendTool.init({...})`), configured per-tool by the thin wrapper scripts in `assets/js/tools/word-to-pdf.js`, `assets/js/tools/pdf-to-word.js`, etc. The controller: 1. Reads `window.QPHP_API_BASE` from `assets/js/config.js`. If blank, it shows the error state with a message explaining the backend isn't connected — it never fakes a result. 2. On submit, builds a `FormData` with the uploaded file(s) (and `password` for Protect/Unlock PDF) and `POST`s it to `QPHP_API_BASE + endpoint`. 3. Parses the response per the conventions above and drives the existing progress/success/error UI. To bring a tool online: implement its endpoint per this contract, deploy it, and set `window.QPHP_API_BASE` in `assets/js/config.js` to your API's origin. No other frontend change is required.