Docs
Python SDK
Use pip install relaypdf in Python when you want the official client instead of raw urllib. Request JSON field names match REST; methods are snake_case. The PyPI README is the full method and error reference.
The official Python SDK uses the standard library (urllib) and mirrors the Node client. Field names in request bodies match REST. Methods are snake_case.
Installation
Install from PyPI.
Package: relaypdf on PyPI. Current published line is 0.1.x. The PyPI README is the full method and error reference.
pip install relaypdfQuick start
api_key is required. Load it from the environment written by relaypdf setup.
import os
from relaypdf import RelayPDF
client = RelayPDF(api_key=os.environ["RELAYPDF_API_KEY"])
pdf = client.pdf.from_html(
"<h1>Invoice #1042</h1><p>Total: $1,200.00</p>",
filename="invoice.pdf",
)
pdf.save("invoice.pdf")
print(pdf.id, pdf.size_bytes)URL, Markdown, templates
Same sources as REST. from_template takes a published template id or slug plus a dict.
pdf = client.pdf.from_url(
"https://example.com",
filename="page.pdf",
options={"format": "A4", "printBackground": True},
)
md = client.pdf.from_markdown("# Hello\n\nFrom **Markdown**.")
invoice = client.pdf.from_template(
"invoice",
{"number": "INV-1042", "total": 1458},
filename="invoice.pdf",
strict=True,
)Binary, URL, and async results
Default is binary with a save() helper. response="url" returns a 24-hour link. response="async" returns a job; wait then download.
url_result = client.pdf.from_html("<h1>Hi</h1>", response="url")
print(url_result.url, url_result.expires_at)
job = client.convert.from_path("deck.pptx", to="pdf", response="async")
done = client.jobs.wait(job.id)
file = client.files.download(done["id"])
file.save("deck.pdf")Images, convert, merge
file values may be bytes or base64. from_path reads a local Office file and sets sourceFilename.
shot = client.images.from_url("https://example.com", options={"fullPage": True})
from_word = client.convert.from_path("letter.docx", to="pdf")
pack = client.pdf.merge(
files=[
{"url": "https://example.com/cover.pdf"},
{"file": from_word.bytes},
]
)
qr = client.barcodes.qr("https://relaypdf.com")Account, health, webhooks
health() is unauthenticated. verify_webhook needs the raw body bytes/str and the RelayPDF-Signature header.
from relaypdf import verify_webhook
print(client.health())
print(client.account())
ok = verify_webhook(os.environ["RELAYPDF_WEBHOOK_SECRET"], raw_body, signature_header)Errors
HTTP failures raise RelayPDFError with status, code, message, and optional retry_after.
from relaypdf import RelayPDF, RelayPDFError
try:
client.pdf.from_url("https://example.com")
except RelayPDFError as err:
print(err.status, err.code, err.message, err.retry_after)SDK reference
JSON bodies keep REST camelCase (printBackground, sourceFilename, templateId). Methods are snake_case. The PyPI README lists the same table.
Result classes: BinaryResult (save), UrlResult, AsyncResult. RelayPDFError has status, code, message, retry_after.
| Method | HTTP | Description |
|---|---|---|
| health() | GET /health | Liveness; no API key |
| account() | GET /v1/account | Plan, rate tier, millicents; not billed |
| pdf.from_html / from_url / from_markdown / from_template / create | POST /v1/pdf | HTML, URL, Markdown, or template → PDF |
| pdf.merge / extract / protect / unlock / bookmarks | POST /v1/pdf/* | Merge, extract, password, outline |
| pdf.raster / from_images / stamp / rotate / delete_pages / compress | POST /v1/pdf/* | Raster, images→PDF, stamp, rotate, delete, compress |
| pdf.info / text / data / form_fields / form_fill | POST /v1/pdf/info · /text · /data · /form/* | Inspect, extract, fill |
| images.from_html / from_url | POST /v1/images | Screenshot |
| convert.from_html / from_path / wkhtml / create | POST /v1/convert | LibreOffice or wkhtmltopdf |
| templates.list / gallery / get / create / update / delete / publish | /v1/templates | Handlebars drafts (Node has extra preview/generate helpers) |
| barcodes.create / qr | POST /v1/barcodes | Barcode / QR |
| zip.create | POST /v1/zip | Zip files |
| jobs.get / wait | GET /v1/jobs/:id | Poll or wait |
| files.download | GET /v1/files/:id | 24h download |
| webhooks.list / create / delete | GET/POST/DELETE /v1/webhooks | Signed endpoint CRUD |
| verify_webhook | RelayPDF-Signature | HMAC-SHA256 |
Document platform release support
The release adds ocr, pdfa, crop, resize, repair, optimize, attachments, extract-images, redact, compress, image-convert, and email processing. Every official SDK exposes process / ProcessAsync plus files.upload, files.delete, billingUsage / billing_usage, and billingLimits / billing_limits. Availability requires the matching released package. Older published versions may not contain these methods.
See /docs/files, /docs/billing, and each operation guide for field names and limits.
For safe retries, use URL or async output with Idempotency-Key. Per-request caps use X-RelayPDF-Max-Charge-Microdollars (integer millionths of USD). Billing APIs preserve microdollar precision; legacy account millicent fields are not the complete precise balance.
Native OCR with a per-job cap
Requires relaypdf 0.1.6 or a compatible newer release. Replace the example URL with your own publicly accessible scan. The 40000-microdollar cap authorizes at most $0.04; it is not a price estimate. Reuse the idempotency key only for retries of the same request.
client.files.upload / delete; client.billing_usage / billing_limits. Python also provides template discard, duplicate, versions, restore, validate, preview, and generate helpers.
Files and billing APIs do not require a separate client. See /docs/files, /docs/billing, and /docs/idempotency for ownership, precision, and retry behavior.
import os
from relaypdf import RelayPDF
client = RelayPDF(
api_key=os.environ["RELAYPDF_API_KEY"],
)
job = client.process(
"ocr",
{"url": "https://example.com/scan.pdf",
"response": "async"},
idempotency_key="scan-001",
max_charge_microdollars=40000,
)