PDF Template API

PDF Template API: einmal gestalten, tausendfach erzeugen

Schreiben Sie eine Vorlage in HTML und CSS, speichern Sie sie einmal und senden Sie dann JSON. Jedes PDF erscheint im Markenlook, mit Schleifen, Bedingungen, Währungen und QR-Codes, die die Engine befüllt.

  • 50 kostenlose Renderings/Monat
  • Ohne Kreditkarte
  • Jinja-Syntax

Was ist eine PDF-Vorlagen-API?

Eine PDF-Vorlagen-API speichert ein Dokumentlayout mit Platzhaltern und befüllt es auf Anfrage mit Daten. Sie gestalten die Vorlage einmal und senden dann JSON — etwa einen Kundennamen, Rechnungsposten oder Daten —; die API setzt die Daten ins Layout ein, rendert es und liefert ein fertiges PDF zurück. Das Layout liegt an einem Ort statt in Ihrem Code.

PDF Template API: die wichtigsten Fakten
EndpunktPOST https://api.dynamicdocumentapi.com/v1/pdf/from-template
VorlagenspracheJinja-Syntax (MiniJinja-Engine): Variablen, Schleifen, Bedingungen, Makros, Includes, automatisches HTML-Escaping
VorlagentypenHTML/CSS-Code-Vorlagen und Markdown-Vorlagen
FormatierungWährungen, Zahlen, Prozente und Daten in jeder Sprache, auf Basis der Unicode-CLDR-Daten (ICU4X)
CodesQR-Codes und 16 Barcode-Typen, darunter Code 128, EAN-13, UPC-A, ITF-14 und GS1-128
VersionierungEntwurf, veröffentlichte Versionen, jede Version per Nummer rendern, Rückkehr mit einem Aufruf
AusgabePDF oder PNG/JPEG/WebP aus derselben Vorlage
PreisFree: 50 Renderings/Monat. Bezahlt ab 15 €/Monat (jährlich abgerechnet) für 3.000 Renderings, automatisches Nachladen ab 6 € je 1.000

Von der Vorlage zum PDF in drei Schritten

  1. Vorlage schreiben

    HTML und CSS mit Jinja-Platzhaltern. Beginnen Sie mit Ihrem vorhandenen Layout; Sie können Vorlagen in reinem HTML und CSS schreiben — mit denselben Druckfunktionen wie bei einem einzelnen Rendering.

  2. Version veröffentlichen

    Testen Sie den Entwurf mit Beispieldaten und einem Testschlüssel, dann veröffentlichen Sie. Die Vorlage bekommt eine feste ID und eine Versionsnummer.

  3. JSON senden, PDFs bekommen

    Jede Anfrage enthält die Vorlagen-ID und Ihre Daten. Die API liefert das PDF oder einen signierten Link darauf.

Ein PDF aus JSON erzeugen

Die Anfrage nennt die Vorlage und übergibt Ihre Daten. Das JSON darf jede Form haben: Verschachtelte Objekte und Arrays kommen in der Vorlage genau so an, wie Sie sie senden — Sie müssen Daten aus Ihrer Datenbank oder Ihrem Abrechnungssystem also selten umbauen.

curl https://api.dynamicdocumentapi.com/v1/pdf/from-template \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C",
    "version": "live",
    "data": {
      "number": "2026-0042",
      "customer": { "name": "Acme Co." },
      "items": [
        { "name": "API renders", "total": 1200.00 },
        { "name": "Support",     "total": 99.00 }
      ],
      "paid": false,
      "issued": "2026-09-22"
    },
    "filename": "invoice-{{ data.number }}.pdf"
  }'
// Node.js 18+ (built-in fetch)
const res = await fetch("https://api.dynamicdocumentapi.com/v1/pdf/from-template", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    template_id: "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C",
    data: {
      number: "2026-0042",
      customer: { name: "Acme Co." },
      items: [{ name: "API renders", total: 1200 }, { name: "Support", total: 99 }],
      paid: false,
      issued: "2026-09-22",
    },
  }),
});

const render = await res.json();
console.log(render.files[0].url);
import os
import requests

res = requests.post(
    "https://api.dynamicdocumentapi.com/v1/pdf/from-template",
    headers={"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}"},
    json={
        "template_id": "tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C",
        "data": {
            "number": "2026-0042",
            "customer": {"name": "Acme Co."},
            "items": [{"name": "API renders", "total": 1200},
                      {"name": "Support", "total": 99}],
            "paid": False,
            "issued": "2026-09-22",
        },
        "delivery": "binary",
    },
    timeout=60,
)
res.raise_for_status()
open("invoice.pdf", "wb").write(res.content)
<?php
$payload = [
    'template_id' => 'tpl_01J9ZK3M7Q8V5W2X4Y6Z8A0B1C',
    'data' => [
        'number'   => '2026-0042',
        'customer' => ['name' => 'Acme Co.'],
        'items'    => [
            ['name' => 'API renders', 'total' => 1200],
            ['name' => 'Support', 'total' => 99],
        ],
        'paid'   => false,
        'issued' => '2026-09-22',
    ],
];

$ch = curl_init('https://api.dynamicdocumentapi.com/v1/pdf/from-template');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . getenv('DYNAMIC_DOCUMENT_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode($payload),
]);
$render = json_decode(curl_exec($ch), true);
echo $render['files'][0]['url'];

version ist optional und steht standardmäßig auf "live", der neuesten veröffentlichten Version. Legen Sie eine Nummer wie 7 fest, wenn ein Dokument immer gleich aussehen muss, etwa bei einem Vertrag, der in diesem Layout unterschrieben wurde. Auch der filename ist eine Vorlage.

Vorlagensyntax

Vorlagen nutzen Jinja-Syntax. Wer schon eine Vorlage für Django, Flask, Jekyll oder Shopify Liquid geschrieben hat, kennt das meiste davon. Unten die Teile, die Dokumente am häufigsten brauchen — jeweils oben die Vorlage, darunter das, was das PDF zeigt.

Variablen

Jeder Wert aus Ihrem JSON, auch verschachtelte Felder. Text wird automatisch HTML-maskiert — ein Kunde namens <b>Acme</b> kann Ihr Layout also nicht verändern.

Hello {{ customer.name }},
→ Hello Acme Co.,

Schleifen für Rechnungsposten und Tabellen

for wiederholt einen Block für jeden Eintrag. loop.index, loop.first und loop.last helfen bei Nummerierung und Trennern, und sum_by summiert eine Spalte.

{% for item in items %}
<tr><td>{{ loop.index }}</td><td>{{ item.name }}</td></tr>
{% endfor %}
Total: {{ items | sum_by("total") }}

Bedingungen

Einen Block nur zeigen, wenn die Daten es sagen: einen Stempel „Bezahlt", eine Rabattzeile, eine Fußzeile in zweiter Sprache oder einen anderen Adressblock für Geschäftskunden.

{% if paid %}<p class="stamp">Paid</p>
{% elif due_days > 30 %}<p>Overdue</p>{% endif %}

Währungen, Zahlen und Daten in jeder Sprache

Die Formatierung nutzt Unicode-CLDR-Daten, dieselben Daten, auf denen Betriebssysteme und Browser beruhen. Symbole, Trennzeichen, Position des Symbols und Monatsnamen stimmen für jede Sprache, ohne Formatierungscode in Ihrer App.

{{ 1234.5 | format_currency("EUR", "de") }}  → 1.234,50 €
{{ 1234.5 | format_currency("USD", "en-US") }}  → $1,234.50
{{ issued | format_date("long", "en-US") }}  → September 22, 2026
{{ 0.256 | format_percent }}  → 26%

number_to_words schreibt Beträge auf Englisch, Deutsch, Französisch, Spanisch oder Niederländisch aus — für Schecks und Zahlscheine.

Bilder, QR-Codes und Barcodes

qrcode zeichnet einen scharfen Vektor-QR-Code mit der Fehlerkorrekturstufe Ihrer Wahl. barcode unterstützt 16 Typen, darunter Code 128, Code 39, EAN-13, EAN-8, UPC-A, ITF-14, ISBN und GS1-128, und berechnet Prüfziffern. Bilder laden von jeder öffentlichen URL.

{{ ticket.url | qrcode(size="30mm", ecc="Q") }}
{{ product.gtin | barcode(type="ean13") }}

Markdown in Vorlagen

Freitextfelder aus einem CMS oder einem Formular enthalten oft Markdown. Der Filter markdown macht daraus sauberes, bereinigtes HTML in Ihrem Layout: Überschriften, Listen, Tabellen, Links und Fußnoten.

<section class="notes">{{ notes | markdown }}</section>

Außerdem verfügbar: macro für wiederverwendbare Blöcke wie eine Adresse, include für gemeinsame Teile wie eine rechtliche Fußzeile, page_break() für eine neue Seite und table, um eine Liste von Objekten in einer Zeile in eine HTML-Tabelle zu verwandeln.

Vorlagenversionen und sichere Änderungen

Beim Ändern einer Live-Vorlage bricht die Dokumentenautomatisierung meistens: Jemand verschiebt ein Feld, und Rechnungen gehen halb leer hinaus. Vorlagen funktionieren hier wie Releases.

  • Entwurf und live. Änderungen landen in einem Entwurf. Der Produktivbetrieb rendert weiter die Live-Version, bis der Entwurf veröffentlicht ist.
  • Jede Version bleibt. Jedes Veröffentlichen erzeugt eine nummerierte Version mit optionaler Notiz. Jede davon rendern Sie mit "version": 7.
  • Rückkehr mit einem Aufruf. POST /v1/templates/{id}/rollback macht eine frühere Version wieder live.
  • Testen vor dem Ausliefern. Rendern Sie den Entwurf mit einem Testschlüssel: Test-Renderings kosten nichts, tragen das Wasserzeichen „TEST" und werden nach einem Tag gelöscht.
  • Fehlerhafte Daten früh erkennen. Jede Vorlage kann ein Datenschema festlegen. Mit strenger Prüfung scheitert eine Anfrage mit fehlenden oder falsch typisierten Feldern mit einer Liste der Fehler, statt ein kaputtes PDF zu erzeugen.

Dieselbe Vorlage kann mehr als eine Ausgabe bedienen: als PDF für den Druck und als PNG, JPEG oder WebP für E-Mails oder soziale Netzwerke. Vorlagen sind einer von vier Eingängen unserer PDF-Generierungs-API, neben rohem HTML, URLs und Markdown.

Tausende Dokumente aus einer Vorlage

Für Monatsrechnungen, einen Jahrgang Zertifikate oder einen Bericht pro Kunde senden Sie einen Stapel statt Tausender Einzelanfragen. POST /v1/batches nimmt eine Vorlagen-ID und eine Liste von Einträgen oder eine CSV-Datei mit Spaltenzuordnung. Jeder Eintrag wird ein PDF, und auf Wunsch fügen wir alle zu einem einzigen PDF zusammen.

Der Fortschritt kommt per Webhook (batch.progress, batch.completed), und retry-failed wiederholt nur die fehlgeschlagenen Einträge. Stapel gibt es in Bezahltarifen.

Wo Teams PDF-Vorlagen einsetzen

  • Rechnungen und Belege. Rechnungsposten, von Ihnen berechnete Steuern, Summen in der Währung der Kundschaft. So bauen Sie eine Rechnungsvorlage, die sauber über Seiten umbricht.
  • Berichte. Ein Layout, ein PDF pro Kunde, mit Diagrammen, die JavaScript vor der Erfassung zeichnet.
  • Zertifikate und Tickets. Namen, Daten und ein QR-Code zur Prüfung oder zum Einlass.
  • Verträge und Angebote. Klauseln, die sich über Bedingungen ein- und ausschalten, festgelegt auf die Version, die die Kundschaft unterschrieben hat.

Preise der PDF Template API

Free

€0

50 Renderings pro Monat, volle REST-API. Genug, um eine Vorlage zu bauen und zu testen.

Starter

€15 / Monat

3.000 Renderings pro Monat, jährlich abgerechnet (19 € bei monatlicher Abrechnung). Etwa 0,005 € pro Rendering.

Vorlagenlimits und Stapelgrößen wachsen mit jedem Tarif. Siehe Vorlagenlimits je Tarif.

FAQ

PDF Template API: häufige Fragen

Welche Vorlagensprache nutzt die API?

Jinja-Syntax, die Vorlagensprache von Pythons Jinja2 und vieler Static-Site-Generatoren. Sie bekommen Variablen, for-Schleifen, if-Bedingungen, Makros, Includes und Filter, dazu eingebaute Filter für Währung, Datum, QR-Codes und Barcodes. HTML-Ausgabe wird automatisch maskiert, damit Daten Ihrer Nutzer das Layout nicht zerstören können.

Kann ich meine vorhandenen HTML-Vorlagen übernehmen?

Ja. Eine Vorlage ist HTML und CSS, ein vorhandenes Rechnungs- oder Berichtslayout funktioniert also so, wie es ist. Ersetzen Sie die fest eingetragenen Werte Schritt für Schritt durch {{ variables }}; noch nicht umgestellte Teile rendern trotzdem.

Können Nicht-Entwickler eine Vorlage bearbeiten, ohne die API-Integration zu gefährden?

Änderungen passieren in einem Entwurf. Ihre Anwendung rendert weiter die Live-Version, bis jemand den Entwurf veröffentlicht, und jede veröffentlichte Version bleibt verfügbar — ein Fehler lässt sich mit einem Aufruf zurücknehmen. Mit strenger Datenprüfung scheitert ein Rendering, dessen JSON nicht zum Schema der Vorlage passt, mit einer klaren Fehlermeldung, statt ein falsches Dokument zu erzeugen.

Kann ich ein PDF direkt aus JSON erzeugen?

Ja. Senden Sie Ihre Daten als JSON in data zusammen mit einer template_id an POST /v1/pdf/from-template. Das JSON darf jede Form haben: Verschachtelte Objekte und Arrays stehen in der Vorlage genau so zur Verfügung, wie Sie sie senden.

Wie gehe ich mit Tabellen um, die über mehrere Seiten laufen?

Schreiben Sie die Tabelle in reinem HTML mit einem <thead>. Die Engine wiederholt die Kopfzeile auf jeder Seite, und tr { break-inside: avoid; } verhindert, dass Zeilen geteilt werden. Mit der Funktion page_break() erzwingen Sie eine neue Seite vor einem Abschnitt.

Kann dieselbe Vorlage ein Bild erzeugen?

Ja. POST /v1/images/from-template rendert dieselbe Vorlage als PNG, JPEG oder WebP — etwa ein Zertifikat als PDF zum Drucken und als PNG zum Teilen.

Bauen Sie Ihre erste Vorlage kostenlos

50 Renderings im Monat im Free-Tarif, ohne Kreditkarte, automatisches Nachladen in Bezahltarifen.

Kostenlos starten