{"openapi":"3.1.0","info":{"title":"BrowsePDF Document API","version":"1.0.0","description":"Programmatic PDF operations — merge, split, convert, watermark, redact, compress, OCR, render, extract text, and compose them into pipelines. Upload a file to get a document handle, run operations that return new handles, then download. Designed to be composable for developers and AI agents.","contact":{"name":"BrowsePDF","url":"https://browsepdf.co/developers"}},"servers":[{"url":"https://browsepdf.co/api/v1","description":"Production"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Documents","description":"Upload, fetch, download, and delete document handles."},{"name":"Operations","description":"One-shot operations on documents."},{"name":"Pipelines","description":"Compose operations into a DAG."},{"name":"Jobs","description":"Poll asynchronous operations."}],"paths":{"/documents":{"post":{"operationId":"uploadDocument","summary":"Upload a document","description":"Upload a file and receive an opaque document handle. multipart/form-data with a `file` field.","tags":["Documents"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentHandle"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"415":{"$ref":"#/components/responses/Error"}}}},"/documents/{id}":{"get":{"operationId":"getDocument","summary":"Get a document handle","tags":["Documents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentHandle"}}}},"404":{"$ref":"#/components/responses/Error"}}},"delete":{"operationId":"deleteDocument","summary":"Delete a document","tags":["Documents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/Error"}}}},"/documents/{id}/metadata":{"get":{"operationId":"getDocumentMetadata","summary":"Get document metadata (free)","tags":["Documents"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Metadata"}}}}}}},"/documents/{id}/download":{"get":{"operationId":"downloadDocument","summary":"Download document bytes","tags":["Documents"],"description":"302 redirect to a short-lived signed URL for the raw bytes.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"302":{"description":"Redirect to signed URL"}}}},"/operations/metadata":{"post":{"operationId":"op_metadata","summary":"Inspect a PDF","description":"Return page count, sizes, and encrypted/signed/fillable flags, fonts, and attachment count. Free. Cost: 0 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Operation-specific data (see description)."}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/merge":{"post":{"operationId":"op_merge","summary":"Merge documents","description":"Concatenate multiple PDFs into one, in the order given. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Document handles to merge, in order."}},"required":["documents"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/split":{"post":{"operationId":"op_split","summary":"Split a document","description":"Split a PDF into multiple documents by page ranges (e.g. \"1-3\", \"4-\", \"5\"). Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"ranges":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Page ranges, 1-indexed inclusive. \"1-3\", \"4-\", \"-2\", \"5\"."}},"required":["document","ranges"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"string"}}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/pages":{"post":{"operationId":"op_pages","summary":"Reorder / delete / rotate pages","description":"Rebuild a document from an explicit page order (reorder, delete by omission, duplicate by repetition) with optional per-page rotation. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"order":{"type":"array","items":{"type":"integer"},"description":"Final page order as 1-indexed source page numbers. Defaults to identity."},"rotations":{"type":"object","additionalProperties":{"type":"integer"},"description":"Map of source page number → rotation degrees (multiple of 90)."}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/copy":{"post":{"operationId":"op_copy","summary":"Duplicate pages","description":"Duplicate the given pages into the document at a position. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"pages":{"type":"array","items":{"type":"integer"},"minItems":1,"description":"1-indexed source pages to duplicate."},"at":{"type":"integer","description":"1-indexed insert position (default: appended)."}},"required":["document","pages"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/watermark":{"post":{"operationId":"op_watermark","summary":"Add a watermark","description":"Stamp a text watermark on every page, centered or tiled. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"text":{"type":"string","description":"Watermark text."},"font":{"type":"string","enum":["sans","serif","mono"],"default":"sans"},"fontSize":{"type":"number","default":48},"opacity":{"type":"number","minimum":0,"maximum":1,"default":0.3},"angle":{"type":"number","default":45},"color":{"type":"array","items":{"type":"integer"},"description":"RGB 0–255, e.g. [128,128,128]."},"tile":{"type":"boolean","default":false}},"required":["document","text"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/page-numbers":{"post":{"operationId":"op_page_numbers","summary":"Add page numbers","description":"Stamp running page numbers with a template and position. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"template":{"type":"string","default":"{n}","description":"Template with {n} and {total}."},"numeral":{"type":"string","enum":["arabic","roman","roman-upper"],"default":"arabic"},"position":{"type":"string","enum":["top-left","top-center","top-right","bottom-left","bottom-center","bottom-right"],"default":"bottom-center"},"start":{"type":"integer","default":1},"margin":{"type":"number","default":24},"fontSize":{"type":"number","default":12}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/fill-form":{"post":{"operationId":"op_fill_form","summary":"Fill form fields","description":"Populate AcroForm fields by name; optionally flatten so values are baked into the page. Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"values":{"type":"object","description":"Field name → value (string | boolean | string[])."},"flatten":{"type":"boolean","default":false}},"required":["document","values"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/extract-text":{"post":{"operationId":"op_extract_text","summary":"Extract text","description":"Extract the text layer, with optional word/block bounding boxes. Returns has_text_layer=false for scanned PDFs (route those to ocr). Cost: 1 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"include":{"type":"array","items":{"type":"string","enum":["words","blocks"]},"description":"Add positional data with bounding boxes."}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","description":"Operation-specific data (see description)."}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/render":{"post":{"operationId":"op_render","summary":"Render pages to images","description":"Rasterize pages to PNG or JPEG image documents. Cost: 2 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"pages":{"type":"array","items":{"type":"integer"},"description":"1-indexed pages (default: all)."},"scale":{"type":"number","default":2,"description":"1 = 72 DPI, 2 ≈ 144 DPI. Clamped to [0.5, 4]."},"format":{"type":"string","enum":["png","jpeg"],"default":"png"},"quality":{"type":"integer","description":"JPEG quality 0–100."}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"page":{"type":"integer"},"width":{"type":"integer"},"height":{"type":"integer"},"content_type":{"type":"string"}}}}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/redact":{"post":{"operationId":"op_redact","summary":"Redact regions","description":"Permanently burn out rectangular regions by rasterizing the affected pages (text underneath is destroyed, not merely covered). Cost: 2 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"regions":{"type":"array","minItems":1,"items":{"type":"object","properties":{"page":{"type":"integer"},"x":{"type":"number"},"y":{"type":"number"},"width":{"type":"number"},"height":{"type":"number"}},"required":["page","x","y","width","height"]},"description":"Rectangles in PDF points with y measured from the top."}},"required":["document","regions"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/compress":{"post":{"operationId":"op_compress","summary":"Compress a PDF","description":"Rasterizing compression, best for scanned/image-heavy PDFs. Never returns a larger file (returns the original unchanged when it wouldn't be smaller). Cost: 2 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"level":{"type":"string","enum":["low","balanced","high"],"default":"balanced"}},"required":["document"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string"},"original_size":{"type":"integer"},"new_size":{"type":"integer"},"ratio":{"type":"number"},"rasterized":{"type":"boolean"}}}}}},"202":{"description":"Accepted (async job; large inputs or Prefer: respond-async)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/convert":{"post":{"operationId":"op_convert","summary":"Convert to PDF","description":"Convert an office/HTML document (docx, xlsx, pptx, odt, rtf, html, …) to PDF. Always async. Cost: 3 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."}},"required":["document"]}}}},"responses":{"202":{"description":"Accepted (async job)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/operations/ocr":{"post":{"operationId":"op_ocr","summary":"OCR a scanned PDF","description":"Recognize a scanned/image PDF and return a searchable PDF (image + invisible text layer) plus the extracted text. Always async. Cost: 10 credit(s).","tags":["Operations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document":{"type":"string","description":"A document handle id (from POST /documents or a prior operation)."},"lang":{"type":"string","default":"eng","description":"Tesseract language code(s), e.g. \"eng\" or \"eng+deu\"."}},"required":["document"]}}}},"responses":{"202":{"description":"Accepted (async job)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/pipelines":{"post":{"operationId":"runPipeline","summary":"Run a pipeline (DAG of operations)","description":"Chain operations server-side. Nodes reference inputs by name or other node ids; document handles flow between steps with no intermediate downloads. Stops on the first failing node.","tags":["Pipelines"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineSpec"}}}},"responses":{"200":{"description":"Completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineResult"}}}},"202":{"description":"Accepted (async job)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobAccepted"}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/jobs/{id}":{"get":{"operationId":"getJob","summary":"Poll an async job","tags":["Jobs"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key as a Bearer token: `Authorization: Bearer <key>`."}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}}},"DocumentHandle":{"type":"object","properties":{"id":{"type":"string"},"file_name":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer"},"page_count":{"type":["integer","null"]},"sha256":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"}}},"Metadata":{"type":"object","properties":{"pages":{"type":"integer"},"encrypted":{"type":"boolean"},"signed":{"type":"boolean"},"fillable":{"type":"boolean"},"page_sizes":{"type":"array","items":{"type":"object","properties":{"page":{"type":"integer"},"width":{"type":"number"},"height":{"type":"number"}}}},"fonts":{"type":"array","items":{"type":"string"}},"attachments":{"type":"integer"}}},"JobAccepted":{"type":"object","properties":{"job":{"type":"string"},"status":{"type":"string","enum":["queued"]}}},"Job":{"type":"object","properties":{"job":{"type":"string"},"operation":{"type":"string"},"status":{"type":"string","enum":["queued","running","done","error"]},"result":{"type":["object","null"]},"error":{"type":["object","null"]},"created_at":{"type":"string"},"finished_at":{"type":["string","null"]}}},"PipelineSpec":{"type":"object","required":["nodes","output"],"properties":{"inputs":{"type":"object","additionalProperties":{"type":"string"},"description":"Named input document handles."},"nodes":{"type":"object","additionalProperties":{"type":"object","properties":{"op":{"type":"string","description":"Operation name."},"in":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Input ref(s): an input name or upstream node id."},"options":{"type":"object","description":"Operation options (merged into the request body)."}},"required":["op","in"]}},"output":{"type":"string","description":"Node id whose output is the pipeline result."}}},"PipelineResult":{"type":"object","properties":{"status":{"type":"string","enum":["succeeded","failed"]},"document":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"type":"string"}},"completed":{"type":"array","items":{"type":"string"}},"failed":{"type":"string"},"error":{"$ref":"#/components/schemas/Error"}}}}}}