Session-Lebenszyklus: Status, Fristen, Abrechnung
Wie eine Session von pending zu released wandert, wann die Abrechnungsuhr startet und warum Frist und Idle-Timeout zwei verschiedene Zahlen sind.
Zuletzt aktualisiert:
Der Lebenszyklus im Überblick
Was eine Session ist
Eine Browserberg-Session ist ein echter Chromium-Browser in einem eigenen isolierten, gehärteten Container — für dich gestartet, beim Ende der Session abgerissen, nie mit fremder Arbeit geteilt. Der Container ist eine Sicherheitsgrenze: Alles, was die geladenen Seiten anfassen könnten, stirbt mit ihm.
Der Session-Datensatz führt einen Status: pending, ready, releasing, released oder failed. Dieses Enum ist offen — ein Wert, den du nicht kennst, gehört in deinen Default-Zweig, nicht in einen Fehlerpfad.
Die Abrechnung beginnt bei readyAt, nie bei der Annahme: Wartezeit und Container-Start kosten dich nichts. Ein Warm-Start übernimmt einen bereits laufenden Browser und ist meist innerhalb einer Sekunde bereit; ein Kalt-Start baut den Container erst und braucht mehrere Sekunden. Das Feld warmStart im Datensatz verrät dir, welchen du bekommen hast.
Optionen beim Erstellen
Jedes Feld von `POST /v1/sessions` ist optional — `{}` ist ein gültiger Body. Requests sind strikt: Ein vertipptes Feld wird mit 400 abgelehnt, nie stillschweigend ignoriert.
| Name | Typ | Beschreibung |
|---|---|---|
shape
|
object |
Viewport, Locale, Zeitzone, Headless-Flag und allowlistete zusätzliche Chromium-Argumente. Für die Lebensdauer der Session fixiert.
Standard: 1440×900, de-DE, Europe/Berlin, headless
|
profileId
|
string | Hängt ein persistentes Profil an. Eine noch nicht existierende id legt das Profil an, geprüft gegen das Kontingent deines Tarifs. |
credentialIds
|
string[] | Tresor-Zugangsdaten, die diese Session freigeben darf — jede nur auf der Site, für die sie hinterlegt wurde. |
egress
|
object | Listen allowDomains und denyDomains, die einschränken, wohin sich der Browser verbinden darf. |
recording
|
object |
Session-Aufzeichnung. Standardmäßig an, 24 Stunden aufbewahrt.
Standard: aktiv, 24 h Aufbewahrung
|
ttlSeconds
|
integer |
Anfängliche Lebensdauer, 30 bis 259200 Sekunden. Per Keep-alive verlängerbar, bis maxLifetimeAt erreicht ist.
Standard: 900
|
keepAlive.idleTimeoutSeconds
|
integer | Gibt die Session frei, wenn so lange keine Aktivität stattfand — unabhängig von jeder Frist. |
keepAlive.checkpointSeconds
|
integer | Intervall, in dem der Zustand der Session gesichert wird; checkpointedAt im Datensatz zeigt den letzten Stand. |
poolId
|
string | Beansprucht einen Browser aus einem reservierten Pool statt eines Kalt-Starts. Die Shape muss zum Pool passen; eine Abweichung wird abgelehnt. |
metadata
|
object | Freie Schlüssel-Wert-Daten, die im Session-Datensatz zurückkommen. |
Fristen sind keine Idle-Timeouts
Eine Frist und ein Idle-Timeout sind verschiedene Zahlen, und ein Wert kann nicht beide Rollen spielen. keepAlive.idleTimeoutSeconds räumt eine Session ab, die niemand benutzt — es beobachtet Aktivität, nicht die Uhr. expiresAt und maxLifetimeAt begrenzen auch eine beschäftigte Session: Ersteres ist die aktuelle Frist, die ein Keep-alive verschieben kann, Letzteres die harte Obergrenze, die dein Tarif bei der Erstellung setzt — und die kein Keep-alive jemals bewegt.
Endet eine Session, sagt shutdownReason, warum. Auch das ist ein offenes Enum — 1.2.0 hat ihm idle_timeout hinzugefügt — also leite nie gesehene Werte durch einen Default-Zweig, statt erschöpfend zu matchen.
Eine Session verlängern
Ein Keep-alive bittet um mehr Zeit, und die Antwort meldet, was tatsächlich gewährt wurde. `clampedToMaxLifetime` heißt: Plane eine frische Session. `clampedToPlanLimit` heißt: Diese eine Verlängerung wurde gekürzt — frag später erneut.
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": 120}' \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["session"]["id"])')
# Ask for another hour. The response says what actually happened: an extension
# may be trimmed to the plan's ceiling, and maxLifetimeAt never moves.
curl -s -X POST "$BASE/v1/sessions/$ID/keepalive" -H "$AUTH" -H "$JSON" \
-d '{"ttlSeconds": 3600}' \
| python3 -c 'import json,sys; r = json.load(sys.stdin); print(json.dumps({
"expiresAt": r["session"]["expiresAt"],
"maxLifetimeAt": r["session"]["maxLifetimeAt"],
"clampedToMaxLifetime": r["clampedToMaxLifetime"],
"clampedToPlanLimit": r["clampedToPlanLimit"]}, indent=2))'
curl -s -X DELETE "$BASE/v1/sessions/$ID" -H "$AUTH" > /dev/null
{
"expiresAt": "2026-01-01T00:00:00.000Z",
"maxLifetimeAt": "2026-01-01T00:00:00.000Z",
"clampedToMaxLifetime": false,
"clampedToPlanLimit": false
}
Profile tragen Zustand weiter
Ein Profil trägt Browser-Zustand — Cookies, Storage, eingeloggte Sitzungen — von einer Session zur nächsten. Gib beim Erstellen eine profileId an: Der Zustand wird beim Teardown erfasst, mit dem Schlüssel deines Tenants verschlüsselt und in die nächste Session mit derselben id zurückgespielt. Die Anleitung zu persistenten Profilen zeigt den kompletten Rundweg.