Zum Inhalt springen

Seitenberichte-API-Referenz

Request- und Response-Formen der fünf inferenzfreien Berichts-Endpunkte einer Session: Consent, Agentensicht, Ziele, Kündigung und Screenshot.

Zuletzt aktualisiert:

Fünf Endpunkte auf einer laufenden Session beantworten strukturelle Fragen zu einer Seite, ohne je ein Modell aufzurufen: welche Consent-Plattform erscheint und was der Browser schon vor jeder Entscheidung hielt, wie der Baum des Agenten aussieht, wohin jedes Bedienelement führt, ob eine Kündigungsmöglichkeit erreichbar ist, und ein Bild der Seite. Alle fünf sind POSTs gegen eine Session-ID mit deinem bb_-Schlüssel als Bearer-Token, und alle fünf entstehen aus derselben Wahrnehmung, auf der auch der Agent arbeitet. Genau deshalb funktionieren sie auf einem Deployment, das Sessions hat und überhaupt kein Inference-Gateway.

Sie kamen mit Protokoll 1.5. Ein Client, der x-browserberg-protocol: 1.5.0 an einen älteren Server meldet, wird mit protocol_incompatible abgewiesen, statt die Lücke Route für Route zu entdecken. Ein Deployment, das die Berichte anbietet, führt reports im Array features von GET /v1/me; eines ohne sie registriert die Routen gar nicht, ein Aufruf bekommt also not_found.

Drei Fehler lohnen eine eigene Verzweigung. Ein Body, der die Validierung nicht besteht, ist invalid_request (400), mit den ersten zehn Schema-Beanstandungen in details.issues. Eine Session, die es nicht gibt oder die einer anderen Organisation gehört, ist not_found (404) — bewusst dieselbe Antwort für beides. Eine Adresse, die der Browser nicht öffnen kann, wegen DNS, TLS oder eines gesperrten Schemas, ist navigation_failed (422). Eine Seite, die einfach nie fertig lädt, ist dagegen kein Fehler: Nach fünfzehn Sekunden wird der Bericht so genommen, wie die Seite steht, und eine Zeile landet in warnings.

POST /v1/sessions/:id/consent-report

Welche Consent-Plattform erscheint, was der Browser vor jeder Entscheidung hielt und was ein Ablehnen verändert hat.

POST /v1/sessions/:id/agent-view

Die Seite, wie der Agent sie liest, in bis zu drei Detailstufen, samt den gefundenen Bedienelementen.

Agentensicht: Anfrage

Name Typ Beschreibung
url string Wird zuerst geöffnet, wie oben. Weglassen für die Seite, auf der die Session steht.
fidelities string[] Ein bis drei aus `full`, `economy` und `lean`. Jeder Eintrag rendert DENSELBEN Baum; nur die Auslassung unterscheidet sich, die Element-IDs stimmen über alle Darstellungen hinweg überein. Standard: [full, economy, lean]
screenshot boolean Legt ein JPEG des sichtbaren Bereichs in Qualität 60 bei. Standard: true
maxChars integer 1000 bis 400000, eine Obergrenze je gerenderter Sicht. Ein Abschneiden steht in `views[].truncated` und geschieht nie stillschweigend.
consent string `reject`, `accept` oder `off` — wie ein Banner behandelt wird, bevor die Seite gelesen wird. Standard: reject

Agentensicht: Antwort

Name Typ Beschreibung
url string Die gelesene Seite.
views array Ein Eintrag je angeforderter Detailstufe: `{fidelity, text, chars, lines, truncated}`.
controls array Ein Eintrag je interaktivem Element, ohne dessen Teilbaum: `{encodedId, role, name, tag, jsClickable, hasAccessibleName}`. Genug, um Lesbarkeit zu beurteilen, und zu wenig, um die Seite nachzubauen.
stats object `{rawNodes, keptNodes, frames, occluded, offscreen, warnings}` — wie viel von der Seite das Beschneiden überstanden hat, und warum.
world string `extension` oder `cdp-fallback`: welche Ausführungswelt gelesen hat.
consentDismissed boolean Ob vor der Aufnahme des Baums tatsächlich ein Banner geräumt wurde.
screenshot object Vorhanden, sofern du `screenshot` nicht auf false gesetzt hast.
warnings string[] Die Warnungen der Navigation und die der Seitenvorbereitung, aneinandergehängt.
durationMs integer Vergangene Zeit für den ganzen Aufruf.

Die controls-Liste lesen

jsClickable kennzeichnet ein Element ohne eigene interaktive Rolle, das nur anklickbar ist, weil ein Skript darauf lauscht — üblich bei Portalen, die aus gestylten divs gebaut sind. hasAccessibleName ist false für ein Bedienelement, das weder ein Agent noch ein Screenreader beim Namen ansprechen kann, und das ist meist die nützlichste Zahl der Seite: Eine Oberfläche, deren halbe Schaltflächen namenlos sind, macht einem Agenten aus Gründen zu schaffen, die mit dem Modell nichts zu tun haben.

Der gerenderte text ist Seiteninhalt. Behandle ihn als nicht vertrauenswürdig und zäune ihn ein, bevor er in einen weiteren Prompt gerät — genau wie den Baum, den observe zurückgibt.

POST /v1/sessions/:id/destination-report

Löst in der Seite auf, wohin jeder Link, jede Schaltfläche und jedes Formular wirklich führt, und wie der Ziel-Wächter das jeweils beurteilen würde.

Ziel-Bericht: Anfrage

Name Typ Beschreibung
url string Wird zuerst geöffnet. Weglassen für die Seite, auf der die Session steht.
limit integer Wie viele Bedienelemente aufgelöst werden, in Dokumentreihenfolge, 1 bis 500. Gab es mehr, ist `truncated` true. Standard: 200
consent string `reject`, `accept` oder `off`. Ein stehen gelassenes Banner verdeckt die Bedienelemente dahinter. Standard: reject

Ziel-Bericht: Antwort

Name Typ Beschreibung
url string Die Seite, auf der gezählt wurde.
anchorSite string | null Die registrierbare Site der Seite selbst — daran wird `sameSite` gemessen.
secure boolean Die Seite selbst wurde über https ausgeliefert.
controls array `{encodedId, role, name, action, destination, site, sameSite, risk, blockedUnderDefault, blockedUnderStrict}`, je aufgelöstem Bedienelement einmal.
summary object `{total, sameSite, offSite, offSiteSubmit, insecureSubmit, unsafeScheme, scriptOnly, unresolved}` — die Zahlen, auf die die meisten Aufrufer wirklich verzweigen.
truncated boolean Es gab mehr Bedienelemente, als `limit` zuließ.
warnings string[] Warnungen aus Navigation und Seitenvorbereitung.
durationMs integer Vergangene Zeit für den ganzen Aufruf.

Wie ein einzelnes Element beurteilt wird

action ist das, was ein Agent mit dem Element täte — click, type, select oder scroll —, entschieden aus Rolle und Tag, nie aus einer Anweisung. destination ist {url, via, method?, target?, hasFileInput?, unresolved?}, und via hält fest, woher das Ziel stammt: href, ancestor-href, formaction, form, implicit-submit, script, wenn nur Code weiß, wohin es geht, oder none, wenn gar nichts gefunden wurde.

risk ist der Befund des Ziel-Wächters für dieses eine Element, einzeln beurteilt. Der Wächter hält sonst beim ersten blockierten Schritt eines Plans an, was für einen Plan richtig und für eine Zählung falsch ist, also läuft jedes Element für sich hindurch. off_site_submit, insecure_submit und unsafe_scheme werden schon unter der Standard-Policy verweigert und setzen blockedUnderDefault; off_site_navigation ist standardmäßig erlaubt — eine SSO-Weiterleitung verlässt die Site aus gutem Grund — und setzt nur blockedUnderStrict. Ein href mit Skript-Schema ist überhaupt kein Risiko: Alte Portale schreiben so etwas an jeden Tabellenlink, der Wächter lässt es in Ruhe, und der Bericht sagt nur, was er gesehen hat.

POST /v1/sessions/:id/cancellation-report

Sucht auf einer Startseite ein Bedienelement, dessen Beschriftung nach Kündigung klingt, löst dessen Ziel auf und beschreibt die Seite dahinter.

Kündigungs-Bericht: Anfrage

Name Typ Beschreibung
url erforderlich string Die Seite, von der aus eine Verbraucherin startet. Pflicht, denn die Frage dieses Berichts ist die Erreichbarkeit von genau hier aus.
consent string `reject`, `accept` oder `off`. Standard: reject
follow boolean Öffnet das aufgelöste Ziel des besten Kandidaten und beschreibt es. Geklickt wird das Element nie und abgeschickt wird nichts; die Zieladresse wird direkt geöffnet. Standard: true
screenshot boolean Nimmt die Startseite auf, und die gefolgte Seite ebenfalls, wenn eine gefolgt wurde. JPEG des sichtbaren Bereichs in Qualität 60. Standard: true

Kündigungs-Bericht: Antwort

Name Typ Beschreibung
url string Die angefragte Startseite.
finalUrl string Wo diese Seite nach Weiterleitungen gelandet ist.
candidates array `{encodedId, role, name, matchedPhrase, destination, site, sameSite}`. `matchedPhrase` ist der Eintrag aus dem Kündigungs-Wortschatz des Produkts, auf den die Beschriftung passte — so ist nachvollziehbar, warum ein Element aufgefallen ist.
followed object | null `{encodedId, targetUrl, confirmationControls, fields, screenshot?}`, oder null, wenn nichts gefolgt wurde.
screenshot object Die Startseite, wenn du Bilder angefordert hast.
warnings string[] Sagt, wenn kein Kandidat gefunden wurde, und wenn es Kandidaten gab, denen aber keiner gefolgt werden konnte.
durationMs integer Vergangene Zeit für den ganzen Aufruf, beide Seiten eingerechnet.

Was follow wirklich tut

Gefolgt wird dem ersten Kandidaten, dessen Ziel eine Adresse hat und nicht auf eine andere registrierbare Site führt. Einem Kandidaten, dessen Ziel nur ein Skript kennt, kann man ohne Drücken nicht folgen, und eine Kündigung unbeaufsichtigt zu drücken ist genau das, was das Produkt verweigert — er wird also übersprungen, und eine Warnung sagt warum. followed ist deshalb in vier verschiedenen Lagen null: kein Kandidat gefunden, follow war false, alle Kandidaten führten weg von der Site oder waren skriptgesteuert, oder das Ziel ließ sich nicht öffnen.

Wurde eine Seite gefolgt, listet confirmationControls die Schaltflächen und Links darauf, deren Beschriftung nach dem bestätigenden Druck klingt — wieder der Kündigungs-Wortschatz, dazu die üblichen Bestätigungs- und Absende-Wörter auf Deutsch und Englisch. fields listet, was die Seite verlangt, als {role, name, required}, wobei required null ist, wenn die Seite dazu nichts gesagt hat. Das ist die interessante Hälfte für eine Verbraucherfrage: Eine Kündigung, die einen Klick entfernt ist und dann eine Kundennummer verlangt, ist eine andere Erfahrung als eine, die das nicht tut.

POST /v1/sessions/:id/screenshot

Ein Bild der Seite, nachdem das Consent-Banner behandelt wurde, sichtbarer Bereich oder ganzes Dokument.

Screenshot: Anfrage

Name Typ Beschreibung
url string Wird zuerst geöffnet. Weglassen, um die Seite aufzunehmen, auf der die Session steht.
format string `jpeg` oder `png`. JPEG ist Standard, weil niemand die Pixel liest und eine ganzseitige Portalaufnahme als PNG megabyteweise anfällt. Standard: jpeg
quality integer 1 bis 100. Nur für JPEG; bei PNG wirkungslos. Standard: 60
fullPage boolean Nimmt das ganze Dokument statt des sichtbaren Bereichs auf. Die Höhe kommt aus den Layout-Metriken der Seite und wird bei 16384 CSS-Pixeln gekappt, denn eine Aufnahme über 200000 Pixel ist kein Screenshot mehr. Standard: false
consent string `reject`, `accept` oder `off`. Nur `off` überspringt das Wegklicken ganz und lässt das Banner im Bild. Standard: reject
waitMs integer Zusätzliche Beruhigungszeit nach dem Laden, 0 bis 15000, für Seiten, die spät zeichnen. Danach bekommt das Netz ohnehin bis zu 1,5 s, um still zu werden. Standard: 0

Screenshot: Antwort

Name Typ Beschreibung
url string Die aufgenommene Seite.
contentType string `image/jpeg` oder `image/png`.
base64 string Die Bildbytes, base64-kodiert, damit ein Bericht ein einziges JSON-Dokument bleibt, das man aufheben kann.
width integer Breite der Aufnahme in CSS-Pixeln.
height integer Höhe der Aufnahme in CSS-Pixeln, nach der Kappung bei ganzseitigen Bildern.
fullPage boolean Gibt zurück, was angefordert wurde.
consentDismissed boolean Ob vor dem Auslösen tatsächlich ein Banner geräumt wurde.
durationMs integer Vergangene Zeit für den ganzen Aufruf.

Hinweis · Beobachtungen, niemals Urteile

Der Consent-Bericht sagt, welche Cookies gesetzt waren, bevor überhaupt eine Wahl angeboten wurde. Er sagt nicht, dass eine Site rechtskonform ist, und kein Feld auf der Leitung trägt eine Note. Der Kündigungs-Bericht sagt, ob ein Element mit Kündigungs-Beschriftung gefunden wurde, wohin es führte und was die Seite dahinter verlangte; er sagt nicht, dass eine gesetzliche Anforderung erfüllt ist. Das Urteil gehört der Person, die den Bericht liest, und eine Form, die ein Urteil trüge, würde als solches zitiert.

Zwei Berichte auf einer Session

Eine Session, zwei Berichte, keine Inferenz. Die cURL-Variante zeigt die rohe Form auf der Leitung; die SDKs liefern dasselbe Dokument geparst.

Voraussetzungen: api-key

BASE="https://browserberg.com"
AUTH="Authorization: Bearer $BROWSERBERG_API_KEY"
JSON="Content-Type: application/json"

ID=$(curl -s -X POST "$BASE/v1/sessions" -H "$AUTH" -H "$JSON" -d '{"ttlSeconds": 180}' \
  | python3 -c 'import json,sys; print(json.load(sys.stdin)["session"]["id"])')

# No model call: the report is computed from the page, so it costs browser time only.
curl -s -X POST "$BASE/v1/sessions/$ID/consent-report" -H "$AUTH" -H "$JSON" -d '{
  "url": "https://shop.example.com/", "policy": "reject", "waitMs": 5000
}' | python3 -c 'import json,sys; r = json.load(sys.stdin); print(json.dumps({
      "cmp": r["cmp"],
      "bannerDetectedAtMs": r["bannerDetectedAtMs"],
      "summary": r["summary"]}, indent=2))'

curl -s -X DELETE "$BASE/v1/sessions/$ID" -H "$AUTH" > /dev/null

Weiter im Stoff

  • Consent- und Ziel-Berichte Dieselben fünf Endpunkte als Aufgabe, von Anfang bis Ende
  • Consent-Autopilot Wie ein Banner erkannt und geräumt wird
  • Session-Verben Die modellgestützte Hälfte: observe, act, extract
  • Fehler und Wiederholungen Der Umschlag, den alle Fehler oben teilen