Public PDF API

A public REST API for converting arbitrary HTML and CSS to PDF. This API is independent of book content and can be used by any external system. It proxies requests to the WeasyPrint-based PDF server.

The API requires a dedicated API key for authentication and provides an asynchronous conversion workflow: start a job, poll for status, download the result.

Configuration

Environment variables:

  • PDFSERVER_URL - PDF server URL (default: http://localhost:8040)

Registry records:

  • wcs.backend.pdfserver.pub.apikey - The API key that clients must provide. Configurable via the Plone control panel or GenericSetup registry export.

Authentication

All requests must include the X-PDFServer-API-Key header with a valid key.

Requests with a missing, invalid, or unconfigured API key receive a 401 Unauthorized response:

{
    "error": "Invalid or missing API key"
}

Endpoints

POST @pdfserver-pub-convert

Starts an asynchronous HTML-to-PDF conversion.

const response = await fetch('https://example.com/@pdfserver-pub-convert', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-PDFServer-API-Key': '<your-api-key>',
  },
  body: JSON.stringify({
    html: '<html><body><h1>Hello</h1></body></html>',
    css: 'h1 { color: navy; }',
    filename: 'report.pdf',
  }),
});
import requests

response = requests.post(
    'https://example.com/@pdfserver-pub-convert',
    headers={
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-PDFServer-API-Key': '<your-api-key>',
    },
    json={
        'html': '<html><body><h1>Hello</h1></body></html>',
        'css': 'h1 { color: navy; }',
        'filename': 'report.pdf',
    },
)

Request Body:

Field

Required

Description

html

Yes

HTML content to convert.

css

No

CSS stylesheet as a string. Defaults to empty.

filename

No

Output filename. Defaults to output.pdf.

Response (200):

{
    "uid": "550e8400-e29b-41d4-a716-446655440000",
    "filename": "report.pdf",
    "status": "running"
}

GET @pdfserver-pub-status

Polls the conversion job status.

const status = await fetch(
  'https://example.com/@pdfserver-pub-status?uid=550e8400-...',
  {
    headers: {
      'Accept': 'application/json',
      'X-PDFServer-API-Key': '<your-api-key>',
    },
  }
);

Query Parameters:

  • uid (required) - The job UID returned by the convert endpoint.

Response (200):

{
    "uid": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "filename": "report.pdf",
    "download": "/pdf/550e8400-e29b-41d4-a716-446655440000"
}

Possible status values: running, completed, failed.

GET @pdfserver-pub-download

Downloads the generated PDF once the job status is completed.

const pdf = await fetch(
  'https://example.com/@pdfserver-pub-download?uid=550e8400-...',
  { headers: { 'X-PDFServer-API-Key': '<your-api-key>' } }
);
const blob = await pdf.blob();

Query Parameters:

  • uid (required) - The job UID returned by the convert endpoint.

Response: Binary PDF file with Content-Type: application/pdf.

File Locations

  • wcs/backend/pdfserver_pub/restapi.py - REST API endpoints

  • wcs/backend/pdfserver_pub/auth.py - API key validation

  • wcs/backend/pdfserver_pub/configure.zcml - ZCML registration

  • wcs/backend/book/pdfserver_client.py - PDF server client (shared with book PDF export)