{"components":{"schemas":{"ErrorEnvelope":{"properties":{"detail":{"type":"string"},"job_id":{"type":["string","null"]},"status":{"example":400,"type":"integer"},"success":{"example":false,"type":"boolean"},"title":{"example":"Missing file","type":"string"},"type":{"example":"/errors/missing-file","type":"string"}},"required":["success","type","title","status","detail"],"type":"object"},"JobManifest":{"properties":{"created_at":{"format":"date-time","type":"string"},"error":{"type":["object","null"]},"expires_at":{"format":"date-time","type":"string"},"job_id":{"type":"string"},"metadata":{"properties":{"filename":{"type":"string"},"pages":{"type":"integer"},"processing_ms":{"type":"integer"},"size_bytes":{"type":"integer"}},"type":"object"},"mimetype":{"type":"string"},"output_filename":{"type":"string"},"output_url":{"type":"string"},"status":{"enum":["queued","processing","done","failed"],"type":"string"},"tool":{"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"type":"object"},"Metadata":{"properties":{"filename":{"type":"string"},"pages":{"type":"integer"},"processing_ms":{"type":"integer"},"size_bytes":{"type":"integer"}},"type":"object"},"SuccessEnvelope":{"properties":{"expires_at":{"format":"date-time","type":"string"},"job_id":{"example":"job_a1b2c3d4e5f6","type":"string"},"metadata":{"properties":{"filename":{"type":"string"},"pages":{"type":"integer"},"processing_ms":{"type":"integer"},"size_bytes":{"type":"integer"}},"type":"object"},"output_url":{"example":"/api/v1/jobs/job_a1b2c3d4e5f6/download","type":"string"},"success":{"example":true,"type":"boolean"},"tool":{"type":"string"}},"required":["success","job_id","tool","output_url","metadata","expires_at"],"type":"object"}},"securitySchemes":{"BearerAuth":{"description":"API key passed as Bearer token. Only enforced when API_KEY_REQUIRED=true.","scheme":"bearer","type":"http"}}},"info":{"contact":{"email":"hello@intelliforge.tech"},"description":"Open-source, privacy-first PDF toolkit API by IntelliForge AI. Merge, split, rotate, extract text, encrypt, and decrypt PDFs via simple REST calls. Self-host or use the hosted service.","license":{"name":"MIT"},"title":"PDFforge API","version":"1.0.0"},"openapi":"3.1.0","paths":{"/api/v1/decrypt":{"post":{"description":"Decrypt a password-protected PDF using the current password and produce an unlocked copy. Use when a user has the password for an encrypted PDF and wants to remove the protection.","operationId":"decrypt","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":"The PDF file to process.","format":"binary","type":"string"},"password":{"description":"The current password of the encrypted PDF.","type":"string"}},"required":["file","password"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Remove password from a PDF","tags":["PDF Tools"]}},"/api/v1/encrypt":{"post":{"description":"Encrypt a PDF with a user-supplied password so it requires the password to open. Use when a user wants to secure a PDF before sharing it.","operationId":"encrypt","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":"The PDF file to process.","format":"binary","type":"string"},"password":{"description":"The password to set on the PDF.","type":"string"}},"required":["file","password"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Password-protect a PDF","tags":["PDF Tools"]}},"/api/v1/extract_text":{"post":{"description":"Extract machine-readable text from every page of a PDF and return as a .txt file. Use when a user needs the text content of a PDF for search, analysis, or indexing.","operationId":"extract_text","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":"The PDF file to process.","format":"binary","type":"string"}},"required":["file"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Extract text from a PDF","tags":["PDF Tools"]}},"/api/v1/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"service":{"example":"pdfforge","type":"string"},"status":{"example":"ok","type":"string"},"version":{"example":"v1","type":"string"}},"type":"object"}}},"description":"Service healthy."}},"summary":"Health check","tags":["System"]}},"/api/v1/jobs/{job_id}":{"delete":{"operationId":"deleteJob","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Job deleted."},"404":{"description":"Job not found."}},"summary":"Delete a job early","tags":["Jobs"]},"get":{"description":"Retrieve the full manifest for a job. Returns 404 if the job does not exist or 410 if it has expired.","operationId":"getJob","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobManifest"}}},"description":"Job manifest."},"404":{"description":"Job not found."},"410":{"description":"Job expired."}},"summary":"Get job status and metadata","tags":["Jobs"]}},"/api/v1/jobs/{job_id}/download":{"get":{"description":"Download the processed output file for a completed job.","operationId":"downloadJob","parameters":[{"in":"path","name":"job_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/pdf":{},"application/zip":{},"text/plain":{}},"description":"The output file."},"404":{"description":"Job not found."},"410":{"description":"Job expired."}},"summary":"Download job output file","tags":["Jobs"]}},"/api/v1/merge":{"post":{"description":"Combine 2 or more PDF files into a single document. Upload multiple files under the 'files' field. Use this when a user has several PDFs they want combined into one file.","operationId":"merge","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"files":{"description":"One or more PDF files.","items":{"format":"binary","type":"string"},"type":"array"}},"required":["files"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Merge multiple PDFs into one","tags":["PDF Tools"]}},"/api/v1/rotate":{"post":{"description":"Rotate all or selected pages of a PDF by 90, 180, or 270 degrees. Use when a user has a PDF with pages in the wrong orientation.","operationId":"rotate","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"angle":{"description":"Rotation angle in degrees (90, 180, or 270).","enum":[90,180,270],"type":"integer"},"file":{"description":"The PDF file to process.","format":"binary","type":"string"},"pages":{"description":"Optional page selection, e.g. '1,3-5'. Blank = all pages.","type":"string"}},"required":["file","angle"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Rotate PDF pages","tags":["PDF Tools"]}},"/api/v1/split":{"post":{"description":"Export selected page ranges from a PDF as separate files (returned in a ZIP). Use when a user wants to extract specific pages or ranges like '1-3,5,7-10'.","operationId":"split","parameters":[{"description":"Set to true to receive the raw output file instead of the JSON envelope.","in":"query","name":"download","schema":{"default":false,"type":"boolean"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":"The PDF file to process.","format":"binary","type":"string"},"ranges":{"description":"Comma-separated page ranges, e.g. '1-3,5,7-10'. 1-based.","type":"string"}},"required":["file","ranges"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}},"description":"Job completed successfully."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Bad request \u2014 missing or invalid input."},"401":{"description":"Unauthorized \u2014 invalid or missing API key."},"500":{"description":"Processing failed."}},"summary":"Split a PDF by page ranges","tags":["PDF Tools"]}}},"security":[{"BearerAuth":[]}],"servers":[{"description":"Production","url":"https://pdfforge-api.fly.dev"},{"description":"Local development","url":"http://localhost:5050"}],"tags":[{"description":"Core PDF processing operations.","name":"PDF Tools"},{"description":"Retrieve, download, or delete job results.","name":"Jobs"},{"description":"Health, metrics, and capability endpoints.","name":"System"}]}
