Documentation

Local REST API for synchronous PDF generation from structured JSON data.

Example PDF Output (Default template)

Templates are customized per customer and provided and deployed by the OnPremPDF team.

This is an example of a PDF generated from a JSON payload using the default template.

Open example PDF

Quick Test (1 minute)

Info: You can test the sandbox with your demo API key. A simple example looks like this:


curl -X POST https://sandbox.pdfmotor.net/v1/render \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_DEMO_KEY" \
  -d '{
    "template": "default",
    "title": "Demo PDF",
    "subtitle": "Generated via PDF Motor",
    "fields": [
      { "label": "Name", "value": "John Doe" },
      { "label": "Email", "value": "john@example.com" }
    ]
  }' \
  -o document.pdf

The generated PDF is streamed directly to you as document.pdf. PDFs are never stored on server-side.



Note: On some systems (especially Windows), multiline JSON may fail with 400 Invalid JSON. Use the one-line example below if needed.


curl -X POST https://sandbox.pdfmotor.net/v1/render -H "Content-Type: application/json" -H "X-API-Key: YOUR_DEMO_KEY" -d "{\"template\":\"default\",\"title\":\"Sandbox Test\",\"subtitle\":\"First API Call\",\"fields\":[{\"label\":\"Name\",\"value\":\"John Doe\"},{\"label\":\"Email\",\"value\":\"john@example.com\"}],\"footer\":\"Generated with PDF Motor\"}" -o sandbox-test.pdf

API Endpoint

The endpoint synchronously generates a PDF document and returns it directly as the HTTP response.


POST http://sandbox.pdfmotor.net/v1/render
Content-Type: application/json
X-API-Key: sk_live_***

Request Body (JSON)

JSON structure sent in the body of the POST /v1/render request.

  • Each field represents one row in the PDF
  • Order is preserved
  • Dynamically extensible
  • Custom tempaltes are scoped to API key

: The fields array can contain an arbitrary number of entries. Each entry is rendered as a separate row in the generated PDF.

{
  "template": "default",
  "title": "Damage Report",
  "subtitle": "Date: 2026-01-10",
  "fields": [
    { "label": "Type", "value": "Water damage" },
    { "label": "Description", "value": "Water is leaking" },
    { "label": "Name", "value": "John Doe" },
   { "label": "E-Mail", "value": "john@example.de" }
  ],
  "footer": "Generated on 2026-01-11"
}

Request Parameters

The API key is provided via HTTP header. All other parameters are sent as JSON in the request body.

Parameter Type Description Default
X-API-Key string API key used for authentication (HTTP header) required
template string PDF layout template to use for rendering
Example: "default", "invoice", "report"
default
title string Document title null
subtitle string Subtitle (e.g. date or reference) null
fields array List of label/value objects []
footer string Footer text null
Note: Templates are scoped to your API key. Each API key has access only to its own templates. Templates cannot be accessed, listed, or used by other customers.

Templates

Templates are custom-built per customer and deployed within your environment. They are not shared, listed, or accessible across accounts.

Templates define the visual layout and structure of generated PDF documents. They control typography, spacing, tables, branding, and overall document design.

Each customer environment includes a default template for immediate use. Additional templates can be designed and deployed based on your specific document requirements.

Selecting a template

The template used for rendering can be specified via the optional template field in the request body. If omitted, the default template is applied automatically.

{
  "template": "default"
}
Scope: Templates are bound to your API key or on-premise instance. Only templates deployed within your environment can be used for rendering.

Custom template example

Below is an example of a customer-specific template. Custom templates may include complex layouts such as table-based documents, invoices, certificates, reports or government forms.

Code Examples

This example uses the sandbox URL. You can test it freely.


import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

public class Example {

  public static void main(String[] args) throws Exception {

    String json = "{" +
      "\"template\":\"default\"," +
      "\"title\":\"Damage Report\"," +
      "\"subtitle\":\"Date: 2026-01-10\"," +
      "\"fields\":[" +
      "  {\"label\":\"Name\",\"value\":\"John Doe\"}," +
      "  {\"label\":\"Email\",\"value\":\"john@example.com\"}," +
      "  {\"label\":\"Damage Type\",\"value\":\"Water damage\"}" +
      "]," +
      "\"footer\":\"Generated with PDF Motor\"" +
      "}";

    URL url = new URL("https://sandbox.pdfmotor.net/v1/render");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();

    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type", "application/json");
    con.setRequestProperty("X-API-Key", "YOUR_DEMO_KEY");
    con.setDoOutput(true);

    try (OutputStream os = con.getOutputStream()) {
      os.write(json.getBytes(StandardCharsets.UTF_8));
    }

    int status = con.getResponseCode();
    System.out.println("HTTP Status: " + status);

    if (status != 200) {
      throw new RuntimeException("HTTP error: " + status);
    }

    try (InputStream is = con.getInputStream()) {
      Files.copy(
        is,
        Path.of("document.pdf"),
        java.nio.file.StandardCopyOption.REPLACE_EXISTING
      );
    }

    System.out.println("PDF generated: document.pdf");
  }
}

HTTP Responses & Error Messages

The API uses standard HTTP status codes to indicate the outcome of a request. Successful responses return the generated PDF directly in the response body.

HTTP Code Meaning Description
200 OK PDF generated successfully. The PDF document is returned directly in the HTTP response body.
400 Bad Request Invalid or unparsable JSON, or an incorrect Content-Type header.
422 Unprocessable Entity Required fields are missing (e.g. title or fields).
429 Too Many Requests The daily request limit of the API key or license has been reached.
500 Internal Server Error An unexpected internal error occurred during PDF generation.