API documentation
Base URL https://api.bestpdfever.com/v1. Machine-readable spec: openapi.json (OpenAPI 3.1).
Quickstart
- Create an API key in the dashboard. It is shown once; store it as an environment variable such as
BPE_API_KEY. - Send a file (or a public file URL) to an endpoint. You get a job ID back straight away.
- Poll the job until its status is
done, or pass awebhook_urland we call you. - Download each output from its
url. Links last 15 minutes; files are deleted after an hour.
1. Create a job
curl -X POST https://api.bestpdfever.com/v1/compress \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"targetKB":500}'HTTP/1.1 202 Accepted
{
"id": "6f1c1a52-8d2e-4a59-9a4e-2f6b0f6e3c1d",
"status": "queued",
"credits": 2,
"statusUrl": "https://api.bestpdfever.com/v1/jobs/6f1c1a52-8d2e-4a59-9a4e-2f6b0f6e3c1d"
}2. Wait for the result
curl https://api.bestpdfever.com/v1/jobs/$JOB_ID \
-H "Authorization: Bearer $BPE_API_KEY"{
"id": "6f1c1a52-8d2e-4a59-9a4e-2f6b0f6e3c1d",
"status": "done",
"progress": 1,
"outputs": [
{ "name": "report-compressed.pdf", "size": 482113, "contentType": "application/pdf", "url": "https://…" }
]
}Authentication
Send your key in the Authorization header on every request. Keys start with bpe_live_.
Authorization: Bearer bpe_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXKeep keys on your server; never put them in browser or mobile app code. We store only a hash, so a lost key can’t be recovered: revoke it and create a new one. Check your plan and remaining credits with GET /v1/account.
Jobs and files
Every endpoint accepts either form:
- multipart/form-data: one or more
filefields (in order), an optionaloptionsfield containing a JSON object, and an optionalwebhook_url. - application/json:
{ "url": "https://…" }or{ "urls": [...] }with public file URLs, plusoptionsandwebhook_url. We download the files for you (redirects are followed; private network addresses are refused).
Jobs move through queued → active → done or failed. A failed job has an error code and costs nothing:
| password_required | The PDF is encrypted. Use /v1/unlock with the password first. |
| wrong_password | The password given to /v1/unlock is incorrect. |
| invalid_input | The file is damaged or not what its extension says. |
| conversion_failed | The converter could not process the file. |
| no_tables | PDF to Excel (tables mode) found no tables. |
| timeout | The job took longer than 5 minutes. |
Jobs are only visible to the account that created them. Uploaded files are deleted as soon as the job has run.
Webhooks
On paid plans, add webhook_url to any request and we POST the finished job to it (the same JSON as GET /v1/jobs/:id). Non-2xx responses are retried three times over about 45 seconds.
POST /your/webhook
BPE-Signature: t=1760000000,v1=5f2b…
{ "id": "6f1c…", "status": "done", "outputs": [ … ] }Verify each delivery with your signing secret from the dashboard: compute HMAC-SHA256 of `${t}.${rawBody}` and compare it with v1.
import { createHmac, timingSafeEqual } from "node:crypto";
// header = req.headers["bpe-signature"], rawBody = the exact request body string
function verify(header, rawBody, secret) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false; // replay window
const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1 ?? ""));
}Credits and limits
Each successful job costs the credits listed on its endpoint. The Free plan includes 100 credits per calendar month and stops at the limit; paid plans continue and bill overage per credit. Rate limits apply per account per minute, and file size limits per file. See pricing.
| Plan | Credits / month | Requests / minute | Max file |
|---|---|---|---|
| Free | 100 | 10 | 10 MB |
| Starter | 2,500 | 60 | 25 MB |
| Pro | 10,000 | 120 | 50 MB |
| Business | 50,000 | 300 | 50 MB |
Errors
Errors return JSON: { "error": "code", "message": "…", "detail": "…" }.
| 400 | invalid_input | Wrong number or type of files for the endpoint. |
| 400 | invalid_options | An option failed validation. `detail` says which. |
| 400 | blocked_url / unreachable_url | A file URL is private, blocked or could not be downloaded. |
| 401 | missing_api_key / invalid_api_key | No key, a malformed key, or a revoked key. |
| 402 | quota_exceeded | Free plan credits are used up for this month. |
| 403 | webhooks_not_in_plan | webhook_url was sent on the Free plan. |
| 404 | not_found | Unknown job ID, or a job created by another account. |
| 413 | too_large | A file is larger than your plan allows. |
| 429 | rate_limited | Too many requests this minute. Wait for Retry-After seconds. |
| 503 | unavailable | The endpoint is temporarily unavailable. Retry later. |
Endpoint reference
Merge PDF
1 credit per jobPOST /v1/merge
Combine 2–20 PDFs into one, in the order you send them.
Files: 2–20 · .pdf
curl -X POST https://api.bestpdfever.com/v1/merge \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@file1.pdf" \
-F "file=@file2.pdf"Split PDF
1 credit per jobPOST /v1/split
Split a PDF into one file per page, or into the page ranges you choose.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| ranges | string | Comma-separated page ranges, one output file per range, e.g. "1-3,4,5-9". Omit to split every page into its own file. |
curl -X POST https://api.bestpdfever.com/v1/split \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"ranges":"1-3,4-6"}'Rotate PDF
1 credit per jobPOST /v1/rotate
Rotate all pages, or only the pages you list, clockwise.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| angle | 90 | 180 | 270 | Clockwise rotation in degrees. Default: 90. |
| pages | string | Page ranges to rotate, e.g. "1,3-5". Omit to rotate every page. |
curl -X POST https://api.bestpdfever.com/v1/rotate \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"pages":"1,3-5"}'Compress PDF
2 credits per jobPOST /v1/compress
Shrink a PDF by downsampling images and removing redundant data.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| level | "low" | "recommended" | "extreme" | How hard to compress. Ignored when targetKB is set. Default: "recommended". |
| targetKB | integer | Try to get the file under this size in kilobytes. |
| grayscale | boolean | Convert to grayscale for extra savings. Default: false. |
curl -X POST https://api.bestpdfever.com/v1/compress \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"targetKB":500}'Repair PDF
1 credit per jobPOST /v1/repair
Rebuild a damaged or partly corrupted PDF.
Files: 1 · .pdf
curl -X POST https://api.bestpdfever.com/v1/repair \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"OCR PDF
3 credits per jobPOST /v1/ocr
Add a searchable, selectable text layer to scanned PDFs.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| languages | string[] | 1–3 Tesseract language codes: eng, spa, por, fra, deu, ita, nld, ind, swa, hin, ara, rus, tur, vie, chi_sim, jpn, kor. Default: ["eng"]. |
| deskew | boolean | Straighten crooked scans. Default: true. |
| force | boolean | Re-OCR pages that already contain text. Default: false. |
curl -X POST https://api.bestpdfever.com/v1/ocr \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"languages":["eng","fra"]}'Word to PDF
2 credits per jobPOST /v1/convert/word-to-pdf
Convert DOC, DOCX, ODT, RTF or TXT to PDF. Up to 10 files, one PDF each.
Files: 1–10 · .doc, .docx, .odt, .rtf, .txt
curl -X POST https://api.bestpdfever.com/v1/convert/word-to-pdf \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.doc"PowerPoint to PDF
2 credits per jobPOST /v1/convert/powerpoint-to-pdf
Convert PPT, PPTX, ODP, PPS or PPSX to PDF. Up to 10 files.
Files: 1–10 · .ppt, .pptx, .odp, .pps, .ppsx
curl -X POST https://api.bestpdfever.com/v1/convert/powerpoint-to-pdf \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.ppt"Excel to PDF
2 credits per jobPOST /v1/convert/excel-to-pdf
Convert XLS, XLSX, ODS or CSV to PDF. Up to 10 files.
Files: 1–10 · .xls, .xlsx, .ods, .csv
curl -X POST https://api.bestpdfever.com/v1/convert/excel-to-pdf \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.xls"HTML / URL to PDF
2 credits per jobPOST /v1/convert/html-to-pdf
Render a public web page or an uploaded HTML file to PDF with a real browser.
Files: 0–1 · .html, .htm
| Option | Type | Description |
|---|---|---|
| url | string | Public page to render. Send this instead of a file. |
| format | "A4" | "Letter" | "Legal" | Paper size. Default: "A4". |
| landscape | boolean | Landscape orientation. Default: false. |
| margin | "none" | "small" | "normal" | Page margins. Default: "small". |
| background | boolean | Print background colors and images. Default: true. |
| media | "print" | "screen" | CSS media type to emulate. Default: "screen". |
curl -X POST https://api.bestpdfever.com/v1/convert/html-to-pdf \
-H "Authorization: Bearer $BPE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"options":{"url":"https://example.com"}}'PDF to Word
2 credits per jobPOST /v1/convert/pdf-to-word
Convert a PDF to an editable DOCX.
Files: 1 · .pdf
curl -X POST https://api.bestpdfever.com/v1/convert/pdf-to-word \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"PDF to PowerPoint
2 credits per jobPOST /v1/convert/pdf-to-powerpoint
Convert each PDF page into a slide with editable text.
Files: 1 · .pdf
curl -X POST https://api.bestpdfever.com/v1/convert/pdf-to-powerpoint \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"PDF to Excel
2 credits per jobPOST /v1/convert/pdf-to-excel
Extract tables from a PDF into an XLSX workbook.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| mode | "tables" | "pages" | "tables": one sheet per detected table. "pages": one sheet per page with all text. Default: "tables". |
curl -X POST https://api.bestpdfever.com/v1/convert/pdf-to-excel \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"PDF to PDF/A
2 credits per jobPOST /v1/convert/pdf-to-pdfa
Convert to PDF/A for long-term archiving.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| level | "1" | "2" | "3" | PDF/A conformance level (PDF/A-1b, -2b or -3b). Default: "2". |
curl -X POST https://api.bestpdfever.com/v1/convert/pdf-to-pdfa \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"Protect PDF
1 credit per jobPOST /v1/protect
Encrypt a PDF with a password (AES-256) and set permissions.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| userPasswordrequired | string | Password needed to open the file. |
| ownerPassword | string | Password that unlocks the permissions. Defaults to a random one. |
| allowPrinting | boolean | Allow printing. Default: true. |
| allowCopying | boolean | Allow copying text and images. Default: false. |
| allowEditing | boolean | Allow editing and annotations. Default: false. |
curl -X POST https://api.bestpdfever.com/v1/protect \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf" \
-F 'options={"userPassword":"s3cret"}'Unlock PDF
1 credit per jobPOST /v1/unlock
Remove the password and restrictions from a PDF you have the password for.
Files: 1 · .pdf
| Option | Type | Description |
|---|---|---|
| password | string | The document's password. Leave empty for files with only permission restrictions. Default: "". |
curl -X POST https://api.bestpdfever.com/v1/unlock \
-H "Authorization: Bearer $BPE_API_KEY" \
-F "file=@input.pdf"