Skip to main content

pdfik

Official Python SDK for PDFik — the premium, fast, and reliable PDF generation API.

Convert HTML markup or any public URL into pixel-perfect PDF documents in seconds, powered by scalable browser rendering.

Features

  • Type Safety: Type hints for all options and response objects.
  • Sync & Async: Exposes both PdfikClient and AsyncPdfikClient using the modern httpx engine.
  • Auto Retry: Automatic exponential backoff for 5xx and 429 (Rate Limit) errors powered by tenacity.
  • DX Affordances: Built-in polling logic (wait_for_job) and file download helpers.

Installation

pip install pdfik

Quick Start

Convert public URL to PDF (Sync)

from pdfik import PdfikClient, PdfOptions, MarginOptions

# Initialize the client
client = PdfikClient(api_key="sk_live_...")

# 1. Submit the URL to be rendered
job = client.url_to_pdf(
    "https://example.com",
    options=PdfOptions(
        format="A4",
        landscape=False,
        print_background=True,
        margin=MarginOptions(top="10mm", bottom="10mm")
    )
)

print(f"Job created: {job.job_id}. Waiting for rendering...")

# 2. Poll until the job completes
result = client.wait_for_job(job.job_id)
print(f"Job finished! Pages: {result.pages_count}")

# 3. Download the PDF bytes
pdf_bytes = client.download_pdf(job.job_id)

with open("output.pdf", "wb") as f:
    f.write(pdf_bytes)
print("PDF saved to output.pdf")

# Close connection pool
client.close()

Convert raw HTML to PDF (Async)

import asyncio
from pdfik import AsyncPdfikClient, PdfOptions

async def main():
    async with AsyncPdfikClient(api_key="sk_live_...") as client:
        job = await client.html_to_pdf(
            "<h1>Hello World</h1><p>Sent from PDFik Python SDK</p>",
            options=PdfOptions(format="Letter")
        )
        
        result = await client.wait_for_job(job.job_id)
        print(f"Job finished! Status: {result.status}")
        
        pdf_bytes = await client.download_pdf(job.job_id)

asyncio.run(main())

Get the direct download URL

Get the direct API download URL for the generated PDF (requires the "X-API-Key" header to download):

file_info = client.get_file_url(job.job_id)
print(f"Direct Download URL: {file_info.download_url}")

Test mode

Pass test=True to run a job through the full pipeline (statuses, webhook, download) without real rendering — the download returns a small sample PDF. Test jobs are free (no PDF or byte quota is debited) and rate-limited instead: 60 test calls per minute and 2,000 per day per account. Job status and webhook payloads always carry test: true|false, so you can safely exercise your integration end to end:

job = client.url_to_pdf("https://example.com", test=True)
result = client.wait_for_job(job.job_id)
print(result.test)        # True
print(result.expires_at)  # e.g. "2026-08-05T12:00:00Z"

pdf_bytes = client.download_pdf(job.job_id)  # sample PDF

Limits, retention and error codes

  • Generated volume per month (byte quota, counts rendered output only — downloads are free): Free 0.5 GB, Starter 10 GB, Pro 50 GB, Business 300 GB. Business plans can purchase additional +1 GB blocks from the dashboard. Exceeding the quota returns 429 (quota-bytes-exceeded).
  • File size: up to 150 MB per PDF on every plan — contact support if you need more. A larger render fails the job with FILE_TOO_LARGE (file-too-large).
  • Retention: each file is available for download for 24 hours after the job finishes; the exact deadline is the expires_at field in the job status and webhook payload. After that the download returns 410 (file-expired).
  • Downloads: at most 3 download attempts per file (counted when the stream starts); after that the API returns 429 (download-attempts-exhausted) — re-render the file or contact support. Only 1 download stream may be active at a time; a concurrent request returns 429 (download-busy) — wait ~10 seconds and retry, it does not burn an attempt.

Handling Webhooks

If you specify webhook_url in the options of url_to_pdf or html_to_pdf, PDFik will send an HTTP POST request to your server when the rendering job is finished.

You should verify the authenticity of the webhook by validating the signature. We provide a static helper verify_webhook_signature in PdfikClient for this purpose.

During a secret rotation both the new and the previous secret verify for the overlap window you pick in the dashboard (1 hour to 5 days, or none at all), so check the new one first and fall back to the old one while you roll your receivers out.

Custom delivery headers (e.g. a Cloudflare Access service token) are configured once on the dashboard Webhooks page and attached to every delivery — nothing to pass per request.

Example (FastAPI):

from fastapi import FastAPI, Request, HTTPException
from pdfik import PdfikClient

app = FastAPI()

# Get your webhook secret from the PDFik Dashboard
WEBHOOK_SECRET = "whsec_..."

@app.post("/webhook")
async def handle_webhook(request: Request):
    # Retrieve headers
    headers = dict(request.headers)
    
    # Retrieve the raw payload bytes
    raw_body = await request.body()
    
    # Verify signature
    is_valid = PdfikClient.verify_webhook_signature(raw_body, headers, WEBHOOK_SECRET)
    
    if not is_valid:
        raise HTTPException(status_code=400, detail="Invalid signature")
        
    # Process event
    event = await request.json()
    print(f"Received webhook event: {event.get('event_type')} for job: {event.get('job_id')}")
    
    return {"received": True}

License

MIT License.

Metadata

Release files for pdfik 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pdfik 0.2.2
File Size Uploaded
pdfik-0.2.2.tar.gz 9.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pdfik 0.2.2
File Interpreter ABI Platform
pdfik-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 17.8 kB

Release files / pdfik-0.2.2.tar.gz

Download URL pdfik-0.2.2.tar.gz
Size 9.0 kB
Tags Source
SHA-256 checksum
How to use checksums
640ac30c7f63dbe922f27a720f20d9f8a481f1c966a13a8c9d73b2670cf5e66c
BLAKE2b-256 checksum
How to use checksums
95d630c08a7746560bae2db5d5205bda82b8ce12dc8230b1846233d9e4bde5dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / pdfik-0.2.2-py3-none-any.whl

Download URL pdfik-0.2.2-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b654f5d27c63a7c88b51e91bad943f5ae6fea3693e7d89ca5e7d5f486cc92bed
BLAKE2b-256 checksum
How to use checksums
1419f26ae100b456531b0e9a610844edd82269d91c23884872c8f32256b322f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release history Release notifications | RSS feed

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

This release

0.2.2 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page