Report Generation API

Report Generation API für automatisierte PDF-Berichte

Diagramme, lange Tabellen und Seitenzahlen, gerendert aus Ihren Daten — auf Abruf oder am Ende jedes Monats. Ein Aufruf liefert ein fertiges mehrseitiges PDF, das Ihre Kundschaft behalten kann.

  • 50 kostenlose Renderings/Monat
  • Ohne Kreditkarte
  • Diagramme, Lesezeichen, Seitenzahlen

Was ist eine API zur Berichtserstellung?

Eine API zur Berichtserstellung macht aus strukturierten Daten einen fertigen PDF-Bericht. Ihre Anwendung sendet Kennzahlen, Tabellenzeilen und Diagrammdaten als JSON; die API setzt sie in eine HTML-Vorlage ein, wartet, bis jedes Diagramm fertig gezeichnet ist, bricht das Ergebnis in Seiten um und liefert ein mehrseitiges PDF mit laufenden Kopfzeilen, Lesezeichen und Seitenzahlen.

Report Generation API: die wichtigsten Fakten
EndpunktPOST https://api.dynamicdocumentapi.com/v1/pdf/from-template oder /v1/pdf/from-html und /v1/pdf/from-url für eine Seite, die Sie bereits rendern
EingabeIhre Berichtsdaten als JSON plus eine HTML/CSS-Vorlage mit Jinja-Syntax
DiagrammeJede JavaScript-Diagrammbibliothek — Chart.js, ECharts, D3, Highcharts —, gezeichnet in Chromium 153 vor der Erfassung
Wartenload, networkidle, ein CSS-selector, ein ready_flag oder eine feste delay; Timeout 100 ms bis 300 s
SeitenumbruchWiederholte Tabellenköpfe, gesteuerte Seitenumbrüche, laufende Kopf- und Fußzeile, „Seite 3 von 12"
NavigationPDF-Lesezeichen mit outline, getaggtes PDF mit tagged, einzelne Abschnitte mit page_ranges
MassenverarbeitungStapel aus einer JSON-Liste oder einem CSV-Export, ein PDF pro Kunde oder zusammengeführt in eine Datei (Bezahltarife)
RenderzeitMedian 216 ms, p95 516 ms1, plus die Zeit, die Ihre Diagramme zum Zeichnen brauchen
PreisFree: 50 Renderings/Monat. Bezahlt ab 15 €/Monat (jährlich abgerechnet) für 3.000 Renderings, automatisches Nachladen ab 6 € je 1.000

Ein Hinweis zum Namen. Wer nach „Reporting API" sucht, findet auch die gleichnamige Browserfunktion, die CSP-Verstöße und Hinweise auf veraltete Funktionen an einen Sammel-Endpunkt schickt. Das ist etwas anderes. Diese Seite behandelt die andere Bedeutung — auch gesucht als PDF-Report-API —, bei der Ihre Daten hineingehen und ein fertiger, paginierter Bericht zurückkommt.

1. Gemessen über 1.664 erfolgreiche Renderings auf Engine 2026.4. total_ms = Wartezeit in der Warteschlange plus Verarbeitung im Worker, ohne API-Overhead und Netzwerkübertragung. Ein Bericht mit aufwendigen clientseitigen Diagrammen dauert länger, weil die Engine auf die von Ihnen gesetzte Bedingung wartet, bevor sie die Seite erfasst.

Von Daten zum fertigen PDF-Bericht

Speichern Sie das Berichtslayout einmal als Vorlage — Deckblatt, Diagrammteil, Tabellenteil — und senden Sie dann einen Aufruf pro Bericht. Das Beispiel fordert Lesezeichen, eine laufende Fußzeile mit Seitenzahlen und ein getaggtes PDF an und wartet vor der Erfassung, bis die Diagramme fertig sind. Wenn die Berichtsseite in Ihrer App schon existiert, können Sie stattdessen HTML-Berichte als PDF rendern.

curl https://api.dynamicdocumentapi.com/v1/pdf/from-template \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Idempotency-Key: acme-2026-Q3" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_quarterly_report",
    "data": {
      "client": "Acme Co.",
      "period": "Q3 2026",
      "locale": "en-US",
      "currency": "USD",
      "kpis": { "revenue": 482150.00, "orders": 1284, "growth": 0.18 },
      "series": [82000, 97400, 113200, 140550],
      "rows": [ { "channel": "Search", "sessions": 48120, "revenue": 190400 } ]
    },
    "pdf": {
      "paper": { "format": "A4" },
      "margin": { "top": "22mm", "bottom": "18mm" },
      "outline": true,
      "tagged": true,
      "footer": { "enabled": true,
                  "left": "Acme Co. · Q3 2026",
                  "right": "Page {{page}} of {{pages}}" },
      "wait": { "until": "selector", "selector": "#charts[data-ready]",
                "timeout_ms": 20000, "strict": false }
    },
    "filename": "acme-q3-2026.pdf"
  }'
// Node.js 18+: render one client report and return the signed link
export async function renderReport(client, period, data) {
  const res = await fetch("https://api.dynamicdocumentapi.com/v1/pdf/from-template", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
      "Idempotency-Key": `${client}-${period}`, // one report per period
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      template_id: "tpl_quarterly_report",
      data,
      pdf: {
        outline: true,
        tagged: true,
        footer: { enabled: true, right: "Page {{page}} of {{pages}}" },
        wait: { until: "selector", selector: "#charts[data-ready]" },
      },
      filename: `${client}-${period}.pdf`,
    }),
  });
  if (!res.ok) throw new Error(await res.text());
  const render = await res.json();
  return render.files[0].url; // signed link, 1 hour by default
}
import os
import requests

def render_report(client: str, period: str, data: dict) -> bytes:
    res = requests.post(
        "https://api.dynamicdocumentapi.com/v1/pdf/from-template",
        headers={
            "Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}",
            "Idempotency-Key": f"{client}-{period}",
        },
        json={
            "template_id": "tpl_quarterly_report",
            "data": data,
            "pdf": {
                "outline": True,          # PDF bookmarks per section
                "tagged": True,           # structure for screen readers
                "footer": {"enabled": True, "right": "Page {{page}} of {{pages}}"},
                "wait": {"until": "selector", "selector": "#charts[data-ready]"},
            },
            "delivery": "binary",   # PDF bytes, ready to attach
        },
        timeout=120,
    )
    res.raise_for_status()
    return res.content
<?php
function renderReport(string $client, string $period, array $data): string
{
    $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'),
            'Idempotency-Key: ' . $client . '-' . $period,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS     => json_encode([
            'template_id' => 'tpl_quarterly_report',
            'data'        => $data,
            'pdf'         => [
                'outline' => true,
                'footer'  => ['enabled' => true, 'right' => 'Page {{page}} of {{pages}}'],
                'wait'    => ['until' => 'selector', 'selector' => '#charts[data-ready]'],
            ],
            'delivery'    => 'binary',
        ]),
    ]);
    return curl_exec($ch); // PDF bytes
}

Die Antwort ist ein Render-Objekt mit einem signierten Link in files[0].url, standardmäßig eine Stunde gültig und mit expires_in bis zu sieben Tage. Fordern Sie stattdessen "delivery": "binary" an, bekommen Sie die PDF-Bytes direkt zurück, bereit als E-Mail-Anhang. Der Idempotency-Key macht eine Wiederholung harmlos: Derselbe Schlüssel liefert 24 Stunden lang den bereits gerenderten Bericht.

Diagramme, die fertig sind, bevor die Seite erfasst wird

Die meisten kaputten PDF-Berichte haben dieselbe Ursache: Die Seite wurde erfasst, während die Diagramme noch animierten. JavaScript läuft standardmäßig, und die Engine wartet immer auf das Ereignis load, Webfonts, die Dekodierung der Bilder und zwei gerenderte Frames. Für Diagramme reicht das meist nicht — also legen Sie fest, was „fertig" bedeutet.

Das Diagramm meldet sich selbst

Das zuverlässigste Signal kommt von der Diagrammbibliothek selbst. Schalten Sie die Animation ab und setzen Sie im Abschluss-Callback der Bibliothek eine Markierung, auf die die API warten kann.

// Chart.js: no animation, flag when drawn
new Chart(ctx, { options: { animation: {
  onComplete: () => charts.dataset.ready = "1"
} } });
"wait": { "until": "selector",
  "selector": "#charts[data-ready]",
  "timeout_ms": 20000, "strict": false }

Vier weitere Arten zu warten

networkidle wartet auf ein ruhiges Netzwerk (ein Fenster von 500 ms ohne Anfragen) und passt zu Dashboards, die ihre Daten selbst laden. ready_flag lässt Ihr Skript den Abschluss melden, delay fügt eine feste Pause ein, und load ist der Standard. timeout_ms reicht von 100 ms bis 300 Sekunden.

Festlegen, was ein Timeout bedeutet

Mit strict: false liefert ein Timeout den Bericht trotzdem, plus eine Warnung wait_timeout, die Sie protokollieren können — ein Monatsauszug muss meist raus, auch wenn ein Widget fehlt. Mit strict: true schlägt das Rendering stattdessen fehl; das wollen Sie bei einem Bericht, der vollständig sein muss.

Scharfe Diagramme statt Screenshots

SVG-Diagramme bleiben im PDF Vektorgrafik und drucken in jeder Größe sauber. Canvas-Diagramme sind Rastergrafik: Geben Sie dem Canvas vor dem Zeichnen ein höheres Device-Pixel-Ratio oder rendern Sie dieselben Daten für den Druck als SVG. So oder so folgen die Farben print_background, das standardmäßig an ist.

Der Bericht existiert schon als Seite in Ihrem Produkt? Richten Sie den URL-Endpunkt darauf und exportieren Sie eine Dashboard-URL mit einem Session-Cookie oder einem Authorization-Header, statt das Layout als Vorlage nachzubauen.

Lange Tabellen, Seitenumbrüche und Navigation

Ein Bericht ist selten nur eine Seite lang. Diese CSS-Regeln und PDF-Optionen entscheiden, ob ein 40-seitiger Export fertig oder improvisiert aussieht.

Tabellen, die einen Seitenumbruch überstehen

Posten sind eine normale HTML-Tabelle, es gelten also die Druckregeln des Browsers. Die Kopfzeile wiederholt sich auf jeder Seite, Zeilen werden nie in der Mitte geteilt, und ein Abschnitt hält mindestens zwei Zeilen zusammen.

thead            { display: table-header-group; }
tr, .totals      { break-inside: avoid; }
h2               { break-after: avoid; }
p                { orphans: 2; widows: 2; }
.section + .section { break-before: page; }

Lesezeichen und Struktur

"outline": true baut den Lesezeichenbaum des PDFs aus Ihren Überschriften, sodass Lesende in der Seitenleiste jedes PDF-Viewers zu „Kanäle" oder „Anhang" springen können. "tagged": true ergänzt die Struktur, auf die Screenreader und Barrierefreiheitsprüfungen angewiesen sind. page_ranges liefert nur einen Abschnitt — praktisch, wenn Kunden „nur die Zusammenfassung" möchten.

Deckblatt, laufende Kopfzeile und Seitenzahlen

Laufende Kopf- und Fußzeile sind vom Dokumentkörper getrennt. Nutzen Sie die einfache Form mit left, center und right oder übergeben Sie eigenes HTML für ein Logo und einen Vertraulichkeitshinweis. {{page}} und {{pages}} werden je Seite befüllt, und der obere Rand muss Platz für die Kopfzeile lassen.

"header": { "enabled": true, "height": "16mm",
  "html": "<div class='hdr'><img src='logo.svg'>Confidential</div>" },
"footer": { "enabled": true,
  "left": "Acme Co. · Q3 2026",
  "right": "Page {{page}} of {{pages}}" },
"margin": { "top": "22mm", "bottom": "18mm" }

Ein Deckblatt ist einfach der erste Abschnitt der Vorlage mit break-after: page. Damit die Kopfzeile dort nicht erscheint, blenden Sie sie in Ihrem Kopfzeilen-HTML mit einer {{page}}-Bedingung für die erste Seite aus, oder rendern Sie das Deckblatt separat und führen die Dateien zusammen.

Monatsläufe: ein Bericht pro Kunde

Berichtsarbeit kommt in Wellen. Am ersten Arbeitstag des Monats braucht eine Agentur 200 Kundenberichte, an allen anderen Tagen fast keine. Genau dafür gibt es drei Teile der API.

  1. Ihr Zeitplan, unser Rendering

    Die API rendert, wenn Sie sie aufrufen; der Kalender bleibt in Ihrem System — ein Cronjob, ein Queue-Worker oder eine geplante Aufgabe, die am Ersten des Monats um 6:00 Uhr läuft.

  2. Ein Stapel, viele Berichte

    Senden Sie den ganzen Lauf als Stapel aus einer JSON-Liste oder einem CSV-Export: eine Zeile pro Kunde, ein PDF pro Zeile — oder alle Berichte in einer einzigen Datei.

  3. Webhook, wenn es fertig ist

    Lange Läufe laufen asynchron. Ein signierter Webhook meldet Ihrem System, wann jeder Bericht — oder der ganze Stapel — fertig ist, damit nichts an einer offenen Verbindung hängt.

Webhooks werden nach der Standard-Webhooks-Spezifikation mit HMAC-SHA256 signiert, und eine Zustellung, die Ihr Server nicht annimmt, wird bis zu achtmal über etwa 28 Stunden wiederholt. Stapel gibt es in Bezahltarifen. Dateien bleiben so lange, wie Sie es mit retention_days festlegen, bis zum Maximum Ihres Tarifs, und Sie können sie jederzeit löschen — oder Sie nehmen die Bytes direkt entgegen und speichern nichts bei uns.

Berichtsarten, die Teams automatisieren

Kundenberichte von Agenturen

Monatliche Performance-Berichte mit dem Kundenlogo auf dem Deckblatt, Kanaltabellen und einem Kommentarteil. Eine Vorlage, ein Stapel, 200 PDFs im Markenlook — statt 200 Exporten, die in Folien kopiert werden.

Analyse- und Nutzungsexporte

Der Button „Als PDF exportieren" in Ihrem eigenen Produkt. Der Nutzer wählt einen Zeitraum, Ihr Backend rendert dieselbe Ansicht als paginiertes Dokument, und der Download erscheint Sekunden später.

Auszüge und Finanzübersichten

Kontoauszüge, Portfolioübersichten und Auszahlungsberichte, mit Beträgen und Daten je Sprache formatiert aus Unicode-CLDR-Daten und Summen, die Ihr System berechnet hat.

Prüf- und Compliance-Berichte

Lange, strukturierte Dokumente mit Lesezeichen, getaggter Struktur und festen Metadaten. Ergänzen Sie mit protect ein Passwort und Berechtigungen, wenn ein Bericht das Haus verlässt.

Report-API, BI-Export oder eigenes Headless Chrome?

Eine PDF-Report-API ist nicht immer das richtige Werkzeug. Hier sehen Sie, wo welche Option wirklich besser ist.

Report Generation API im Vergleich mit BI-Exporten und selbst betriebenem Headless Chrome
Frage Export aus dem BI-Tool Selbst betriebenes Headless Chrome Dynamic Document API
Wer gestaltet das LayoutDas Tool, im Rahmen seines Export-ThemesSie, in HTML und CSSSie, in HTML und CSS
Ihr Branding auf jeder SeiteAuf das Theme beschränktVolle KontrolleVolle Kontrolle, dazu versionierte Vorlagen
Aus Ihrer App ausgelöstSelten, oft ein manueller ExportJaJa, ein HTTP-Aufruf
DiagrammeEingebautIhre DiagrammbibliothekIhre Diagrammbibliothek, mit Wartebedingungen
BetriebNichts über das Tool hinausQueue, Worker, Browser-Updates, SpeicherKeiner — wir betreiben die Engine
Daten verlassen Ihr NetzwerkHängt vom Tool abNeinJa: Die Nutzdaten gehen an die API
Am besten, wennMenschen Daten interaktiv erkundenDaten Ihr Netzwerk nie verlassen dürfen oder das Volumen sehr hoch und gleichmäßig istIhr Produkt fertige Dokumente im Markenlook ausgeben muss

Zwei ehrliche Grenzen. Wir liefern PDFs und Bilder, keine bearbeitbaren XLSX- oder DOCX-Dateien — wenn Ihre Leser mit den Zahlen weiterarbeiten müssen, liefern Sie eine Tabelle neben dem PDF mit. Und ein Bericht, der Ihre Infrastruktur nie verlassen darf, gehört auf Ihre eigene Hardware, nicht auf irgendeine API, unsere eingeschlossen.

Was das Erzeugen eines Berichts kostet

Free

€0

50 Berichte pro Monat. Genug, um die Vorlage zu bauen und einen ganzen Monat lang zu testen.

Starter

€15 / Monat

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

Ein Rendering ist eine zurückgegebene Datei mit bis zu 50 Seiten, ein 40-seitiger Bericht kostet also so viel wie ein einseitiger. Bei 15.000 Berichten im Monat kostet der Growth-Tarif 47 € bei jährlicher Abrechnung, etwa 0,0031 € pro Stück. Siehe die Kosten pro Bericht in jedem Tarif.

FAQ

Report Generation API: häufige Fragen

Kann ich Diagramme in PDF-Berichte einbauen?

Ja. Berichte werden in Chromium mit aktiviertem JavaScript gerendert, Chart.js, ECharts, D3, Highcharts oder ein einfaches Canvas funktionieren also. Diagramme erscheinen als scharfe Vektor- oder hochaufgelöste Rastergrafik, genau so, wie die Bibliothek sie im Browser zeichnet. Es gibt keine eigene Diagrammsyntax zu lernen.

Wie bleiben Tabellenköpfe auf jeder Seite?

Nutzen Sie eine normale HTML-Tabelle und lassen Sie CSS die Arbeit machen: thead { display: table-header-group } wiederholt die Kopfzeile auf jeder Seite, und tr { break-inside: avoid } verhindert, dass eine Zeile geteilt wird. Dieselben Regeln halten einen Summenblock bei den Zeilen darüber.

Lassen sich Berichte nach Zeitplan erzeugen?

Die API rendert einen Bericht, sobald Sie sie aufrufen. Der Zeitplan bleibt in Ihrem System: Ein Cronjob, ein Queue-Worker oder eine geplante Aufgabe in Ihrem Automatisierungstool ruft den Endpunkt am Ende jedes Monats oder jeder Woche auf. Für lange Aufträge nutzen Sie den asynchronen Modus und einen Webhook, damit nichts blockiert.

Kann ich eine Dashboard-URL als PDF-Bericht exportieren?

Ja. Richten Sie den URL-Endpunkt auf das Dashboard und übergeben Sie ein Session-Cookie oder einen Authorization-Header, damit die Seite angemeldet lädt. Zugangsdaten gehen nur an dieselbe registrierbare Domain. Warten Sie dann auf einen CSS-Selektor oder ein Ready-Flag, damit jedes Widget vor der Erfassung gezeichnet ist.

Was, wenn ein Diagramm lange zum Laden braucht?

Setzen Sie pdf.wait auf die Bedingung, die „fertig" beschreibt: einen CSS-Selektor, den Ihr Diagramm ergänzt, ein Ready-Flag, das Ihr Skript setzt, oder networkidle. timeout_ms reicht bis 300 Sekunden. Mit strict: false liefert ein Timeout trotzdem das PDF plus eine Warnung wait_timeout; mit strict: true schlägt das Rendering stattdessen fehl.

Kann ich einen Bericht pro Kunde im Stapel erzeugen?

Ja. Senden Sie in Bezahltarifen einen Stapel aus einer JSON-Liste oder einem CSV-Export: eine Zeile pro Kunde, ein PDF pro Zeile oder zusammengeführt in eine Datei. Ein signierter Webhook meldet Ihrem System, wann der Stapel fertig ist, und jedes Rendering kann einen eigenen Dateinamen und eigene Metadaten tragen.

Bauen Sie Ihren ersten Bericht kostenlos

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

Kostenlos starten