Alle Integrationen

API-Referenz von Guard.ch

Alle Endpunkte, die du mit einem App-Schlüssel aufrufen kannst, mit Feldern, Beispielen und Fehlern.

Hier steht, was die API annimmt und zurückgibt. Wie du vom App-Schlüssel zum laufenden Playwright-Skript kommst, zeigt die Anleitung zur eigenen Integration. KI-Assistenten bindest du einfacher über MCP an.

Grundlagen

Basis-URL
https://api.guard.ch/v8
Authentifizierung
Ein App-Schlüssel im Authorization-Header
Format
JSON über HTTPS
Zugang
Guard Analyst oder Guard Team, auch in der Testphase

Die Pfade in dieser Referenz beziehen sich auf die Basis-URL. Schick einen Body immer als JSON mit Content-Type: application/json. Antworten können weitere Felder enthalten, die hier fehlen; ignoriere einfach, was du nicht brauchst.

App-Schlüssel erstellst du unter Apps im Dashboard. Ein Schlüssel handelt für dein Konto: Die Sitzungen, die er startet, gehören dir, zählen gegen deine Limits und stehen in deiner Sitzungsliste.

App-Schlüssel erstellen

Authentifizierung

Schick den Schlüssel bei jeder Anfrage mit:

Authorization: Bearer YOUR_API_KEY

Schlüssel beginnen mit brl-k-v7-. Die API liest sie nur aus diesem Header, nie aus der URL. GET /image ist der einzige Endpunkt auf dieser Seite, der ohne Schlüssel funktioniert. Ein Schlüssel läuft nach einem Jahr ohne Nutzung ab oder an dem festen Datum, das du beim Erstellen gewählt hast, je nachdem, was früher eintritt.

Antworten und Fehler

Jeder Endpunkt antwortet mit HTTP 200 und einem JSON-Body. Ob es geklappt hat, steht im Feld status. Prüf also dieses Feld und nicht den HTTP-Code:

StatusBedeutung
okDie Anfrage hat geklappt. Die übrigen Felder enthalten das Ergebnis.
deniedDie Anfrage wurde abgelehnt, zum Beispiel weil der Schlüssel fehlt oder abgelaufen ist, ein Wert ungültig ist, kein Sitzungsplatz frei ist oder es die Sitzung nicht gibt.
upgradeDein Plan enthält das nicht: den API-Zugang selbst oder eine Option wie einen Standort, einen eigenen Proxy oder den Residential-Ausgang.
errorBei uns ist etwas schiefgelaufen, oder den Pfad gibt es nicht. Versuch es später noch einmal.

Werte jeden anderen Status als ok als Fehler. message nennt den Grund in einem Satz, den du einer Person zeigen kannst. Die Sprache folgt dem Header Accept-Language und ist ohne ihn Englisch. Werte den Text deshalb nicht aus, sondern verzweige nach status und, falls vorhanden, nach code.

{
  "status": "denied",
  "message": "This browser session could not be found. Check the session ID and try again."
}

Fehlt der Schlüssel oder ist er ungültig, widerrufen oder abgelaufen, lautet die Antwort denied mit loggedIn: false. Ist deine E-Mail-Adresse noch nicht bestätigt, kommt denied mit verified: false. Einzige Ausnahme von HTTP 200 sind Datei-Downloads, siehe Datei herunterladen.

Endpunkte

EndpunktBeschreibung
POST /web/sessionsSitzung starten
GET /web/sessionsEigene Sitzungen auflisten
GET /web/sessions/:idEine Sitzung abrufen
DELETE /web/sessions/:idSitzung beenden
GET /web/sessions/:id/downloads/:downloadIdVom Browser heruntergeladene Datei abholen
GET /web/usageDeine API-Nutzung der letzten 30 Tage
GET /user/quotaLimits deines Plans und was davon belegt ist
GET /imageBrowser-Images und Standorte

Sitzungen

Eine Sitzung ist ein isolierter Browser. Dein Code steuert ihn über CDP, und eine Person kann in der Live-Ansicht zuschauen oder übernehmen. Diese Endpunkte erreichen nur Sitzungen deines eigenen Kontos, nie die deiner Kolleginnen und Kollegen.

Sitzung starten

POST https://api.guard.ch/v8/web/sessions

Startet einen Browser und antwortet sofort, während der Browser im Hintergrund weiter hochfährt: status ist erst starting, dann running. Verbinde Playwright mit connectOverCDP oder Puppeteer mit browserWSEndpoint auf die connectUrl. Wird die Verbindung anfangs abgelehnt, warte, bis GET /web/sessions/:id running meldet.

Alle Felder im Body sind optional:

FeldBeschreibung
imageID des Browser-Images. Jedes aktive Image mit supports_programmatic in GET /image. Standard: chrome.
nameAnzeigename für deine Sitzungsliste, 1 bis 64 Zeichen. Ohne Angabe entsteht ein Name wie brisk-otter-27.
urlAdresse, die beim Start geöffnet wird. Erlaubt sind nur http und https.
countryStandort als Länder- oder Stadtcode aus vpnLocations in GET /image, zum Beispiel de oder us-dal. Ohne Angabe nutzt die Sitzung die Verbindung des Rechenzentrums. Nicht mit proxy kombinierbar.
egressMit residential läuft der Verkehr über einen Residential-Ausgang statt über ein Rechenzentrum. Das Land wählst du zusätzlich mit country. Der Verkehr zählt gegen das Residential-Kontingent deines Plans. Nicht mit proxy kombinierbar.
proxyDein eigener Proxy im Format protocol://[user:password@]host:port, mit http, https, socks4 oder socks5. Private und interne Adressen werden abgelehnt. Nicht mit country oder egress kombinierbar.
screenViewport als {"width": 1440, "height": 900}: Breite 320 bis 1920, Höhe 480 bis 1080. Standard: 1366 x 768.
idempotencyKeyWiederholungsschlüssel mit 1 bis 128 Zeichen. Schickst du die Anfrage innerhalb von 10 Minuten mit demselben App-Schlüssel und Wiederholungsschlüssel noch einmal, bekommst du die erste erfolgreiche Antwort zurück statt eines zweiten Browsers. Fehlgeschlagene Versuche werden nicht gespeichert; nach einer Ablehnung startet eine Wiederholung also wirklich neu.

Zum Beispiel:

curl -X POST https://api.guard.ch/v8/web/sessions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "triage-4821",
    "url": "https://example.com",
    "country": "de",
    "screen": { "width": 1440, "height": 900 },
    "idempotencyKey": "ticket-4821"
  }'
{
  "status": "ok",
  "id": "brl-v-v7-q8m2r7k4d1",
  "name": "triage-4821",
  "image": "chrome",
  "connectUrl": "wss://api.guard.ch/web/brl-v-v7-q8m2r7k4d1/cdp?token=3f9c2a7d",
  "liveViewUrl": "https://guard.ch/en/viewer?id=brl-v-v7-q8m2r7k4d1",
  "createdAt": "2026-09-26T08:14:03.512Z",
  "screen": { "width": 1440, "height": 900 },
  "quota": {
    "running_session_limit": 3,
    "running_sessions_used": 1,
    "running_sessions_remaining": 2
  }
}

Eine erfolgreiche Antwort enthält:

FeldBeschreibung
idSitzungs-ID für die anderen Endpunkte.
nameDer Name, den du angegeben hast, oder der erzeugte.
imageDas Image, auf dem die Sitzung läuft.
connectUrlCDP-WebSocket-URL für Playwright oder Puppeteer. Sie enthält ein eigenes Token der Sitzung; behandle sie wie ein Passwort.
liveViewUrlDie Live-Ansicht der Sitzung in Guard.ch, zum Zuschauen und Übernehmen. Zum Öffnen musst du in deinem Konto angemeldet sein.
createdAtStartzeit im Format ISO 8601.
screenDer Viewport, mit dem der Browser läuft.
quotaDeine gleichzeitigen Sitzungen inklusive dieser: running_session_limit, running_sessions_used und running_sessions_remaining.

Ein abgelehnter Start enthält zusätzlich einen maschinenlesbaren code:

CodeBedeutung
invalid_argumentsEin Wert ist nicht verwendbar, etwa ein fehlerhafter Proxy. Die meisten Feldprüfungen antworten ohne Code; dann nennt message das Feld.
image_not_supportedDas Image gibt es nicht, oder es kann keine API-Sitzungen ausführen. allowedImages listet die Images, die du nutzen kannst.
image_restrictedDein Plan kann dieses Image nicht starten (Status upgrade). allowedImages listet die Images, die du nutzen kannst.
quota_exceededAlle deine Sitzungsplätze sind belegt, ein Kontingent ist aufgebraucht, oder deinem Plan fehlt eine Option, die du angefragt hast. Beende eine Sitzung oder ändere die Anfrage; derselbe Aufruf noch einmal hilft nicht.
rate_limitedDu hast in kurzer Zeit zu viele Sitzungen gestartet. retryAfterMs sagt dir, wie viele Millisekunden du warten sollst.
internal_errorBei uns ist etwas fehlgeschlagen (Status error). Versuch es später noch einmal.

Sitzungen auflisten

GET https://api.guard.ch/v8/web/sessions

Gibt deine Sitzungen in data zurück, die neuste zuerst. Aufgelistet werden nur Sitzungen, die über die API oder MCP gestartet wurden. Untersuchungen, die du in Guard.ch von Hand startest, fehlen hier; mit GET /web/sessions/:id findest du sie trotzdem über ihre ID.

ParameterBeschreibung
statusall nimmt beendete Sitzungen der letzten 30 Tage dazu. Ohne den Parameter siehst du nur Sitzungen, die gerade starten oder laufen.
limitHöchstzahl der Sitzungen, 1 bis 200. Standard: 50.
curl "https://api.guard.ch/v8/web/sessions?status=all&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "status": "ok",
  "data": [
    {
      "id": "brl-v-v7-q8m2r7k4d1",
      "name": "triage-4821",
      "image": "chrome",
      "status": "running",
      "createdAt": "2026-09-26T08:14:03.512Z",
      "endedAt": null,
      "endedReason": null,
      "expiresAt": "2026-09-27T02:14:03.512Z",
      "lastseen": "2026-09-26T08:31:40.087Z",
      "url": "https://example.com",
      "country": "de",
      "connectUrl": "wss://api.guard.ch/web/brl-v-v7-q8m2r7k4d1/cdp?token=3f9c2a7d",
      "liveViewUrl": "https://guard.ch/en/viewer?id=brl-v-v7-q8m2r7k4d1",
      "startedByKind": "agent",
      "analysisEnabled": false,
      "startedBy": { "id": 4821, "email": "[email protected]", "firstname": "Ana", "lastname": "Meier" }
    }
  ]
}

Jede Sitzung hat diese Felder:

FeldBeschreibung
id, name, imageSitzungs-ID, Anzeigename und Image, wie beim Start zurückgegeben.
statusstarting oder running, solange die Sitzung läuft. Jeder andere Wert heisst, dass sie beendet ist.
createdAt, endedAtStart- und Endzeit im Format ISO 8601. endedAt ist null, solange die Sitzung läuft.
endedReasonWarum sie endete: stopped (von dir oder über die API beendet), timeout (maximale Laufzeit erreicht), disconnect (zu lange nichts verbunden), runtime (Laufzeitkontingent des Plans aufgebraucht), error oder lost (der Browser ist ausgefallen oder seine Maschine ist weg). Null, solange sie läuft.
expiresAtDer späteste Zeitpunkt, zu dem die Sitzung endet, festgelegt durch deinen Plan. Sie kann auch früher enden, siehe Limits.
lastseenWann ein verbundener Client die Sitzung zuletzt am Leben gehalten hat.
urlDie Startadresse aus der Anfrage oder null.
countryStandortcode oder null.
connectUrlCDP-WebSocket-URL, solange die Sitzung startet oder läuft, sonst null.
liveViewUrlDie Live-Ansicht in Guard.ch.
startedByKindagent für Sitzungen, die über die API oder MCP gestartet wurden, app für Untersuchungen, die jemand von Hand gestartet hat.
analysisEnabledOb die Live-Analyse gerade eingeschaltet ist.
startedByDas Konto, das die Sitzung gestartet hat: id, email, firstname und lastname.

Sitzung abrufen

GET https://api.guard.ch/v8/web/sessions/:id

Gibt eine Sitzung in data zurück, mit denselben Feldern wie die Liste. So findest du auch Untersuchungen, die du in Guard.ch von Hand gestartet hast, und ein Skript kann sich über ihre connectUrl damit verbinden. Eine unbekannte ID oder die Sitzung einer anderen Person ergibt denied.

Sitzung beenden

DELETE https://api.guard.ch/v8/web/sessions/:id

Beendet die Sitzung, entfernt ihren Browser und gibt den Platz sofort frei. Die Antwort ist ok, auch wenn die Sitzung schon beendet war. endedReason wird zu stopped, ausser die Sitzung endete vorher aus einem anderen Grund. Das beendet auch Untersuchungen, die du von Hand gestartet hast; beende also nur, was dein Skript gestartet hat.

curl -X DELETE https://api.guard.ch/v8/web/sessions/brl-v-v7-q8m2r7k4d1 \
  -H "Authorization: Bearer YOUR_API_KEY"

Datei herunterladen

GET https://api.guard.ch/v8/web/sessions/:id/downloads/:downloadId

Gibt die Bytes einer Datei zurück, die der Browser während der Sitzung heruntergeladen hat, mit Inhaltstyp und Dateiname. Die Download-ID (d1, d2, ...) liefert das MCP-Tool browser_downloads zusammen mit dieser URL.

Anders als alle anderen Endpunkte antwortet dieser mit echten HTTP-Statuscodes: 200 mit der Datei oder 404 mit Status denied, wenn die Datei nicht verfügbar ist. Die Datei wird mit den Cookies der Seite noch einmal angefordert; ein einmaliger oder abgelaufener Download-Link ergibt deshalb 404.

Nutzung und Kontingent

API-Nutzung

GET https://api.guard.ch/v8/web/usage

Summen über die Sitzungen, die dein Konto über die API oder MCP gestartet hat:

FeldBeschreibung
activeSessionsSitzungen, die gerade starten oder laufen.
sessionsLast30dIn den letzten 30 Tagen gestartete Sitzungen.
totalMinutesLast30dIhre gesamte Laufzeit in Minuten; laufende Sitzungen zählen bis jetzt.
planDein Plan: name, runningSessionLimit (gleichzeitige Sitzungen) und featureProgrammaticAccess.
poolsEin Eintrag pro Abo: subscription_id, plan_id, plan_name, running_session_limit und running_sessions_used. Ein Datenpaket, das nur Residential-Verkehr finanziert, zeigt das Limit 0.

Limits des Plans

GET https://api.guard.ch/v8/user/quota

Die Zähler, die dein Plan durchsetzt, über alle Sitzungen deines Kontos, egal ob von Hand oder über die API gestartet:

FeldBeschreibung
has_planOb ein aktiver Plan gilt.
running_session_limit, running_sessions_used, running_sessions_remainingGleichzeitige Sitzungen: erlaubt, belegt und frei.
cycle_start, cycle_session_limit, cycle_sessions_used, cycle_sessions_remainingBeginn des aktuellen Abrechnungszyklus und die darin gezählten Sitzungen. Null als Limit heisst unbegrenzt.
residential_cycle_mb_limit, residential_bytes_used_cycleDein Residential-Kontingent für den Zyklus in MB (null, wenn unbegrenzt oder ohne Plan) und der Verbrauch in Bytes.
poolsDieselben Zähler pro Abo, mit subscription_id, plan_id und plan_name.

Images und Standorte

GET https://api.guard.ch/v8/image

Der Katalog hinter den Feldern image, country und egress. Dafür brauchst du keinen Schlüssel.

curl https://api.guard.ch/v8/image
FeldBeschreibung
imagesBrowser-Images mit id, name, picture, enabled, requires_feature_restricted_images, supports_analysis und supports_programmatic. Nimm ein Image, das aktiv ist und programmatischen Zugriff unterstützt.
vpnLocationsLänder mit code, name, default (die Stadt, zu der ein reiner Ländercode aufgelöst wird) und cities mit je code und location. Als country funktionieren Länder- und Stadtcodes.
residentialAbdeckung des Residential-Ausgangs: configured und countries mit den erreichbaren Ländercodes (null: alle Länder).

Limits

  • Drei gleichzeitige Sitzungen pro Person. Das gilt für Guard Analyst und Guard Team, und Sitzungen, die du von Hand startest, zählen mit. Sind alle Plätze belegt, wird eine neue Sitzung abgelehnt und nicht eingereiht.
  • Sitzungen enden von selbst. Eine Sitzung endet etwa fünf Minuten, nachdem sich der letzte Client getrennt hat, spätestens aber bei expiresAt: 18 Stunden nach dem Start. Beende Sitzungen, die du nicht mehr brauchst, dann ist ihr Platz sofort wieder frei.
  • Das Starten ist begrenzt. Pro Minute, Stunde und Tag gelten Limits, je App-Schlüssel und je Konto. Eine Ablehnung enthält code: rate_limited und retryAfterMs.
  • Auch Anfragen sind begrenzt. Der API-Host nimmt von einer IP-Adresse etwa zwei Anfragen pro Sekunde an, kurze Spitzen darüber sind möglich. Darüber hinaus lautet die Antwort denied; warte kurz und versuch es noch einmal.
  • Aufrufe kosten nichts extra. Weder Anfragen noch Sitzungen werden nach Menge abgerechnet. Residential-Verkehr zählt gegen das Kontingent deines Plans im Abrechnungszyklus.

Sicherheit

  • Ein App-Schlüssel hat auf diesen Endpunkten dieselben Rechte wie dein Konto. Bewahr ihn in einem Secret Store auf und widerrufe ihn unter Apps, falls er je nach aussen gelangt.
  • Schick Schlüssel nur im Authorization-Header, nie in URLs, wo sie in Logs und im Browserverlauf landen.
  • Jede connectUrl hat ein eigenes Token und funktioniert nicht mehr, sobald die Sitzung endet. Logge oder teile sie nicht.
  • Zielseiten laden in unserer Infrastruktur, nie auf dem Rechner, der die API aufruft.

Fragen zur API?

Unklarheiten bei einem Endpunkt, oder fehlt dir etwas für deine Integration? Schreib uns.

Guard.ch 30 Tage testen.

Du hinterlegst eine Karte. Belastet wird sie erst nach der Testphase.

30 Tage gratis testen