> ## Documentation Index
> Fetch the complete documentation index at: https://docs.acedata.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# WebExtrator Webseitenrendering API Integrationsleitfaden

> WebExtrator Web Render & Extract API guide - Ace Data Cloud

`POST https://api.acedata.cloud/webextrator/render`

Die WebExtrator Webseitenrendering API ist ein auf Headless Chromium basierender Webseitenrendering-Dienst. Geben Sie eine URL an, um das vollständig gerenderte HTML (einschließlich JS-injizierter Inhalte), reinen Text, den Seitentitel und die endgültige URL zurückzugeben.

Render ist die grundlegendste Schnittstelle von WebExtrator. Wenn Sie **strukturierte** Extraktionsergebnisse (Artikelinhalt, Produktpreise, Rezeptzutaten …) benötigen, verwenden Sie
[`/webextrator/extract`](development_webextrator_extract) — es führt auf derselben Rendering-Basis eine vollständige Typisierungsextraktionspipeline aus.

## Antragsprozess

Um den WebExtrator-Dienst zu nutzen, gehen Sie zunächst zur [Ace Data Cloud Konsole](https://platform.acedata.cloud/console/applications), um Ihr API-Token zu erhalten, das Sie für später aufbewahren sollten.

![](https://cdn.acedata.cloud/5hmkdg.jpg)

Wenn Sie noch nicht angemeldet oder registriert sind, werden Sie automatisch zur Anmeldeseite weitergeleitet, die Sie zur Registrierung und Anmeldung einlädt. Nach Abschluss werden Sie automatisch zur aktuellen Seite zurückgeleitet.

**Ein API-Token reicht aus, um auf alle Dienste der Plattform zuzugreifen, ohne dass für jeden Dienst separat beantragt werden muss.** Bei der ersten Beantragung erhalten Sie ein kostenloses Kontingent, um es kostenlos auszuprobieren; wenn das Kontingent erschöpft ist, können Sie im [Dashboard](https://platform.acedata.cloud/console/coin) Ihr allgemeines Guthaben aufladen.

> 📘 Vollständige Dokumentation: [WebExtrator-Dienstseite →](https://platform.acedata.cloud/service/webextrator)

## Authentifizierung

Alle WebExtrator-Schnittstellen verwenden die standardmäßige Bearer-Token-Authentifizierung:

```
Authorization: Bearer YOUR_API_KEY
Content-Type:  application/json
```

## Anfrageparameter

| Feld                | Typ       | Erforderlich | Standard                     | Beschreibung                                                                                                                                              |
| ------------------- | --------- | :----------: | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`               | string    |       ✅      | —                            | Die zu rendernde Seiten-URL, muss `http(s)://` sein.                                                                                                      |
| `user_agent`        | string    |       ❌      | Eingebauter UA-Pool-Rotation | Benutzerdefinierter User-Agent.                                                                                                                           |
| `timeout`           | number    |       ❌      | `30`                         | Timeout für eine Navigation (**Sekunden**).                                                                                                               |
| `wait_until`        | enum      |       ❌      | `networkidle`                | Ladeereignis: `load` / `domcontentloaded` / `networkidle` / `commit`.                                                                                     |
| `delay`             | number    |       ❌      | `0`                          | **Zusätzliche Wartezeit in Sekunden**, nachdem `wait_until` ausgelöst wurde (für SPA-Zweitrendering).                                                     |
| `wait_for_selector` | string    |       ❌      | —                            | Warten auf das Erscheinen dieses CSS-Selectors, stabiler als `networkidle`.                                                                               |
| `block_resources`   | string\[] |       ❌      | `["image","font","media"]`   | Blockierte Ressourcentypen, optional: `image` / `font` / `media` / `stylesheet` / `xhr` / `fetch`.                                                        |
| `headers`           | object    |       ❌      | —                            | Zusätzliche HTTP-Anforderungsheader (z. B. `{"Accept-Language": "en-US"}`).                                                                               |
| `cookies`           | array     |       ❌      | —                            | Vor der Navigation injizierte Cookies, Struktur siehe unten.                                                                                              |
| `callback_url`      | string    |       ❌      | —                            | Callback-Adresse im asynchronen Modus, die Plattform sendet die vollständigen Ergebnisse per `POST` an diese Adresse, wenn die Aufgabe abgeschlossen ist. |
| `bypass_cache`      | boolean   |       ❌      | `false`                      | Umgehen des Redis-Cache-Lesens (aber das Ergebnis wird weiterhin in den Cache geschrieben).                                                               |
| `cache_ttl_seconds` | number    |       ❌      | `3600`                       | Benutzerdefinierte TTL für das aktuelle Schreiben in den Cache, `0` bedeutet, dass diese Antwort nicht im Cache gespeichert wird.                         |
| `async`             | boolean   |       ❌      | `false`                      | Setzen Sie auf `true`, um sofort `task_id` zurückzugeben, die Ergebnisse können über `callback_url` oder die Tasks-API abgerufen werden.                  |

> Die Plattformverträge verwenden einheitlich **snake\_case**. Die internen Rendering-Dienste unterstützen camelCase, aber externe Aufrufe verwenden immer snake\_case.

### Cookie-Struktur

```json theme={null}
{
  "name":      "string",
  "value":     "string",
  "domain":    "string",
  "path":      "/",
  "expires":   1735689600,
  "httpOnly":  false,
  "secure":    true,
  "sameSite":  "Lax"
}
```

## Synchronisierte Antwort

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "trace_id": "550e8400-e29b-41d4-a716-446655440001",
  "started_at": "2026-05-02T10:30:00.123Z",
  "finished_at": "2026-05-02T10:30:01.234Z",
  "elapsed": 1.111,
  "data": {
    "kind": "render",
    "url": "https://example.com",
    "finalUrl": "https://example.com/",
    "title": "Beispiel-Domain",
    "status": 200,
    "html": "<!DOCTYPE html><html>...</html>",
    "text": "Beispiel-Domain\nDiese Domain wird für illustrative Beispiele verwendet...",
    "userAgent": "Mozilla/5.0 ...",
    "elapsedMs": 1108
  }
}
```

| Feld                 | Typ            | Beschreibung                                                                              |
| -------------------- | -------------- | ----------------------------------------------------------------------------------------- |
| `data.kind`          | string         | Festgelegt auf `"render"`.                                                                |
| `data.url`           | string         | Die von Ihnen eingereichte URL.                                                           |
| `data.finalUrl`      | string         | Die endgültige URL nach der Weiterleitung.                                                |
| `data.title`         | string         | Der gerenderte `document.title`.                                                          |
| `data.status`        | number \| null | Der HTTP-Statuscode der Hauptnavigation.                                                  |
| `data.html`          | string         | Vollständiges gerendertes HTML.                                                           |
| `data.text`          | string         | Snapshot von `document.body.innerText` (verwenden Sie Extract für einen saubereren Text). |
| `data.userAgent`     | string         | Tatsächlich verwendeter UA.                                                               |
| `data.elapsedMs`     | number         | Nur die Zeit, die für das Rendern im Browser benötigt wurde.                              |
| `data.cached`        | boolean?       | `true`, wenn der Cache getroffen wurde.                                                   |
| `data.cacheStoredAt` | number?        | Unix-Millisekunden-Zeitstempel, wann der Cacheeintrag erstmals geschrieben wurde.         |

## Asynchrone Antwort

Wenn `async=true` (oder `callback_url` bereitgestellt wird), wird sofort zurückgegeben (HTTP 200):

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-...",
  "trace_id": "6ba7b810-...",
  "started_at": "2026-05-02T10:30:00.123Z"
}
```

Die Ergebnisse werden per `POST` an `callback_url` gesendet (wenn konfiguriert) oder können über
[`/webextrator/tasks`](development_webextrator_tasks) aktiv abgefragt werden.

### Callback-Struktur

Die Plattform sendet ein `POST` mit einem **genau gleichen** Envelope wie im synchronen Modus an `callback_url`,
`Content-Type: application/json`. Eine Rückgabe von beliebigen `2xx` wird als bestätigt angesehen; `5xx` wird mit exponentiellem Backoff etwa 5 Minuten lang erneut versucht.

## Fehlerantwort

| HTTP | `error.code`     | Bedeutung                                                                                                 |
| ---- | ---------------- | --------------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`    | Der Anfragekörper hat die Zod-Überprüfung nicht bestanden (fehlendes `url`, falscher Typ …).              |
| 401  | `unauthorized`   | Fehlendes oder ungültiges `Authorization: Bearer …`.                                                      |
| 402  | (x402)           | Plattformguthaben unzureichend, Rückgabe von x402 Zahlungsanforderung Umschlag.                           |
| 408  | `timeout`        | Navigation hat `timeout` überschritten.                                                                   |
| 429  | `queue_busy`     | Synchronisierungswarteschlange überlastet, bitte erneut versuchen oder `async=true` verwenden.            |
| 500  | `internal_error` | Serverseitige nicht behandelte Ausnahme (Browserabsturz usw.), Worker versucht automatisch einmal erneut. |

Fehlerstruktur:

```json theme={null}
{
  "success": false,
  "task_id": "...",
  "trace_id": "...",
  "started_at": "...",
  "finished_at": "...",
  "elapsed": 0.012,
  "error": { "code": "bad_request", "message": "url: Ungültige url" }
}
```

## Beispiel

### cURL

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "wait_until": "networkidle",
    "block_resources": ["image", "media", "font"]
  }'
```

### Python (requests)

```python theme={null}
import os, requests

API_KEY = os.environ["ACEDATA_API_KEY"]

resp = requests.post(
    "https://api.acedata.cloud/webextrator/render",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    json={
        "url": "https://example.com",
        "wait_until": "networkidle",
        "block_resources": ["image", "media", "font"],
    },
    timeout=60,
)
resp.raise_for_status()
data = resp.json()["data"]
print(data["title"], data["status"], len(data["html"]))
```

### Node.js (fetch)

```js theme={null}
const apiKey = process.env.ACEDATA_API_KEY;

const res = await fetch('https://api.acedata.cloud/webextrator/render', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    url: 'https://example.com',
    wait_until: 'networkidle',
    block_resources: ['image', 'media', 'font'],
  }),
});
const { data } = await res.json();
console.log(data.title, data.status, data.html.length);
```

### Asynchron + Callback

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "async": true,
    "callback_url": "https://your-app.example.com/hooks/webextrator"
  }'
```

Sofortige Rückgabe `{ "success": true, "task_id": "...", "trace_id": "...", "started_at": "..." }`;
Wenn die Aufgabe abgeschlossen ist, wird die Plattform die vollständigen Ergebnisse an deine `callback_url` POSTen.

### Zwangsweise Cache-Umgehung

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/render \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "bypass_cache": true
  }'
```

## Hinweise und Fallstricke

* **Die Wahl von `wait_until` ist sehr wichtig.** `networkidle` ist am stabilsten, aber am langsamsten; `domcontentloaded` ist schnell, könnte aber asynchron injizierte Inhalte übersehen; `load` eignet sich für traditionelle statische Seiten.
* **Cache-Keys ignorieren `async`.** Synchronisierte und asynchrone Anfragen an dieselbe URL treffen denselben Cache-Eintrag, ein beliebiger Wechsel hat keine Auswirkungen.
* **Cache-Keys ignorieren `bypass_cache` und `cache_ttl_seconds`.** Diese beiden sind Schalter, die den Antwortinhalt nicht beeinflussen.
* **`cookies` und `headers` werden in separaten Caches gespeichert.** Das Anpassen dieser beiden führt dazu, dass die erste gleiche Kombination fehlschlägt.
* **Reaktive SPAs überschreiten häufig die Standardzeit von 30 Sekunden.** Es wird empfohlen, `timeout: 60`, `wait_until: "domcontentloaded"`, `delay: 4` zu verwenden und zusätzlich `wait_for_selector` zu verwenden, um auf wirklich relevante Elemente zu warten.
* **`block_resources` ist der schnellste Weg, um die Latenz zu reduzieren.** Standardmäßig sind Bilder / Schriftarten / Medien blockiert; wenn du Extraktionen machst, die nicht von CSS-Layouts abhängen, kannst du mit `stylesheet` noch schneller werden.
