Batch-Dateikonvertierungs-API#

Die EnConvert Batch-API konvertiert mehrere URLs in einer einzigen Anfrage: Übergib ein Array von URLs an /v1/convert/url-to-pdf oder /v1/convert/url-to-screenshot und erhalte eine HTTP-202-Antwort mit einer batch_id. Jede URL wird asynchron im Hintergrund konvertiert, und die Ergebnisse werden als vorsignierte Download-URLs geliefert, entweder eine pro Datei oder gebündelt in einem einzigen ZIP-Archiv. Verfolge den Fortschritt durch Polling von GET /v1/convert/batch/{batch_id}, oder lass dich per Webhook-Callback oder E-Mail benachrichtigen, sobald der Vorgang abgeschlossen ist.

Nur private Keys: Batch-Verarbeitung ist nur verfügbar, wenn du dich mit einem privaten API-Key authentifizierst (X-API-Key: sk_...). Öffentliche Keys sind auf synchrone Anfragen mit einer einzelnen URL beschränkt.

Funktionsweise#

  1. Sende eine Anfrage mit einem Array von URLs im Parameter url an entweder /v1/convert/url-to-pdf oder /v1/convert/url-to-screenshot.
  2. Die API validiert den Batch gegen die Limits deines Plans und gibt HTTP 202 mit einer batch_id zurück.
  3. Jede URL wird im Hintergrund konvertiert und berechnet eine Op. Die gesamte Batch-Anzahl wird vorab gegen dein verbleibendes monatliches Ops-Kontingent geprüft, bevor die Verarbeitung beginnt.
  4. Verfolge den Fortschritt über GET /v1/convert/batch/{batch_id} oder erhalte bei Abschluss einen Webhook-Callback oder eine E-Mail-Benachrichtigung.
  5. Lade die Ergebnisse über vorsignierte URLs in der Batch-Statusantwort herunter.

Ausgabemodi#

Einzelmodus (Standard)#

Jede URL erzeugt eine separate Datei. Jede Datei erhält ihre eigene vorsignierte Download-URL in der Batch-Statusantwort.

Anfrage:

curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": [
      "https://example.com/page-1",
      "https://example.com/page-2",
      "https://example.com/page-3"
    ]
  }'

Antwort (HTTP 202 Accepted):

{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 3,
    "output_format": "individual"
}
Hinweis: Beim Übergeben mehrerer URLs wird async_mode automatisch auf true gesetzt, unabhängig davon, ob du es explizit in der Anfrage angibst.

ZIP-Bundle-Modus#

Setze output_format auf true, um alle konvertierten Dateien gebündelt in einem einzigen ZIP-Archiv zu erhalten. Erfordert einen Plan mit Zugriff auf ZIP-Ausgabe.

Anfrage:

curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": [
      "https://example.com/page-1",
      "https://example.com/page-2",
      "https://example.com/page-3"
    ],
    "output_format": true,
    "output_filename": "monthly-reports"
  }'

Antwort (HTTP 202 Accepted):

{
    "status": "processing",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "url_count": 3,
    "output_format": "zip"
}

Im ZIP-Modus werden alle URLs sequenziell verarbeitet, und die erfolgreichen Ergebnisse werden in einem einzigen ZIP-Archiv mit dem Namen {output_filename}_{timestamp}.zip gebündelt (oder batch_{timestamp}.zip, falls kein benutzerdefinierter Name angegeben wird).


Batch-Parameter#

Parameter Type Default Beschreibung Plan-Freischaltung
url string[] (erforderlich) Array der zu konvertierenden URLs. --
output_format boolean false Auf true setzen, um alle Ergebnisse in einem ZIP-Archiv zu bündeln. Erfordert mehrere URLs. Erfordert Zugriff auf ZIP-Ausgabe
output_filename string Automatisch generiert Benutzerdefinierter Dateiname für die Ausgabe. Im ZIP-Modus wird damit das ZIP-Archiv benannt. --
async_mode boolean true (implizit) Für Batch immer true. Wird automatisch aktiviert, wenn mehrere URLs angegeben werden. Erfordert Async-Zugriff
notification_email string E-Mail des Projektinhabers E-Mail-Adresse, die bei Abschluss benachrichtigt wird. Falls weggelassen, wird standardmäßig die E-Mail des Projektinhabers verwendet. --
callback_url string null Webhook-URL, die bei Abschluss ein POST erhält. Erfordert Webhook-Zugriff
direct_download -- -- Nicht unterstützt für Batch. Gibt einen 400-Fehler zurück, wenn bei mehreren URLs gesetzt. --

Browser- & Rendering-Parameter#

Diese Einstellungen gelten für jede URL im Batch:

Parameter Type Default Beschreibung
viewport_width integer 1920 Breite des Browser-Viewports in Pixeln.
viewport_height integer 1080 Höhe des Browser-Viewports in Pixeln.
single_page boolean true Als einzelne durchgehende Seite rendern (nur url-to-pdf).
load_media boolean true Warten, bis Bilder und Medien geladen sind.
enable_scroll boolean true Seiten scrollen, um Lazy-Loaded-Inhalte auszulösen.
handle_sticky_header boolean true Sticky/fixierte Header erkennen und behandeln.
handle_cookies boolean true Cookie-Consent-Banner automatisch schließen.
wait_for_images boolean true Warten, bis alle Bilder vollständig geladen sind.

Authentifizierung & benutzerdefinierte Anfragen#

Diese gelten für jede URL im Batch. Erfordern einen Plan mit Basic-Auth-Zugriff.

Parameter Type Default Beschreibung
auth object null HTTP-Basic-Auth-Zugangsdaten: {"username": "...", "password": "..."}.
cookies array null Array von Cookie-Objekten, die vor jedem Seitenaufruf injiziert werden. Max. 50.
headers object null Benutzerdefinierte HTTP-Header, die mit jeder Anfrage gesendet werden. Max. 20.

PDF-Optionen (nur url-to-pdf)#

Übergib ein pdf_options-Objekt, um die PDF-Ausgabeformatierung für jede Seite im Batch zu steuern:

Parameter Type Default Beschreibung
page_size string "A4" Benannte Seitengröße.
orientation string "portrait" "portrait" oder "landscape".
margins object {"top": 10, "bottom": 10, "left": 10, "right": 10} Ränder in mm.
grayscale boolean false Graustufenausgabe via Ghostscript.

Batch-Status-Polling#

Verwende den Batch-Status-Endpoint, um den Fortschritt zu prüfen und Download-URLs abzurufen.

GET /v1/convert/batch/{batch_id}
X-API-Key: sk_your_private_key

Ersetze {batch_id} durch die batch_id, die von der ursprünglichen Anfrage zurückgegeben wurde.

Verarbeitungsstatus#

Während Konvertierungen noch laufen:

{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "processing",
    "total": 3,
    "completed": 1,
    "failed": 0,
    "in_progress": 2,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "In Progress",
            "download_url": null,
            "output_file_size": null,
            "duration": null
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "In Progress",
            "download_url": null,
            "output_file_size": null,
            "duration": null
        }
    ]
}

Abgeschlossener Status#

Wenn alle URLs erfolgreich konvertiert wurden:

{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "total": 3,
    "completed": 3,
    "failed": 0,
    "in_progress": 0,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 97280,
            "duration": "2.87"
        }
    ]
}

Teilweiser Status#

Wenn alle URLs abgeschlossen sind, aber einige fehlgeschlagen sind:

{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "partial",
    "total": 3,
    "completed": 2,
    "failed": 1,
    "in_progress": 0,
    "output_mode": "individual",
    "zip_download_url": null,
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://invalid-url.example",
            "status": "Failed",
            "download_url": null,
            "output_file_size": null,
            "duration": "0.87"
        }
    ]
}

Abgeschlossen im ZIP-Modus#

Im ZIP-Modus wird eine einzelne zip_download_url für das gesamte Archiv bereitgestellt:

{
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "completed",
    "total": 3,
    "completed": 3,
    "failed": 0,
    "in_progress": 0,
    "output_mode": "zip",
    "zip_download_url": "https://spaces.example.com/...",
    "items": [
        {
            "source_url": "https://example.com/page-1",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 184320,
            "duration": "3.12"
        },
        {
            "source_url": "https://example.com/page-2",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 210944,
            "duration": "4.55"
        },
        {
            "source_url": "https://example.com/page-3",
            "status": "Success",
            "download_url": "https://spaces.example.com/...",
            "output_file_size": 97280,
            "duration": "2.87"
        }
    ]
}

Batch-Statuswerte#

Status Bedeutung
processing Mindestens eine URL wird noch konvertiert.
completed Alle URLs wurden erfolgreich konvertiert.
partial Alle URLs sind abgeschlossen, aber einige sind fehlgeschlagen.
failed Alle URLs sind fehlgeschlagen.

Webhook-Callbacks#

Gib in der Anfrage eine callback_url an, um bei Abschluss automatisch eine POST-Benachrichtigung zu erhalten. Der Webhook wird mit Content-Type: application/json und einem 30-Sekunden-Timeout gesendet. Bei Zustellungsfehlern werden keine Wiederholungsversuche unternommen.

Callback im Einzelmodus#

Im Einzelmodus wird für jede URL bei Abschluss ein separater Webhook-POST gesendet:

{
    "job_id": "12345",
    "status": "success",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "gcs_uri": "env/files/{project_id}/url-to-pdf/page1_20260405_123456789.pdf",
    "filename": "page1_20260405_123456789.pdf",
    "file_size": 184320
}

Callback im ZIP-Modus#

Im ZIP-Modus wird ein einziger Webhook-POST gesendet, wenn der gesamte Batch abgeschlossen ist:

{
    "job_id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "success",
    "batch_id": "550e8400-e29b-41d4-a716-446655440000",
    "gcs_uri": "env/files/{project_id}/url-to-pdf/batch_20260405_123456789.zip",
    "filename": "batch_20260405_123456789.zip",
    "file_size": 456789,
    "total_tasks": 3,
    "successful_tasks": 2,
    "failed_tasks": 1,
    "tasks": [
        {"url": "https://example.com/page-1", "status": "success", "filename": "page1.pdf"},
        {"url": "https://example.com/page-2", "status": "success", "filename": "page2.pdf"},
        {"url": "https://invalid.example", "status": "failed", "error": "Page load timeout"}
    ]
}
Unterschied im Benachrichtigungsverhalten: Im Einzelmodus erhältst du N separate Webhook-POSTs (einen pro URL) und N separate E-Mails. Im ZIP-Modus erhältst du einen Webhook-POST und eine E-Mail für den gesamten Batch. Berücksichtige dies beim Entwurf deines Webhook-Handlers.

E-Mail-Benachrichtigungen#

Bei Abschluss des Batches wird eine E-Mail an notification_email gesendet. Wird keine notification_email angegeben, wird die E-Mail standardmäßig an die E-Mail-Adresse des Projektinhabers gesendet.

Die E-Mail enthält:

  • Job-Status (success/failed) mit farbigem Banner
  • Batch-ID
  • Bei Batch-Jobs: eine Tabelle mit jeder URL, ihrem Status und dem Ausgabedateinamen
  • Ein Link zum Herunterladen der Ergebnisse über das Dashboard

Freischaltung nach Abo-Plan#

Feature Founding Indie Studio Enterprise
Batch-Verarbeitung Nein Ja Ja Ja
Async-Modus Nein Ja Ja Ja
ZIP-Ausgabebündelung Nein Nein Ja Ja
Webhook-Callbacks Nein Nein Ja Ja
HTTP Basic Auth / Cookies / Headers Nein Ja Ja Ja
Batch-Größenlimit 0 Planabhängig Planabhängig Unbegrenzt
Monatliche Konvertierungen 100 Planabhängig Planabhängig Unbegrenzt

Codebeispiele#

Python – Einzelmodus mit Polling#

import requests
import time

# Submit batch
response = requests.post(
    "https://api.enconvert.com/v1/convert/url-to-pdf",
    headers={"X-API-Key": "sk_your_private_key"},
    json={
        "url": [
            "https://example.com/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ]
    }
)

data = response.json()
batch_id = data["batch_id"]
print(f"Batch started: {batch_id} ({data['url_count']} URLs)")

# Poll for completion
while True:
    status = requests.get(
        f"https://api.enconvert.com/v1/convert/batch/{batch_id}",
        headers={"X-API-Key": "sk_your_private_key"}
    ).json()

    print(f"Status: {status['status']} ({status['completed']}/{status['total']})")

    if status["status"] in ("completed", "partial", "failed"):
        for item in status["items"]:
            if item["download_url"]:
                print(f"  {item['source_url']} -> {item['download_url']}")
        break

    time.sleep(5)

Python – ZIP-Modus mit Webhook#

import requests

response = requests.post(
    "https://api.enconvert.com/v1/convert/url-to-pdf",
    headers={"X-API-Key": "sk_your_private_key"},
    json={
        "url": [
            "https://example.com/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ],
        "output_format": True,
        "output_filename": "monthly-reports",
        "callback_url": "https://your-server.com/webhook/enconvert",
        "pdf_options": {
            "page_size": "A4",
            "orientation": "portrait"
        }
    }
)

data = response.json()
print(f"Batch started: {data['batch_id']}")
print(f"URLs: {data['url_count']}, Format: {data['output_format']}")
# Results will be delivered to your webhook URL

Node.js – Batch-Screenshots#

const response = await fetch("https://api.enconvert.com/v1/convert/url-to-screenshot", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "X-API-Key": "sk_your_private_key"
    },
    body: JSON.stringify({
        url: [
            "https://example.com/page-1",
            "https://example.com/page-2",
            "https://example.com/page-3"
        ],
        output_format: true,
        output_filename: "screenshots-bundle"
    })
});

const data = await response.json();
console.log(`Batch ${data.batch_id}: ${data.url_count} screenshots queued`);

Fehlerantworten#

Status Bedingung
400 Bad Request url ist leer oder fehlt
400 Bad Request output_format=true bei einer einzelnen URL (erfordert mehrere URLs)
400 Bad Request direct_download=true bei mehreren URLs (nicht unterstützt)
400 Bad Request direct_download=true mit async_mode=true
400 Bad Request Öffentlicher Key versucht mehrere URLs
402 Payment Required Batch würde das verbleibende monatliche Ops-Kontingent überschreiten
402 Payment Required Speicherlimit erreicht
403 Forbidden Async-Verarbeitung im aktuellen Plan nicht verfügbar
403 Forbidden Batch-Verarbeitung nicht verfügbar (Batch-Limit ist 0)
403 Forbidden Batch-Größe überschreitet das Batch-Limit des Plans
403 Forbidden ZIP-Ausgabe im aktuellen Plan nicht verfügbar
403 Forbidden Webhook-Callbacks im aktuellen Plan nicht verfügbar
404 Not Found Batch nicht gefunden (falsche batch_id oder falsches Projekt)

Limits#

Limit Wert
Batch-Größe Planabhängig (Founding: deaktiviert)
Monatliche Konvertierungen Planabhängig (gesamter Batch wird vorab geprüft)
Webhook-Zustellungs-Timeout 30 Sekunden (keine Wiederholungsversuche)
Maximale Cookies pro Anfrage 50
Maximale benutzerdefinierte Header pro Anfrage 20
Aufbewahrungsdauer der Dateien Planabhängig

Häufig gestellte Fragen#

Wie konvertiere ich mehrere URLs mit einer einzigen API-Anfrage in PDF?#

Sende ein POST an /v1/convert/url-to-pdf mit einem Array von URLs im Parameter url, authentifiziert mit einem privaten API-Key (sk_...). Die API antwortet mit HTTP 202 und einer batch_id, und jede URL wird im Hintergrund konvertiert.

Kann ich alle Batch-Konvertierungsergebnisse in einer einzigen ZIP-Datei erhalten?#

Ja. Setze output_format auf true, um alle erfolgreichen Ergebnisse in einem ZIP-Archiv mit dem Namen {output_filename}_{timestamp}.zip zu bündeln (oder batch_{timestamp}.zip, falls kein benutzerdefinierter Name angegeben wird). ZIP-Ausgabe erfordert einen Plan mit Zugriff auf ZIP-Ausgabe (Studio, Production oder Enterprise) und mehrere URLs in der Anfrage.

Wie prüfe ich den Status eines Batch-Konvertierungsjobs?#

Frage GET /v1/convert/batch/{batch_id} mit deinem privaten API-Key per Polling ab. Die Antwort meldet processing, completed, partial oder failed, zusammen mit URL-bezogenen Einträgen, die download_url, output_file_size und duration enthalten.

Warum gibt meine Batch-Anfrage 403 Forbidden zurück?#

Ein 403 Forbidden bedeutet, dass eine Plan-Einschränkung ausgelöst wurde: Async-Verarbeitung ist in deinem Plan nicht verfügbar, Batch-Verarbeitung ist deaktiviert (Batch-Limit ist 0), die Batch-Größe überschreitet das Limit deines Plans, oder ein freischaltbares Feature wie ZIP-Ausgabe oder Webhook-Callbacks ist nicht in deinem Plan enthalten.

Kann ich Batch-Verarbeitung mit einem öffentlichen API-Key verwenden?#

Nein. Batch-Verarbeitung erfordert einen privaten API-Key (sk_...). Öffentliche Keys sind auf synchrone Anfragen mit einer einzelnen URL beschränkt, und das Absenden mehrerer URLs mit einem öffentlichen Key liefert 400 Bad Request zurück.