API reference

Generate a PDF with one POST request

Send HTML or a URL, get a finished PDF back in the response body. No SDK required — any HTTP client works. The free tier covers 50 documents a month.

Quick start

Create a free account, confirm your email, and your key is waiting in the dashboard. Then one request:

# 1. create a free account and copy your key from the dashboard
#    https://pdfgeny.com/account/signup/

# 2. render a document
curl -X POST https://pdfgeny.com/api/v1/render \
  -H "Authorization: Bearer $PDFGENY_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html":"<h1>Invoice 001</h1>"}' \
  --output invoice.pdf

Authentication

Every request carries your key in a header. X-API-Key works as well if a bearer token is awkward in your client. Keys are shown once at creation and stored hashed — if you lose one, revoke it and create another in the dashboard.

Authorization: Bearer pg_your_key_here

POST /api/v1/render

Send exactly one of html or url. The response is the PDF itself with Content-Type: application/pdf.

FieldTypeDefaultNotes
htmlstringMarkup to render. Up to 2 MB.
urlstringPage to load. Must start with http:// or https://.
formatstringA4A3, A4, A5, Letter, Legal, Tabloid.
landscapeboolfalseRotate the page.
marginstring12mmAny CSS length, applied to all four sides.
scalenumber1.0Between 0.1 and 2.
print_backgroundbooltrueKeep background colours and images.
filenamestringdocument.pdfSets Content-Disposition.

Two response headers are worth reading: X-Render-Duration-Ms and X-Quota-Remaining.

Examples

Python

import requests

pdf = requests.post(
    "https://pdfgeny.com/api/v1/render",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"html": "<h1>Invoice 001</h1>", "format": "A4"},
    timeout=60,
)
open("invoice.pdf", "wb").write(pdf.content)

Node.js

const res = await fetch("https://pdfgeny.com/api/v1/render", {
  method: "POST",
  headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://example.com/report", format: "Letter" }),
});
await writeFile("report.pdf", Buffer.from(await res.arrayBuffer()));

PHP

$ch = curl_init("https://pdfgeny.com/api/v1/render");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer $key", "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["html" => "<h1>Invoice</h1>"]),
]);
file_put_contents("invoice.pdf", curl_exec($ch));

Go

body, _ := json.Marshal(map[string]any{"html": "<h1>Invoice</h1>"})
req, _ := http.NewRequest("POST", "https://pdfgeny.com/api/v1/render", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+key)
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()

Quotas and errors

Check your remaining balance at any time:

curl https://pdfgeny.com/api/v1/usage -H "Authorization: Bearer $PDFGENY_KEY"
{"plan":"free","quota":50,"used":3,"remaining":47,"watermark":true,"resets":"2026-10-01"}

Errors share one shape: {"error": {"code": "quota_exceeded", "message": "…", "docs": "…"}}. Codes: missing_api_key, invalid_api_key, invalid_json, invalid_input, payload_too_large, quota_exceeded, render_failed.

StatusMeaning
401Key missing, unknown, revoked, or the account email is not confirmed yet.
400Malformed body, or neither/both of html and url.
413HTML payload above 2 MB.
422The page failed to render — bad markup, or a URL that never loaded.
429Monthly quota reached. The response names the plan and the limit.

Documents on the free plan carry a small footer line. Any paid plan removes it.