Skip to main content
PapyDocs

PapyDocs for developers

The Papy API brings PapyDocs document processing into your applications, websites and software through a simple, versioned REST interface.

  • Every documented endpoint runs the same engines as the PapyDocs tools.
  • Keys are stored as hashes, shown once, and can be rotated or revoked.
  • Files are processed in memory and never stored; only usage counters are kept.

Checking availability…

Quick start

  1. Ask the administrator of this PapyDocs deployment for an API key (created in “Keys and usage” below).
  2. Send a multipart/form-data POST request to /api/v1/OPERATION with your PDF files and parameters.
  3. Add the header Authorization: Bearer YOUR_KEY to every request.
  4. Read the JSON result, or save the PDF or ZIP returned. Errors always come back as JSON with a stable code.
List the operations available on this deployment
curl https://papydocs.com/api/v1

Authentication

Every request is authenticated with an API key sent in the Authorization header.

HTTP
Authorization: Bearer papy_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • PapyDocs stores only a SHA-256 hash of each key, never the key itself.
  • A new key is displayed once, when it is created. Store it in your secrets manager: it cannot be shown again.
  • Rotation issues a new key and revokes the old one immediately; revocation takes effect on the next request.
  • Call the API from your server. Never put a key in a web page or a mobile app bundle.

Endpoint reference

All operations are POST requests to /api/v1/OPERATION with a multipart/form-data body. JSON operations return application/json; file operations return the PDF or ZIP directly.

Document operations

POST/api/v1/info— Document information

Returns the page count, size and metadata of a PDF.

FieldTypeRequired
filePDF fileYes

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/info" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf"
Example response (abridged)
{
  "pages": 2,
  "bytes": 48213,
  "metadata": {
    "title": "Contract",
    "author": "",
    "subject": "",
    "keywords": "",
    "creator": "",
    "producer": "pdf-lib",
    "creationDate": "2026-10-14T09:00:00.000Z",
    "modificationDate": null,
    "customKeys": [],
    "hasXmp": false,
    "hasJavaScript": false,
    "hasEmbeddedFiles": false,
    "pageCount": 2
  }
}

POST/api/v1/merge— Merge

Merges several PDFs in the order they are sent.

FieldTypeRequired
filesSeveral PDF filesYes

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/merge" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "files=@document.pdf" \
  -F "files=@other.pdf" \
  -o result.pdf

POST/api/v1/split— Split

Splits a PDF by page ranges (e.g. 1-2,5) or into one file per page; returns a ZIP.

FieldTypeRequired
filePDF fileYes
modeOne of (ranges | every-page)No
rangesTextNo

Response: ZIP archive of PDF files

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/split" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'mode=ranges' \
  -F 'ranges=1-2,5' \
  -o result.zip

POST/api/v1/compress— Compress

Lossless structural optimisation of a PDF (images are not re-encoded).

FieldTypeRequired
filePDF fileYes

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/compress" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -o result.pdf

POST/api/v1/rotate— Rotate

Rotates every page by 90, 180 or 270 degrees.

FieldTypeRequired
filePDF fileYes
angleOne of (90 | 180 | 270)No

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/rotate" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'angle=90' \
  -o result.pdf

POST/api/v1/page-numbers— Page numbers

Adds page numbers from a template using the {page} and {total} placeholders (Latin characters).

FieldTypeRequired
filePDF fileYes
formatTextNo
startNumberNo

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/page-numbers" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'format={page} / {total}' \
  -F 'start=1' \
  -o result.pdf

POST/api/v1/watermark— Watermark

Adds a diagonal text watermark on every page (Latin characters).

FieldTypeRequired
filePDF fileYes
textTextYes
opacityNumberNo

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/watermark" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'text=CONFIDENTIAL' \
  -F 'opacity=0.2' \
  -o result.pdf

Document intelligence

POST/api/v1/text— Extract text

Returns the text of each page and whether the document looks scanned (needsOcr). No OCR is performed on the server.

FieldTypeRequired
filePDF fileYes

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/text" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf"
Example response (abridged)
{
  "pages": [
    {
      "page": 1,
      "text": "Facture N° FAC-2026-0042\nTotal TTC 144,00 €"
    }
  ],
  "characters": 41,
  "needsOcr": false
}

POST/api/v1/invoice— Extract invoice data

Extracts supplier, customer, number, dates, currency, amounts, line items, payment terms and order reference, each with its source page and line, plus consistency checks. Missing values are returned as null, never estimated.

FieldTypeRequired
filePDF fileYes

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/invoice" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf"
Example response (abridged)
{
  "fields": {
    "invoiceNumber": {
      "value": "FAC-2026-0042",
      "status": "found",
      "source": {
        "pageNumber": 1,
        "excerpt": "Facture N° FAC-2026-0042"
      }
    },
    "total": {
      "value": "144",
      "status": "found",
      "source": {
        "pageNumber": 1,
        "excerpt": "Total TTC 144,00 €"
      }
    },
    "dueDate": {
      "value": null,
      "status": "missing",
      "source": null
    }
  },
  "lineItems": [
    {
      "description": "Ramette papier A4",
      "quantity": 10,
      "unitPrice": 5,
      "amount": 50,
      "source": {
        "pageNumber": 1,
        "excerpt": "Ramette papier A4 10 5,00 € 50,00 €"
      }
    }
  ],
  "checks": [
    {
      "code": "missing",
      "field": "dueDate"
    }
  ]
}

POST/api/v1/contract— Analyse a contract

Returns clause headings, passages by topic (parties, payment, duration, termination…), dates, amounts, notice periods and passages to check, all copied from the document with their page. Keyword-based pointers, not legal advice.

FieldTypeRequired
filePDF fileYes

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/contract" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf"
Example response (abridged)
{
  "notice": "Passages are copied from the document; categories and flags are keyword-based pointers to verify, not legal advice.",
  "pageCount": 2,
  "clauses": [
    {
      "heading": "Article 7 - Résiliation",
      "pageNumber": 2
    }
  ],
  "findings": [
    {
      "category": "termination",
      "pageNumber": 2,
      "clause": "Article 7 - Résiliation",
      "excerpt": "Chaque partie peut résilier le contrat moyennant un préavis de 3 mois."
    }
  ],
  "flags": [
    {
      "reason": "auto-renewal",
      "pageNumber": 1,
      "clause": "Article 2 - Durée",
      "excerpt": "Il est renouvelé par tacite reconduction…",
      "match": "tacite reconduction"
    }
  ],
  "facts": [
    {
      "type": "notice",
      "value": "préavis de 3 mois",
      "pageNumber": 2,
      "clause": "Article 7 - Résiliation",
      "excerpt": "…"
    }
  ],
  "sentenceCount": 14
}

POST/api/v1/compare— Compare two versions

Compares the text of two PDFs page by page and returns the added, deleted and modified passages with their context.

FieldTypeRequired
originalPDF fileYes
revisedPDF fileYes

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/compare" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "original=@contract-v1.pdf" \
  -F "revised=@contract-v2.pdf"
Example response (abridged)
{
  "identical": false,
  "pageCountOriginal": 2,
  "pageCountRevised": 2,
  "wordsAdded": 11,
  "wordsRemoved": 1,
  "changes": [
    {
      "type": "modified",
      "pageNumber": 1,
      "before": "12",
      "after": "24",
      "context": "Le contrat est conclu pour une durée de 24 mois."
    }
  ]
}

POST/api/v1/proofread— Proofread

Runs the PapyDocs local proofreading rules (spacing, punctuation, repeated words, capitals, common misspellings) and returns each issue with its correction and position.

FieldTypeRequired
filePDF fileYes
languageOne of (auto | fr | en | es | pt)No

Response: JSON

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/proofread" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'language=auto'
Example response (abridged)
{
  "language": "fr",
  "engine": "local-rules",
  "issues": [
    {
      "page": 1,
      "start": 11,
      "end": 15,
      "original": "recu",
      "suggestion": "reçu",
      "category": "spelling",
      "rule": "misspelling"
    }
  ]
}

Security and privacy

POST/api/v1/remove-metadata— Remove metadata

Removes document metadata and active content (JavaScript, embedded files).

FieldTypeRequired
filePDF fileYes

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/remove-metadata" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -o result.pdf

POST/api/v1/protect— Protect with a password

Encrypts a PDF (AES-256) with an opening password.

FieldTypeRequired
filePDF fileYes
passwordTextYes
owner_passwordTextNo

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/protect" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'password=your-password' \
  -o result.pdf

POST/api/v1/unlock— Remove a password

Decrypts a PDF when the correct password is supplied.

FieldTypeRequired
filePDF fileYes
passwordTextYes

Response: PDF file

Code samples and example response
cURL
curl -X POST "https://papydocs.com/api/v1/unlock" \
  -H "Authorization: Bearer $PAPY_API_KEY" \
  -F "file=@document.pdf" \
  -F 'password=your-password' \
  -o result.pdf

Key-management endpoints

Reserved for the deployment administrator, authenticated with the administrator token (not with an API key). They are used by the “Keys and usage” section of this page.

  • GET/api/v1/keys— List keys (without secrets)
  • POST/api/v1/keys— Create a key (JSON body with a name); the secret is returned once
  • DELETE/api/v1/keys/{id}— Revoke a key
  • POST/api/v1/keys/{id}/rotate— Rotate a key; the new secret is returned once
  • GET/api/v1/usage?days=30— Usage counters per day, key and operation

Errors and limits

Errors use standard HTTP status codes and a JSON body with a stable, machine-readable code. Messages are not localised: map the code in your application.

Error format
{
  "error": {
    "code": "authorization-required"
  }
}
StatusMeaningError codes
200Success
400Missing or invalid parameterinvalid-options, empty-selection
401Missing, invalid or revoked key (or administrator token)authorization-required
404Unknown operation or keyinvalid-options
413Request or file too largerequest-too-large, file-too-large
415The file is not a PDFunsupported-type
422The PDF cannot be processed (damaged, encrypted, wrong password, no text…)corrupt, encrypted, wrong-password, no-text, invalid-range
429Hourly limit reached: wait for the number of seconds given in Retry-Afterrate-limited
503The API, or key management, is not enabled on this deploymentserver-unavailable

Limits

  • Default limit: 120 requests per hour and per key (configurable by the deployment).
  • Each response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (seconds).
  • Up to 100 MB per PDF, 200 MB per request and 60 files per request.
  • Text operations read up to 500 pages per document; search queries are limited to 200 characters and 100 results.
  • Scanned documents without a text layer are refused by the analysis operations (error no-text): run OCR first, for example with the PapyDocs OCR tool.

Test console

Send a real request to this deployment with your key. The key stays in this page’s memory, is sent only to this site and is never stored. The files you choose are sent to the API for this request only.

Starts with papy_. Not saved.

Keys and usage

For the administrator of this deployment. Enter the administrator token configured on the server (its hash is set in PAPY_ADMIN_TOKEN_HASH). The token stays in this page’s memory only.

Not saved. Sent only to this site.

Data protection

  • Files sent to the API are processed in memory for the duration of the request and are not stored.
  • PapyDocs does not write document content, file names, parameters or keys to its logs.
  • Usage statistics are aggregate counters kept for 90 days.
  • Use HTTPS only. The API runs PapyDocs’ own engines on this server; it does not send your documents to an AI provider.