Skip to content
eFlyPDF

Developers

Pro APIPro plan only

The same tools as on the website, driven from your code. The API is included in the Pro plan and shares your account's quotas.

API version 1, currently opening: the endpoints described here are stable in principle, but some details may still change. Changes will be announced on this page.

The Pro API gives you the same tools as the website: conversions, compression, OCR, merging, and the AI assistant features. A job always runs in four steps: you create it, upload the files, start it, then fetch the result (by polling or through a webhook).

Every request uses HTTPS and returns JSON. Files never go through the API itself: they're sent straight to private storage through short-lived signed URLs.

Authentication

Create a key from your account (API section). It starts with efp_live_ and is shown only once: we only keep a fingerprint of it. Send it in the Authorization header of every request.

Treat this key like a password: never in browser-side code, never in a public repository. You can revoke it at any time; a revoked key stops working immediately.

Header
Authorization: Bearer efp_live_XXXXXXXXXXXXXXXX

Available tools

Each tool is referenced by its identifier, the same as in our registry. Tools that run in the browser on the website run on our servers when called through the API. Each tool's parameters mirror the options on its page.

IdentifierToolFamilyOutput
mergeMerge PDFClassicPDF
splitSplit PDFClassicPDF / ZIP
rotateRotate PDFClassicPDF
delete-pagesDelete PDF pagesClassicPDF
organizeOrganize PDF pagesClassicPDF
cropCrop PDFClassicPDF
watermarkAdd a watermarkClassicPDF
add-imageAdd an image to PDFClassicPDF
page-numbersAdd page numbersClassicPDF
signSign PDFClassicPDF
editEdit PDFClassicPDF
compressCompress PDFClassicPDF
compress-imageCompress imageClassicJPG / PNG / WebP
ocrOCR: make a PDF searchableClassicPDF / TXT
pdf-to-wordPDF to WordClassicDOCX
pdf-to-excelPDF to ExcelClassicXLSX
pdf-to-powerpointPDF to PowerPointClassicPPTX
pdf-to-jpgPDF to JPGClassicJPG / ZIP
pdf-to-pngPDF to PNGClassicPNG / ZIP
pdf-to-textPDF to textClassicTXT
word-to-pdfWord to PDFClassicPDF
excel-to-pdfExcel to PDFClassicPDF
powerpoint-to-pdfPowerPoint to PDFClassicPDF
jpg-to-pdfJPG to PDFClassicPDF
png-to-pdfPNG to PDFClassicPDF
html-to-pdfHTML to PDFClassicPDF
protectProtect PDFClassicPDF
unlockUnlock PDFClassicPDF
metadataPDF metadataClassicPDF
ai-chatChat with your PDFAIRéponses citées / Cited answers
ai-summarizeSummarize PDFAITexte / DOCX / PDF
ai-translateTranslate PDFAIPDF / DOCX
ai-ocrSmart OCRAIDOCX / Markdown / PDF
ai-extractExtract dataAIXLSX / CSV / JSON
ai-fillAssisted form fillingAIPDF
ai-rewriteRewrite and proofreadAIPDF
ai-generateGenerate a documentAIPDF

Create a job

Declare the tool, its parameters and the list of files (name, size in bytes, MIME type). Your account limits are checked at this point: if one is exceeded, the response explains which. Quota is only consumed for good if the job succeeds.

Request
curl -X POST "https://eflypdf.com/api/v1/jobs" \
  -H "Authorization: Bearer efp_live_XXXXXXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "compress",
    "params": { "mode": "recommended" },
    "files": [{ "name": "rapport.pdf", "size": 2483021, "mime": "application/pdf" }]
  }'
Response
{
  "jobId": "4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10",
  "uploads": [
    { "path": "…/4f6c1d2e…/0-rapport.pdf", "signedUrl": "https://…", "token": "…" }
  ]
}

Upload the files

Send each file to its signed URL, in list order. These URLs expire quickly: upload right after creating the job. Every file is virus-scanned before processing.

Request
curl -X PUT "<signedUrl>" \
  -H "Content-Type: application/pdf" \
  --data-binary @rapport.pdf

Start and track the job

Once the files are uploaded, start the job. It moves through queued, running, then succeeded or failed. Poll it at a reasonable interval (every 2 to 5 seconds) or, better, subscribe to webhooks.

API jobs get the Pro plan's high priority in the queue.

Start
curl -X POST "https://eflypdf.com/api/v1/jobs/4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10/start" \
  -H "Authorization: Bearer efp_live_XXXXXXXXXXXXXXXX"
Track
curl "https://eflypdf.com/api/v1/jobs/4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10" \
  -H "Authorization: Bearer efp_live_XXXXXXXXXXXXXXXX"
Response
{
  "id": "4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10",
  "tool": "compress",
  "status": "succeeded",
  "progress": 100,
  "error": null,
  "expiresAt": "2026-10-21T15:00:00Z"
}

Download the result

The download endpoint answers with a redirect to a temporary signed URL. The result stays available for your plan's retention period, then it's deleted automatically along with the source files.

Request
curl -L "https://eflypdf.com/api/v1/jobs/4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10/download" \
  -H "Authorization: Bearer efp_live_XXXXXXXXXXXXXXXX" \
  -o resultat.pdf

Signed webhooks

Register an HTTPS URL in your account and choose the events (job.done, job.failed). Each delivery carries the X-Signature header: t is the Unix timestamp, v1 the hex HMAC-SHA256 signature of the string "t.raw_body" computed with the webhook secret.

Always verify the signature and reject stale messages. Reply with a 2xx code within 10 seconds; on failure, delivery is retried several times with increasing delays. The same event may arrive twice: deduplicate on its id.

Sample delivery
POST https://votre-serveur.example/webhooks
X-Signature: t=1792335600,v1=5f2b…c9e1
Content-Type: application/json

{
  "event": "job.done",
  "jobId": "4f6c1d2e-8a0b-4c7e-9d51-2b8f0e3a9c10",
  "tool": "compress",
  "status": "done",
  "errorCode": null,
  "createdAt": "2026-10-19T15:00:00Z"
}
Verification (Node.js)
import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody: string, header: string, secret: string, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const given = Buffer.from(parts.v1 ?? "", "hex");
  return given.length === 32 && timingSafeEqual(given, Buffer.from(expected, "hex"));
}

Quotas and limits

The API has no separate quota: it uses exactly the same counters as your Pro account on the website (AI pages, translation words, file size, batches). The values below are read from our live configuration.

Rate limiting protects the service: beyond the allowed number of requests per minute, the response is 429. Wait a few seconds before retrying.

LimitValue (Pro plan)
Maximum file size1 GB
Files per run (batch)100 files
Operations per dayUnlimited
AI pages2,000 AI pages per month
Translation500,000 words per month
Document size for chat2,000 pages
Documents open in chat10 documents
Assistant modelFast or advanced (×20 AI pages)
Requests per minute (per account)120

Errors

Errors use the usual HTTP codes: 400 (invalid request), 401 (missing or revoked key), 402 (plan limit reached), 404 (unknown job), 429 (rate or daily quota), 503 (assistant temporarily unavailable: nothing is counted). Limit refusals carry an explicit code.

Example
HTTP/1.1 402 Payment Required
{
  "error": "limit",
  "refused": { "code": "AI_PAGES_EXHAUSTED", "max": 2000, "current": 2000, "resetAt": "2026-11-03T00:00:00Z", "upgradeTo": null }
}