> ## 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 Przewodnik po integracji API renderowania stron

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

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

WebExtrator API renderowania stron to usługa renderowania stron oparta na bezgłowym Chromium. Podaj URL,
zwraca całkowicie wyrenderowany HTML (w tym treści wstrzyknięte przez JS), czysty tekst, tytuł strony i ostateczny URL.

Render to najniższy poziom interfejsu WebExtrator. Jeśli potrzebujesz **ustrukturyzowanych** wyników ekstrakcji (treść artykułu,
ceny produktów, składniki przepisu …), użyj
[`/webextrator/extract`](development_webextrator_extract) — działa na tej samej podstawie renderowania
i uruchamia pełną linię ekstrakcji typów.

## Proces aplikacji

Aby korzystać z usługi WebExtrator, najpierw przejdź do [konsoli Ace Data Cloud](https://platform.acedata.cloud/console/applications), aby uzyskać swój token API, zachowując go na później.

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

Jeśli nie jesteś zalogowany lub zarejestrowany, automatycznie zostaniesz przekierowany na stronę logowania, aby zarejestrować się i zalogować, a po zakończeniu zostaniesz automatycznie przekierowany z powrotem na bieżącą stronę.

**Jeden token API wystarczy do wywołania wszystkich usług platformy, nie ma potrzeby składania osobnych wniosków dla każdej usługi.** Pierwsze zgłoszenie otrzyma darmowy limit, aby móc skorzystać z usługi; w przypadku niewystarczającego limitu można doładować saldo ogólne w [konsoli](https://platform.acedata.cloud/console/coin).

> 📘 Pełna dokumentacja: [Strona usługi WebExtrator →](https://platform.acedata.cloud/service/webextrator)

## Autoryzacja

Wszystkie interfejsy WebExtrator używają standardowej autoryzacji Bearer Token:

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

## Parametry żądania

| Pole                | Typ       | Wymagane | Domyślne                   | Opis                                                                                                                       |
| ------------------- | --------- | :------: | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `url`               | string    |     ✅    | —                          | URL strony do renderowania, musi być `http(s)://`.                                                                         |
| `user_agent`        | string    |     ❌    | Wbudowana rotacja UA       | Niestandardowy User-Agent.                                                                                                 |
| `timeout`           | number    |     ❌    | `30`                       | Czas oczekiwania na pojedynczą nawigację (**sekundy**).                                                                    |
| `wait_until`        | enum      |     ❌    | `networkidle`              | Zdarzenie zakończenia ładowania: `load` / `domcontentloaded` / `networkidle` / `commit`.                                   |
| `delay`             | number    |     ❌    | `0`                        | **Dodatkowy czas oczekiwania w sekundach** po wyzwoleniu `wait_until` (do ponownego renderowania SPA).                     |
| `wait_for_selector` | string    |     ❌    | —                          | Czekaj na pojawienie się tego selektora CSS, bardziej stabilne niż `networkidle`.                                          |
| `block_resources`   | string\[] |     ❌    | `["image","font","media"]` | Typy zasobów do zablokowania, opcjonalne: `image` / `font` / `media` / `stylesheet` / `xhr` / `fetch`.                     |
| `headers`           | object    |     ❌    | —                          | Dodatkowe nagłówki HTTP (np. `{"Accept-Language": "en-US"}`).                                                              |
| `cookies`           | array     |     ❌    | —                          | Ciasteczka wstrzykiwane przed nawigacją, struktura poniżej.                                                                |
| `callback_url`      | string    |     ❌    | —                          | Adres zwrotny w trybie asynchronicznym, platforma wyśle pełne wyniki na ten adres po zakończeniu zadania.                  |
| `bypass_cache`      | boolean   |     ❌    | `false`                    | Pomijaj odczyt z pamięci podręcznej Redis (ale nadal zapisze wyniki w pamięci podręcznej).                                 |
| `cache_ttl_seconds` | number    |     ❌    | `3600`                     | Niestandardowy TTL pamięci podręcznej dla tego zapisu, przekazanie `0` oznacza brak pamięci podręcznej dla tej odpowiedzi. |
| `async`             | boolean   |     ❌    | `false`                    | Ustaw na `true`, aby natychmiast zwrócić `task_id`, wyniki można pobrać przez `callback_url` lub API zadań.                |

> Umowa platformy używa jednolicie **snake\_case**. Wewnętrzne usługi renderowania obsługują camelCase, ale zewnętrzne wywołania zawsze
> używają snake\_case.

### Struktura ciasteczek

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

## Odpowiedź synchronizacyjna

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-e29b-41d4-a716-446655440000",
  "trace_id": "550e8400-e29b-41d4-a716-446655440001",
  "started_at": 1777717800.123,
  "finished_at": 1777717801.234,
  "elapsed": 1.111,
  "data": {
    "kind": "render",
    "url": "https://example.com",
    "finalUrl": "https://example.com/",
    "title": "Example Domain",
    "status": 200,
    "html": "<!DOCTYPE html><html>...</html>",
    "text": "Example Domain\nThis domain is for use in illustrative examples...",
    "userAgent": "Mozilla/5.0 ...",
    "elapsedMs": 1108
  }
}
```

| Pole                 | Typ            | Opis                                                                                                |
| -------------------- | -------------- | --------------------------------------------------------------------------------------------------- |
| `data.kind`          | string         | Stałe `"render"`.                                                                                   |
| `data.url`           | string         | URL, który przesłałeś.                                                                              |
| `data.finalUrl`      | string         | Ostateczny URL po przekierowaniach.                                                                 |
| `data.title`         | string         | `document.title` po renderowaniu.                                                                   |
| `data.status`        | number \| null | Kod stanu HTTP głównej nawigacji.                                                                   |
| `data.html`          | string         | Całkowity wyrenderowany HTML.                                                                       |
| `data.text`          | string         | Zrzut `document.body.innerText` (jeśli potrzebujesz czystszej treści, użyj Extract).                |
| `data.userAgent`     | string         | Rzeczywisty używany UA.                                                                             |
| `data.elapsedMs`     | number         | Czas renderowania w przeglądarce.                                                                   |
| `data.cached`        | boolean?       | `true`, gdy trafiono w pamięć podręczną.                                                            |
| `data.cacheStoredAt` | number?        | Znacznik czasu Unix w milisekundach, kiedy wpis pamięci podręcznej został po raz pierwszy zapisany. |

## Odpowiedź asynchroniczna

`async=true` (lub podanie `callback_url`) natychmiast zwraca (HTTP 200):

```json theme={null}
{
  "success": true,
  "task_id": "550e8400-...",
  "trace_id": "6ba7b810-...",
  "started_at": 1777717800.123
}
```

Wyniki zostaną przesłane za pomocą `POST` do `callback_url` (jeśli skonfigurowano), lub można je
aktywnie sprawdzić przez [`/webextrator/tasks`](development_webextrator_tasks).

### Struktura callbacku

Platforma `POST` wysyła **dokładnie taką samą** paczkę jak w trybie synchronizacyjnym do `callback_url`,
`Content-Type: application/json`. Zwrócenie dowolnego `2xx` uznawane jest za potwierdzenie; `5xx` będzie
ponownie próbowane z wykładniczym opóźnieniem przez około 5 minut.

## Odpowiedź błędu

| HTTP | `error.code`     | Znaczenie                                                                                                     |
| ---- | ---------------- | ------------------------------------------------------------------------------------------------------------- |
| 400  | `bad_request`    | Ciało żądania nie przeszło walidacji Zod (brak `url`, nieprawidłowy typ …).                                   |
| 401  | `unauthorized`   | Brak lub nieprawidłowy `Authorization: Bearer …`.                                                             |
| 402  | (x402)           | Niewystarczający saldo na platformie, zwróć x402 wymaganie płatności envelope.                                |
| 408  | `timeout`        | Nawigacja przekroczyła `timeout`.                                                                             |
| 429  | `queue_busy`     | Kolejka synchronizacji jest zajęta, spróbuj ponownie lub użyj `async=true`.                                   |
| 500  | `internal_error` | Nieprzetworzony wyjątek po stronie serwera (np. awaria przeglądarki), Worker automatycznie spróbuje ponownie. |

Struktura błędu:

```json theme={null}
{
  "success": false,
  "task_id": "...",
  "trace_id": "...",
  "started_at": 1777717800.123,
  "finished_at": 1777717800.135,
  "elapsed": 0.012,
  "error": { "code": "bad_request", "message": "url: Nieprawidłowy url" }
}
```

## Przykład

### 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);
```

### Asynchronicznie + 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"
  }'
```

Natychmiast zwraca `{ "success": true, "task_id": "...", "trace_id": "...", "started_at": 1777717800.123 }`;
Gdy zadanie zostanie zakończone, platforma wyśle pełny wynik na twój `callback_url`.

### Wymuszenie ominięcia pamięci podręcznej

```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
  }'
```

## Wskazówki i pułapki

* **Wybór `wait_until` jest bardzo ważny.** `networkidle` jest najstabilniejszy, ale najwolniejszy; `domcontentloaded` jest szybki, ale może pominąć asynchronicznie wstrzykiwane treści; `load` jest odpowiedni dla tradycyjnych statycznych stron.
* **Klucz pamięci podręcznej ignoruje `async`.** Synchronizacja i asynchroniczne żądania dla tego samego URL trafiają do tego samego wpisu w pamięci podręcznej, swobodne przełączanie nie spowoduje niepowodzenia.
* **Klucz pamięci podręcznej ignoruje `bypass_cache` i `cache_ttl_seconds`.** Te dwa są przełącznikami operacyjnymi, nie wpływają na treść odpowiedzi.
* **`cookies` i `headers` będą miały oddzielne pamięci podręczne.** Dostosowanie tych dwóch spowoduje, że pierwsze takie same kombinacje nie będą trafiały.
* **Reaktywne SPA często przekracza domyślne 30 sekund.** Zaleca się `timeout: 60`, `wait_until: "domcontentloaded"`, `delay: 4`, a następnie w połączeniu z `wait_for_selector` czekać na naprawdę istotne elementy.
* **`block_resources` to najszybsza droga do zmniejszenia opóźnienia.** Domyślnie zablokowane są obrazy / czcionki / media; jeśli nie zależy ci na układzie CSS, dodanie `stylesheet` może przyspieszyć jeszcze bardziej.
