# BrowsePDF Document API — Full Reference Base URL: `https://browsepdf.co/api/v1` Auth: every request needs `Authorization: Bearer ` (except GET /openapi.json). OpenAPI: https://browsepdf.co/api/v1/openapi.json ## Core model 1. Upload a file → get an opaque document handle (`id`). 2. Run operations that reference handles and return new handles. 3. Download the result via a short-lived signed URL. Handles let you chain operations without re-uploading. Documents auto-expire after 24h. ## Documents - `POST /documents` — multipart/form-data with a `file` field → `{ id, file_name, size_bytes, page_count, ... }` - `GET /documents/{id}` — the handle record - `GET /documents/{id}/metadata` — pages, sizes, encrypted/signed/fillable, fonts, attachments (free) - `GET /documents/{id}/download` — 302 → signed URL for the bytes - `DELETE /documents/{id}` — delete early ## Operations — `POST /operations/{name}` All take JSON. Sync ops return `{ document }` / `{ documents }` / data; slow or large ones return `{ job }` (202). - `metadata` { document } → pages/sizes/flags (free) - `merge` { documents: [id, ...] } → { document } - `split` { document, ranges: ["1-3","4-"] } → { documents: [...] } - `pages` { document, order?: [3,1], rotations?: {"2":90} } → { document } - `copy` { document, pages: [2], at?: 5 } → { document } - `watermark` { document, text, opacity?, angle?, tile?, color? } → { document } - `page-numbers` { document, template?: "{n}/{total}", position? } → { document } - `fill-form` { document, values: { field: value }, flatten? } → { document } - `extract-text` { document, include?: ["words","blocks"] } → { text, pages, words?, blocks?, metadata } - `render` { document, pages?, scale?, format?: "png"|"jpeg", quality? } → { documents: [{ id, page, width, height, content_type }] } - `redact` { document, regions: [{ page, x, y, width, height }] } → { document } (permanent; y from top, PDF points) - `compress` { document, level?: "low"|"balanced"|"high" } → { document, original_size, new_size, ratio, rasterized } - `convert` { document } → async { job } → { document } (office/HTML → PDF) - `ocr` { document, lang?: "eng" } → async { job } → { document, text, word_count } (searchable PDF) ## Pipelines — `POST /pipelines` ```json { "inputs": { "src": "" }, "nodes": { "conv": { "op": "convert", "in": "src" }, "mark": { "op": "watermark", "in": "conv", "options": { "text": "DRAFT" } } }, "output": "mark" } ``` → `{ "status": "succeeded", "document": "...", "nodes": {...}, "completed": [...] }` or `{ job }` (202) when any node is async. On a node error: `{ "status": "failed", "completed": [...], "failed": "", "error": {...} }`. ## Jobs — `GET /jobs/{id}` → `{ status: "queued"|"running"|"done"|"error", result?, error? }`. Add `webhook_url` to an operation/pipeline body to be POSTed on completion. ## Errors `{ "error": { "code", "message" } }`. Codes: unauthorized (401), insufficient_credits (402), not_found (404), invalid_request (400), unprocessable (422), rate_limited (429). ## Quickstart (curl) ```bash # Upload curl -X POST https://browsepdf.co/api/v1/documents \ -H "Authorization: Bearer $KEY" -F "file=@doc.pdf" # Watermark curl -X POST https://browsepdf.co/api/v1/operations/watermark \ -H "Authorization: Bearer $KEY" -H "content-type: application/json" \ -d '{"document":"","text":"CONFIDENTIAL","tile":true}' # Download curl -L https://browsepdf.co/api/v1/documents//download -H "Authorization: Bearer $KEY" -o out.pdf ```