PDFBEAR API and MCP server for developers

Compress, convert, merge, split, protect, unlock and OCR PDFs from your own code with a simple REST API, or let an AI assistant do it through our remote MCP server. The same engine that runs pdfbear.com, with a free tier of 100 jobs a month.

Quick start

Every conversion is an asynchronous job: you start it, poll its status, then download the result. Base URL: https://pdfbear.com/api/v1.

  1. Create a free account, confirm your email, then open Account → Developers / API and create a key.
  2. Start a job:
curl -X POST https://pdfbear.com/api/v1/jobs \
  -H "Authorization: Bearer $PDFBEAR_API_KEY" \
  -F tool=compress-pdf \
  -F file=@report.pdf \
  -F 'options={"compression_level":"recommended"}'

# 202 Accepted
{"job_id": "job_3f2c9a0e8b7d4c1e9f6a5b4c3d2e1f00", "status": "queued",
 "tool": "compress-pdf", "status_url": "https://pdfbear.com/api/v1/jobs/job_3f2c..."}
  1. Poll until status is completed, then download:
curl https://pdfbear.com/api/v1/jobs/job_3f2c9a0e8b7d4c1e9f6a5b4c3d2e1f00 \
  -H "Authorization: Bearer $PDFBEAR_API_KEY"

curl -L -o report-small.pdf \
  https://pdfbear.com/api/v1/jobs/job_3f2c9a0e8b7d4c1e9f6a5b4c3d2e1f00/download \
  -H "Authorization: Bearer $PDFBEAR_API_KEY"

Most jobs finish in a few seconds. Poll every 1-2 seconds; status requests count toward the rate limit but not toward your monthly job quota.

Authentication

Send your key in the Authorization header on every request: Authorization: Bearer pdfb_live_.... Keys are 42 characters long and start with pdfb_live_. We store only a SHA-256 fingerprint, so a key is shown once when you create it; if you lose it, revoke it and create a new one. Keys never expire, and revoking one takes effect immediately.

Keep keys on your server. Anyone who has a key can run jobs on your quota.

CORS: /api/v1 and /mcp send Access-Control-Allow-Origin: *, so browsers are allowed to call them (no cookies are used; the key is the only credential). Only do that from a private tool or an app where the user enters their own key: a key embedded in a public web page can be copied by anyone. For public sites, call the API from your server.

Plans, quotas and limits

Free tier at a glance: 100 jobs per month, 60 requests per minute per key, 50 MB per file, no credit card.

Free accountPremium
API jobs per calendar month (UTC)1002,000
Requests per minute, per key6060
Max size per input file50 MB90 MB
Max pages per job30200
AI tools (OCR, summarize, AI Word engine)NoYes, within the fair-use allowance
PDF outputSmall "PDFBEAR.COM - Free Ver." badge in the lower-right corner of each pageClean, no badge
CORS (browser calls)Allowed (Access-Control-Allow-Origin: *)Allowed
Result link lifetime30 daysWhile your subscription is active
About the free badge. API output follows exactly the same rule as the website: on a free account, standard PDF results get a small "PDFBEAR.COM - Free Ver." stamp in the lower-right corner of each page. ZIP, DOCX, JPG and TXT results are not stamped. Encrypted PDFs from protect-pdf and cleaned PDFs from remove-watermark-pdf are also exempt. Premium output is always clean. Each job's status says whether its result carries the badge (free_badge).

Every created job counts toward the monthly quota, including jobs that later fail. Requests that are rejected before a job is created (bad key, invalid options, a file that is too large) do not count. GET /api/v1/me shows what you have left. Total upload size per request is capped at 95 MB; for bigger merges, pass file_urls instead.

Endpoints

GET/api/v1/tools

Lists every tool the API offers with its accepted input types, output format, option schema and whether it needs Premium. No key needed.

POST/api/v1/jobs

Starts a job and returns 202 Accepted with job_id and status_url. Send either multipart/form-data or JSON:

FieldDescription
toolRequired. A tool_id from the table below, e.g. compress-pdf.
file / filesMultipart upload. merge-pdf takes 2 or more files; compare-pdf takes exactly 2.
file_url / file_urlsA public http(s) URL we download the input from (JSON or form). Private and internal addresses are refused.
content_base64 + filenameJSON only: the file inline, base64-encoded. files: [{filename, content_base64}] for merges.
urlhtml-to-pdf renders a web page and rss-to-pdf fetches a feed. For file tools it is treated like file_url.
optionsTool options: a JSON object (in multipart, a JSON string). Unknown options are rejected.
curl -X POST https://pdfbear.com/api/v1/jobs \
  -H "Authorization: Bearer $PDFBEAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"tool": "html-to-pdf", "url": "https://example.com",
       "options": {"page_size": "A4", "remove_popups": true}}'

curl -X POST https://pdfbear.com/api/v1/jobs \
  -H "Authorization: Bearer $PDFBEAR_API_KEY" \
  -F tool=merge-pdf -F files=@part1.pdf -F files=@part2.pdf

GET/api/v1/jobs/{job_id}

Returns status: queued, processing, completed, needs_action or failed. needs_action means the file or selected method must change; failed means PDFBEAR had a system problem. Both include error.message. A completed job includes:

{
  "job_id": "job_3f2c9a0e8b7d4c1e9f6a5b4c3d2e1f00",
  "tool": "compress-pdf",
  "status": "completed",
  "created_at": "2026-09-26T10:15:02Z",
  "finished_at": "2026-09-26T10:15:05Z",
  "input": {"filename": "report.pdf", "size": 4812331},
  "download_url": "https://pdfbear.com/api/v1/jobs/job_3f2c.../download",
  "public_url": "https://pdfbear.com/downloads/converted/converted_9b1e....pdf",
  "filename": "report.pdf",
  "size": 1022456,
  "content_type": "application/pdf",
  "expires_at": "2026-10-26T10:15:02Z",
  "expired": false,
  "free_badge": true
}

download_url needs your key. public_url is the same unguessable, expiring link the website gives you, and it opens in any browser without a key, so treat it like a password-free share link.

GET/api/v1/jobs/{job_id}/download

Streams the result file with a proper Content-Disposition filename. Returns 409 while the job is still running and 410 once the result has expired.

GET/api/v1/me

Your plan, this month's job quota (limit, used, remaining, resets_at) and your limits.

Tools and options

tool_idWhat it doesInputOutputOptionsPlan
compress-pdf Reduce PDF file size (lossless or with image downsampling). .pdf PDF compression_level (less | recommended | extreme) Free
merge-pdf Combine 2 or more PDFs into one, in the order given. 2+ .pdf PDF - Free
split-pdf Split a PDF into several PDFs (returned as a ZIP). .pdf ZIP mode (all | ranges | fixed | size | smart-blank | smart-headings)
ranges (string)
merge_ranges (boolean)
every_n_pages (integer)
max_size_mb (number)
omit_separators (boolean)
Free
pdf-to-word Convert a PDF to an editable Word document (.docx). .pdf DOCX engine (standard | ai) Free
word-to-pdf Convert a Word document (DOC/DOCX/ODT/RTF) to PDF. .doc, .docx, .odt, .rtf PDF - Free
pdf-converter Detect a supported document or image format and convert it to PDF. .doc, .docx, .odt, .rtf, .txt, .html, .htm, .xls, .xlsx, .ppt, .pptx, .jpg, .jpeg, .png, .tif, .tiff, .webp, .bmp, .gif, .heic, .heif, .ods, .odp, .csv, .hwp, .pages, .epub, .zip PDF - Free
pdf-to-jpg Render every PDF page as a JPG image (returned as a ZIP). .pdf ZIP - Free
jpg-to-pdf Convert a JPG or PNG image to a PDF. .jpg, .jpeg, .png PDF - Free
rotate-pdf Rotate all pages, or selected pages, of a PDF. .pdf PDF angle (90 | 180 | 270)
pages (string)
Free
protect-pdf Encrypt a PDF with an open password. .pdf PDF password (string), required Free
unlock-pdf Remove the password/encryption from a PDF you are allowed to open. .pdf PDF password (string)
guess_password (boolean)
Free
remove-watermark-pdf Remove text/image/annotation watermarks from a PDF (automatic structural mode). .pdf PDF watermark_text (string)
target_color (string)
Free
pdf-to-pdfa Convert a PDF to PDF/A-2b for long-term archiving. .pdf PDF - Free
html-to-pdf Render a public web page (http/https URL) to PDF, JavaScript included. web page URL PDF page_size (A3 | A4 | A5 | Letter)
orientation (portrait | landscape)
margin (none | small | big)
screen_width (integer)
one_long_page (boolean)
block_ads (boolean)
remove_popups (boolean)
Free
ocr-pdf Make a scanned PDF searchable with AI OCR. .pdf PDF - Premium
summarize-pdf Create an AI summary of a PDF and return it as text. .pdf TXT length (short | medium | long)
tone (neutral | formal | casual | academic | simple)
Premium
excel-to-pdf Convert an Excel spreadsheet (XLS/XLSX/ODS) to PDF. .xls, .xlsx, .ods PDF - Free
ppt-to-pdf Convert a PowerPoint presentation (PPT/PPTX/ODP) to PDF. .ppt, .pptx, .odp PDF - Free
rss-to-pdf Turn a public RSS or Atom feed into a readable PDF. web page URL PDF max_items (integer)
content_mode (full | summary)
include_images (boolean)
page_size (A3 | A4 | A5 | Letter)
margin (none | small | big)
Free
pdf-to-excel Extract PDF tables and content into an editable Excel workbook (.xlsx). .pdf XLSX - Free
pdf-to-ppt Convert PDF pages into an editable PowerPoint presentation (.pptx). .pdf PPTX - Free
pdf-to-png Render every PDF page as a PNG image (returned as a ZIP). .pdf ZIP - Free
delete-pages-from-pdf Remove selected pages from a PDF and return a new PDF. .pdf PDF pages (string), required Free
resize-pdf Resize PDF pages to a paper preset or scale percentage. .pdf PDF mode (preset | scale)
preset (a3 | a4 | a5 | letter | legal)
scale (number)
Free
repair-pdf Repair a damaged or malformed PDF and recover readable content. .pdf PDF - Free
add-page-numbers-to-pdf Add visible page numbers to a PDF. .pdf PDF position (bottom_center | top_center | bottom_right | top_right | bottom_left | top_left)
start_page (integer)
Free
add-watermark-pdf Add a text watermark to a PDF. .pdf PDF watermark_text (string), required
font_size (integer)
font (helvetica | arial | times | courier)
bold (boolean)
italic (boolean)
color (string)
opacity (number)
rotation (integer)
position (center | top_left | top_center | top_right | middle_left | middle_right | bottom_left | bottom_center | bottom_right)
mosaic (boolean)
underline (boolean)
page_from (integer)
page_to (integer)
layer (over | below)
Free
scan-to-pdf Turn a photo or document scan into a searchable PDF with OCR. .jpg, .jpeg, .png PDF - Premium
crop-pdf Automatically trim PDF margins or crop every page to a fractional box. .pdf PDF crop_box (object) Free
extract-pages-from-pdf Extract selected pages or ranges into a new PDF. .pdf PDF pages (string), required Free
organize-pdf Reorder, rotate, and remove PDF pages in one operation. .pdf PDF page_order (array)
deletions (array)
rotations (object)
Free
compare-pdf Compare exactly two PDFs and create a color-coded text-difference report. 2+ .pdf PDF - Free
pdf-forms Create interactive fields in a PDF or fill its existing form fields. .pdf PDF field_values (object)
created_fields (array)
Free
translate-pdf Translate PDF text into another language while preserving the layout where possible. .pdf PDF target_lang (string), required Premium
redact-pdf Permanently redact matching text or specified page areas from a PDF. .pdf PDF redact_terms (string)
redact_areas (array)
Free
png-to-pdf Convert a PNG image to PDF. .png PDF - Free
heic-to-pdf Convert an iPhone HEIC or HEIF image to PDF. .heic, .heif PDF - Free
tiff-to-pdf Convert a TIFF image or scan to PDF. .tiff, .tif PDF - Free
webp-to-pdf Convert a WebP image to PDF. .webp PDF - Free
bmp-to-pdf Convert a BMP bitmap image to PDF. .bmp PDF - Free
txt-to-pdf Convert a plain-text TXT file to PDF. .txt PDF - Free
rtf-to-pdf Convert a Rich Text Format document to PDF. .rtf PDF - Free
odt-to-pdf Convert an OpenDocument Text document to PDF. .odt PDF - Free
pdf-to-text Extract selectable PDF text into a plain TXT file. .pdf TXT - Free
extract-images-from-pdf Extract embedded raster images from a PDF (returned as a ZIP). .pdf ZIP - Free
flatten-pdf Flatten form fields, annotations, and layers into permanent PDF page content. .pdf PDF - Free
pdf-question-generator Generate study or quiz questions with answers from a PDF. .pdf PDF - Premium
pdf-accessibility-checker Check a PDF for common accessibility issues and return a text report. .pdf TXT - Free
pdfa-checker Pre-check a PDF for common PDF/A conformance issues and return a text report. .pdf TXT - Free
pdf-to-markdown Convert selectable PDF text and structure into Markdown. .pdf MD - Free
ods-to-pdf Convert an ODS spreadsheet to PDF. .ods PDF - Free
odp-to-pdf Convert an ODP presentation to PDF. .odp PDF - Free
csv-to-pdf Convert a CSV table to PDF. .csv PDF - Free
hwp-to-pdf Convert a Hangul HWP document to PDF. .hwp PDF - Free
pages-to-pdf Convert an Apple Pages document with an embedded PDF preview to PDF. .pages PDF - Free
epub-to-pdf Convert EPUB chapters into a readable PDF. .epub PDF - Free
zip-to-pdf Convert supported files in a ZIP archive and merge them into one PDF. .zip PDF - Free
svg-to-pdf Convert an SVG vector image to PDF. .svg PDF - Free
edit-pdf Apply structured text, annotation, shape, image, or redaction edits to a PDF. .pdf PDF edits (object)
text_edits (array)
coords (points)
Free
pdf-annotator Add structured annotations, text, shapes, or images to a PDF. .pdf PDF edits (object)
text_edits (array)
coords (points)
Free
esign-pdf Place user-provided signature edit objects on a PDF. .pdf PDF edits (object), required
coords (points)
Free
presentation-maker Create a researched, designed PDF slide deck from a topic or brief. PDF topic (string), required
num_slides (integer)
audience (string)
tone (string)
theme (auto | azure | midnight | emerald | plum | sunset | slate)
Free

Notes: pdf-to-word with a scanned (image-only) PDF needs AI OCR, which is Premium. unlock-pdf is for files you are allowed to open; guess_password (trying common passwords) is Premium. remove-watermark-pdf runs the automatic mode; on a free account the output still carries the PDFBEAR free badge. The full machine-readable list is at /api/v1/tools.

Python example

import json, os, time, requests

API = "https://pdfbear.com/api/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['PDFBEAR_API_KEY']}"}

def run(tool, path, **options):
    with open(path, "rb") as fh:
        r = requests.post(f"{API}/jobs", headers=HEADERS,
                          data={"tool": tool, "options": json.dumps(options)},
                          files={"file": fh})
    r.raise_for_status()
    job = r.json()
    while job["status"] in ("queued", "processing"):
        time.sleep(1.5)
        job = requests.get(job["status_url"], headers=HEADERS).json()
    if job["status"] == "failed":
        raise RuntimeError(job["error"]["message"])
    out = requests.get(job["download_url"], headers=HEADERS)
    out.raise_for_status()
    with open(job["filename"], "wb") as fh:
        fh.write(out.content)
    return job["filename"]

print(run("compress-pdf", "report.pdf", compression_level="extreme"))

JavaScript example

Node.js 20 or newer (built-in fetch, FormData and fs.openAsBlob):

import { openAsBlob } from "node:fs";
import { writeFile } from "node:fs/promises";

const API = "https://pdfbear.com/api/v1";
const headers = { Authorization: `Bearer ${process.env.PDFBEAR_API_KEY}` };

async function run(tool, path, options = {}) {
  const form = new FormData();
  form.append("tool", tool);
  form.append("options", JSON.stringify(options));
  form.append("file", await openAsBlob(path), path.split("/").pop());

  let res = await fetch(`${API}/jobs`, { method: "POST", headers, body: form });
  let job = await res.json();
  if (!res.ok) throw new Error(job.error.message);

  while (job.status === "queued" || job.status === "processing") {
    await new Promise((r) => setTimeout(r, 1500));
    job = await (await fetch(job.status_url, { headers })).json();
  }
  if (job.status === "failed") throw new Error(job.error.message);

  const file = await fetch(job.download_url, { headers });
  await writeFile(job.filename, Buffer.from(await file.arrayBuffer()));
  return job.filename;
}

console.log(await run("pdf-to-word", "contract.pdf"));

Errors

Errors always look like {"error": {"code": "quota_exceeded", "message": "..."}}. Branch on code; the message is written for humans.

HTTPcodeMeaning
400bad_requestThe body is not multipart or a JSON object.
401missing_api_key, invalid_api_key, api_key_revokedSend a valid key as Authorization: Bearer ....
403email_unverifiedConfirm the email address on your account.
403premium_requiredThe tool or option needs Premium (AI tools, scanned PDFs, password recovery).
404job_not_found, not_foundNo such job on your account, or no such endpoint.
409job_not_ready, job_failedDownload requested before the job completed, or after it failed.
410result_expiredThe result is past its expiry date. Run the job again.
413file_too_large, too_many_pages, too_many_filesThe input is over a size, page or file-count limit.
422validation_error, unknown_option, missing_input, unsupported_tool, unsupported_file_type, empty_file, unsafe_url, url_fetch_failedThe request is well-formed but can't be processed as sent.
429rate_limitedOver 60 requests a minute on this key. Wait for Retry-After seconds.
429quota_exceededThis month's job quota is used up. Retry-After points at the reset.
429ai_allowance_exhaustedThe Premium fair-use AI allowance for this billing period is used up.
500internal_errorOur fault. Retry, and contact support if it keeps happening.

A job that is accepted but then fails (for example a corrupted PDF) is not an HTTP error: the job's status is failed and error.message explains what went wrong.

MCP server

PDFBEAR runs a remote Model Context Protocol server, so AI assistants such as ChatGPT, Claude, Cursor and VS Code agents can use PDFBEAR tools directly. Endpoint: https://mcp.pdfbear.com (Streamable HTTP transport, stateless). Python handles the MCP and OAuth protocols; the dedicated hostname is an Nginx reverse proxy. It uses the same account, quota and plan rules as the REST API.

Each API workflow is an MCP tool (compress_pdf, merge_pdf, pdf_to_word, html_to_pdf, ...) plus get_job. ChatGPT can pass conversation attachments through native file parameters. Other MCP clients can give a tool a file_url, or a small file (up to 10 MB) as content_base64 + filename. The call waits for the job and returns a download link; if the job needs longer, it returns the job_id to check with get_job.

For a narrowly scoped integration, use the machine-only endpoint https://mcp.pdfbear.com/<tool-id> (for example, /compress-pdf). A scoped endpoint exposes only that workflow and the support tools; the root endpoint exposes the complete catalog. Scoped endpoints accept MCP POST requests but do not publish separate web pages.

Claude Code

claude mcp add --transport http pdfbear https://mcp.pdfbear.com \
  --header "Authorization: Bearer pdfb_live_..."

Claude Desktop

Add this to claude_desktop_config.json (Settings → Developer → Edit Config). It uses the mcp-remote bridge, which needs Node.js:

{
  "mcpServers": {
    "pdfbear": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.pdfbear.com",
               "--header", "Authorization:${PDFBEAR_AUTH}"],
      "env": { "PDFBEAR_AUTH": "Bearer pdfb_live_..." }
    }
  }
}

Cursor, VS Code and other MCP clients

Any client that supports remote HTTP servers with custom headers works. Cursor (~/.cursor/mcp.json):

{
  "mcpServers": {
    "pdfbear": {
      "url": "https://mcp.pdfbear.com",
      "headers": { "Authorization": "Bearer pdfb_live_..." }
    }
  }
}

VS Code (.vscode/mcp.json):

{
  "servers": {
    "pdfbear": {
      "type": "http",
      "url": "https://mcp.pdfbear.com",
      "headers": { "Authorization": "Bearer pdfb_live_..." }
    }
  }
}

For a raw client: POST JSON-RPC 2.0 messages to /mcp with Content-Type: application/json. The server supports protocol versions 2025-06-18, 2025-03-26 and 2024-11-05 and answers every request with a single JSON response (there is no server-sent event stream). A browser GET opens the MCP overview and setup page. initialize, ping and tools/list work without a key so you can inspect the tools; tools/call needs one.

curl https://mcp.pdfbear.com -H "Content-Type: application/json" \
  -H "Authorization: Bearer $PDFBEAR_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"compress_pdf",
       "arguments":{"file_url":"https://example.com/report.pdf","compression_level":"extreme"}}}'

Changelog

Questions or a tool you'd like to see in the API? Email support@pdfbear.com.