Skip to main content

Tailprint Python SDK

PyPI version Python versions License: MIT

Official Python client for Tailprint (tailprint.com) — the developer-first programmable PDF and document engine.

Turns Tailwind CSS HTML, dynamic data, and AI prompts into pixel-perfect vector PDFs, European Factur-X / ZUGFeRD e-invoices, and provides full PDF manipulation operations (merge, split, fill forms, stamp, compress, validate).

  • Zero dependencies: Built entirely with standard library modules (urllib, json, base64, hmac). Installs in < 1 second with 0 dependency conflicts.
  • Async & Batch: Native support for asynchronous background rendering and concurrent multi-document batch runs.
  • Enterprise-Ready: Cryptographic webhook signature verification and zero-retention GDPR mode.

📦 Installation

pip install tailprint

🚀 Quickstart

import os
from tailprint import Tailprint

# Initialize with your API key (or set TAILPRINT_API_KEY environment variable)
tp = Tailprint(api_key=os.environ.get("TAILPRINT_API_KEY", "sec_live_..."))

# 1. Render Tailwind HTML to Vector PDF
pdf_bytes = tp.render_pdf(
    html="""
    <div class="p-12 bg-slate-900 text-white font-sans">
        <h1 class="text-3xl font-bold text-indigo-400">Quarterly Invoice</h1>
        <p class="text-slate-400 mt-2">Styled dynamically with Tailwind CSS.</p>
    </div>
    """,
    format="A4",
    smart_pagination=True,
)

with open("invoice.pdf", "wb") as f:
    f.write(pdf_bytes)

🧾 Hosted Templates (JSON in, PDF out)

Skip HTML: pass a template_id and your data. Totals are computed server-side and every value is HTML-escaped.

templates = client.list_templates()            # invoice-modern, receipt-minimal, certificate-classic, report-executive
example = client.get_template("invoice-modern")  # example_data + example_request

pdf = client.render_pdf(
    template_id="invoice-modern",
    data={
        "invoice_number": "INV-1042",
        "issue_date": "2026-11-13",
        "currency": "EUR",
        "seller": {"name": "Tailprint ApS"},
        "buyer": {"name": "Cohero Technologies"},
        "items": [{"description": "API Subscription", "quantity": 1, "unit_price": 49}],
        "tax_rate": 25,
    },
)

Invalid data raises ValidationError naming the offending fields (e.g. seller.name: Required).

⚡ Asynchronous Rendering & Webhooks

For heavy 100+ page reports or async pipelines:

# Submit rendering job in background
job = tp.render_pdf_async(
    html="<h1>Heavy 200-page Annual Financial Report</h1>",
    webhook_url="https://your-api.com/webhooks/pdf",
    webhook_headers={"X-Secret": "your_webhook_secret"},
)

print("Job queued:", job["job_id"])

# Optionally poll until finished:
completed_job = tp.wait_for_job(job["job_id"], poll_interval=1.0, timeout=60.0)
print("Download URL:", completed_job["results"][0]["download_url"])

📦 Concurrent Batch Rendering with Auto-Merge

Render up to 100 documents concurrently and optionally merge them into a single multi-page PDF:

batch = tp.render_batch(
    items=[
        {"html": "<h1>Invoice #101</h1>", "filename": "inv-101.pdf"},
        {"html": "<h1>Invoice #102</h1>", "filename": "inv-102.pdf"},
        {"html": "<h1>Invoice #103</h1>", "filename": "inv-103.pdf"},
    ],
    merge_output=True,
    merged_filename="all-invoices.pdf",
    webhook_url="https://your-api.com/webhooks/pdf",
)

completed = tp.wait_for_job(batch["job_id"])
print("Merged PDF link:", completed["merged_output"]["download_url"])

🇪🇺 European Factur-X / ZUGFeRD E-Invoicing

Generate Compliant Hybrid PDF/A-3

invoice_pdf = tp.generate_einvoice(
    invoice_number="INV-2026-0042",
    currency="EUR",
    seller={"name": "Acme Nordic ApS", "country": "DK", "vat_id": "DK12345678"},
    buyer={"name": "Global Logistics GmbH", "country": "DE", "vat_id": "DE987654321"},
    line_items=[
        {"name": "Consulting Services", "quantity": 10, "unit_price": 150.0, "vat_rate": 25.0}
    ],
    payment_iban="DK001234567890",
)

Validate E-Invoice Compliance (EN 16931)

report = tp.validate_einvoice(pdf=invoice_pdf)
print("Compliant:", report["is_valid"])
print("Profile:", report["profile"])
print("Totals:", report["invoice_details"]["totals"])

🛠 Complete PDF Operations

# 1. Merge multiple PDFs
merged_pdf = tp.merge_pdfs([doc1_bytes, doc2_bytes])

# 2. Extract pages (e.g. pages 1 to 3, and page 5)
split_pdf = tp.split_pdf(doc_bytes, pages="1-3, 5")

# 3. Fill interactive AcroForms
filled_pdf = tp.fill_pdf_form(doc_bytes, fields={"customer_name": "Alice", "opt_in": True})

# 4. Stamp watermark or compliance mark
stamped_pdf = tp.stamp_pdf(doc_bytes, watermark_text="CONFIDENTIAL", opacity=0.2)

# 5. Compress PDF file size
compressed_pdf = tp.compress_pdf(doc_bytes)

🔐 Webhook Signature Verification

Verify HMAC-SHA256 signatures in FastAPI, Flask, or Django:

from fastapi import FastAPI, Request, HTTPException

app = FastAPI()

@app.post("/webhooks/pdf")
async def handle_webhook(request: Request):
    payload = await request.body()
    sig_header = request.headers.get("x-tailprint-signature", "")
    
    if not tp.verify_webhook_signature(payload, sig_header):
        raise HTTPException(status_code=401, detail="Invalid signature")
        
    data = await request.json()
    print("PDF rendered:", data["data"]["download_url"])
    return {"status": "ok"}

📄 License

MIT © Tailprint

Metadata

Release files for tailprint 1.4.0

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

Source distribution (sdist)

Source distribution for tailprint 1.4.0
File Size Uploaded Provenance Actions
tailprint-1.4.0.tar.gz 12.8 kB Without provenance Details for tailprint-1.4.0.tar.gz

Built distribution (wheel)

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

Total release size: 22.6 kB

Release files / tailprint-1.4.0.tar.gz

Download URL tailprint-1.4.0.tar.gz
Size 12.8 kB
Tags Source
SHA-256 checksum
How to use checksums
3d91f01adb36d8ece5d68000932fa53023cc1449eb5dff9e8e08b0a4ae66c14e
BLAKE2b-256 checksum
How to use checksums
b4fe5ef3463e9262f8efe731c90921e3cdae29f26f6c16561118dac203748e54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Release files / tailprint-1.4.0-py3-none-any.whl

Download URL tailprint-1.4.0-py3-none-any.whl
Size 9.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8ddbb240a17bf33e1ff0bd7915d580711ef9d2fd43037eebc8e7f01d74c7a7aa
BLAKE2b-256 checksum
How to use checksums
a40625c36144c4173e83db2bb022aa4090cb1732c0f5188835b103e3284c8eb2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.15.2

Security for tailprint 1.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files No provenance

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