Base URL

When running locally via Docker, the base URL is:

http://localhost:8080

In production, replace with your deployment URL. All endpoints are relative to this base URL.

ℹ️
See the Docker Guide for instructions on running the service and enabling authentication.

POST /api/render

Converts an HTML string to a PDF document. Returns the PDF as a binary response.

Request

PropertyTypeRequiredDescription
htmlstring✅ YesThe HTML document to render
optionsobjectNoRender options (see below)

Response

HeaderValue
Content-Typeapplication/pdf
Content-Dispositioninline; filename="document.pdf"

Minimal example

JSON Request Body
{
  "html": "<h1>Hello, EggPdf!</h1><p>Pure C# PDF rendering.</p>"
}

Full example with options

JSON Request Body
{
  "html": "<!DOCTYPE html><html><body><h1>Report</h1></body></html>",
  "options": {
    "pageSize":  "A4",
    "margins":   { "top": 60, "right": 50, "bottom": 60, "left": 50 },
    "title":     "Q4 Report",
    "footer":    "Page {page} of {pages}",
    "header":    "Acme Corp — Confidential"
  }
}

Options Reference

FieldTypeDefaultDescription
pageSizestring"A4"Page size: A3, A4, A5, Letter, Legal
margins.topnumber40Top margin in CSS pixels
margins.rightnumber40Right margin in CSS pixels
margins.bottomnumber40Bottom margin in CSS pixels
margins.leftnumber40Left margin in CSS pixels
titlestringnullPDF document title metadata
footerstringnullFooter template. Supports {page} and {pages}
headerstringnullHeader template. Supports {page} and {pages}
landscapebooleanfalseRender in landscape orientation

GET /health

Returns the health status of the service. Use this for liveness probes in Kubernetes, ECS, or other orchestrators.

Response

HTTP/1.1 200 OK
Content-Type: application/json

{
  "status":  "Healthy",
  "version": "0.3.0"
}

curl Examples

Minimal — save to file

curl -X POST http://localhost:8080/api/render \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1>Hello</h1>"}' \
  --output hello.pdf

With options

curl -X POST http://localhost:8080/api/render \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<!DOCTYPE html><html><body><h1>Invoice #42</h1></body></html>",
    "options": {
      "pageSize": "Letter",
      "title": "Invoice #42",
      "footer": "Page {page} of {pages}",
      "margins": { "top": 60, "right": 50, "bottom": 60, "left": 50 }
    }
  }' \
  --output invoice-42.pdf

From an HTML file

# Read HTML from file and send as JSON
HTML=$(cat report.html | python3 -c "import sys,json; print(json.dumps(sys.stdin.read()))")
curl -X POST http://localhost:8080/api/render \
  -H "Content-Type: application/json" \
  -d "{\"html\": $HTML}" \
  --output report.pdf

Health check

curl http://localhost:8080/health

Python Example

render_pdf.py
import requests

EGGPDF_URL = "http://localhost:8080"

def render_pdf(html: str, options: dict = None) -> bytes:
    payload = {"html": html}
    if options:
        payload["options"] = options

    response = requests.post(
        f"{EGGPDF_URL}/api/render",
        json=payload,
        timeout=30,
    )
    response.raise_for_status()
    return response.content


# Basic usage
pdf_bytes = render_pdf("<h1>Hello from Python</h1>")
with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print(f"PDF saved: {len(pdf_bytes):,} bytes")

# With options
pdf_bytes = render_pdf(
    "<h1>Invoice</h1>",
    options={
        "pageSize": "Letter",
        "title": "Invoice #42",
        "footer": "Page {page} of {pages}",
    },
)

Node.js Example

renderPdf.mjs
const EGGPDF_URL = 'http://localhost:8080';

async function renderPdf(html, options = {}) {
  const response = await fetch(`${EGGPDF_URL}/api/render`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ html, options }),
  });

  if (!response.ok) {
    const text = await response.text();
    throw new Error(`EggPdf error ${response.status}: ${text}`);
  }

  return Buffer.from(await response.arrayBuffer());
}

// Basic usage
const pdf = await renderPdf('<h1>Hello from Node.js</h1>');
await fs.writeFile('output.pdf', pdf);
console.log(`PDF saved: ${pdf.length.toLocaleString()} bytes`);

// With options — return as HTTP response (Express example)
app.get('/invoice/:id', async (req, res) => {
  const html = await buildInvoiceHtml(req.params.id);
  const pdf = await renderPdf(html, {
    pageSize: 'A4',
    title: `Invoice #${req.params.id}`,
    footer: 'Page {page} of {pages}',
  });
  res.setHeader('Content-Type', 'application/pdf');
  res.send(pdf);
});

Error Responses

On failure, the API returns a JSON error body with an error field:

StatusMeaning
400 Bad RequestMissing or malformed request body (e.g. no html field)
401 UnauthorizedMissing or invalid X-Api-Key header when auth is enabled
500 Internal Server ErrorUnexpected rendering failure (includes error message in body)
// 400 example
{ "error": "The 'html' field is required." }