Glanceshot
Entwicklerdokumentation

API Dokumentation

Basis-URL: https://glanceshot.com/v1. Alle Endpunkte verwenden Standard-HTTP. Parameter können im Query-String (GET) oder im JSON-Body (POST) übergeben werden.

Schnellstart

  1. Registrieren Sie sich kostenlos und erstellen Sie in der Konsole unter „API Key“ einen API Key.
  2. Übergeben Sie den API Key im Request-Header X-Access-Key und rufen Sie den Screenshot-Endpunkt auf:
curl "https://glanceshot.com/v1/screenshot?url=https://example.com&full_page=true" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -o screenshot.png

Authentifizierung

Jede Anfrage benötigt einen API Key. Sie können ihn auf eine der folgenden Arten übergeben:

  • Request-Header X-Access-Key: gls_… (empfohlen für serverseitige Aufrufe)
  • Query-Parameter access_key=gls_… (nur für serverseitige Aufrufe, nicht in Webseiten einbetten)
  • Signierte URL (zum Einbetten in Webseiten, ohne API Key oder secret offenzulegen)

Der API Key wird nur bei der Erstellung einmal im Klartext angezeigt. Bewahren Sie ihn sicher auf. Bei einer Offenlegung können Sie ihn in der Konsole deaktivieren.

Screenshot-Endpunkt

GET/v1/screenshot
POST/v1/screenshot

Screenshot-spezifische Parameter:

ParameterTypStandardBeschreibung
formatenumpngpng, jpeg oder webp.
device_scale_factornumber1Skalierungsfaktor 1–3. Mit 2 erhalten Sie Retina-Schärfe bei etwa 4-facher Dateigröße.
qualityinteger80JPEG / WebP-Qualität, 1–100.
full_pagebooleanfalseNimmt die gesamte Seite auf. Scrollt Bildschirm für Bildschirm, um Lazy Loading auszulösen. Maximale Höhe: 20,000 Pixel.
selectorstring—Nimmt nur das erste Element auf, das diesem CSS-Selektor entspricht. Nicht mit full_page kombinierbar.

Gemeinsame Parameter für Screenshots und PDFs:

ParameterTypStandardBeschreibung
urlstring—URL der aufzunehmenden Webseite, http oder https. Geben Sie entweder diesen Parameter oder html an. Das #-Fragment der URL bleibt erhalten. So können Sie Seiten von Single-Page-Anwendungen mit Hash-Routing (z. B. https://app.com/#/report/1) direkt aufnehmen.
htmlstring—HTML direkt übergeben (maximal 2 MB), nur per POST.
viewport_widthinteger1280Viewport-Breite, 320–3840. Bei Werten unter 768 wird die Seite wie auf einem Mobilgerät gerendert.
viewport_heightinteger800Viewport-Höhe, 200–3840.
wait_untilenumnetworkidleWartestrategie: domcontentloaded (am schnellsten, für statische Seiten), load, networkidle (verfolgt alle Anfragen ab dem Öffnen der Seite; nach dem Laden wird der Screenshot erstellt, sobald 500 Millisekunden lang keine Anfrage mehr läuft; wartet höchstens weitere 8 Sekunden, geeignet für Single-Page-Anwendungen).
wait_for_selectorstring—Wartet nach dem Laden der Seite bis zu 10 Sekunden, bis ein Element erscheint und sichtbar ist, das diesem CSS-Selektor entspricht. Andernfalls wird selector_not_found zurückgegeben (ohne Berechnung). Geeignet für Single-Page-Anwendungen, die Inhalte per Timer oder Animation verzögert rendern, ohne Netzwerkanfragen auszulösen, z. B. .chart-ready.
delayinteger0Zusätzliche Wartezeit in Millisekunden nach Abschluss der Wartestrategie, 0–10000. Für Animationen oder Lazy-Loading-Komponenten.
block_adsbooleantrueBlockiert Anfragen an Werbe- und Tracking-Domains und blendet Werbeflächen auf der Seite aus.
block_cookie_bannersbooleantrueBlendet Cookie-Einwilligungsdialoge aus.
dark_modebooleanfalseSimuliert prefers-color-scheme: dark.
hide_selectorsstring—Liste von CSS-Selektoren für auszublendende Elemente, z. B. .ad,#popup.
cachebooleantrueLegt fest, ob der Cache geprüft wird. Mit false wird die Seite neu gerendert; das Ergebnis wird weiterhin im Cache gespeichert.
cache_ttlinteger86400Cache-Gültigkeitsdauer in Sekunden, 60–2592000.
response_typeenumbinarybinary gibt die Datei direkt zurück; json gibt die Datei-URL und Metadaten zurück.
proxystring—Optional: Greifen Sie über einen selbst gebuchten Proxy auf die Zielseite zu, etwa aus einem bestimmten Land oder einer bestimmten Region. Die Proxy-Kosten tragen Sie selbst. Unterstützt werden socks5:// und http://, auch mit Benutzername und Passwort, im Format socks5://user:pass@203.0.113.10:1080. Nur im POST-Anfragetext zulässig, nicht für GET-Anfragen, signierte URLs oder Batch-Aufträge. Anfragen mit Proxy werden separat zwischengespeichert. Ist der Proxy nicht erreichbar, schlägt die Authentifizierung fehl oder kann der Proxy die Zielseite nicht erreichen, wird proxy_failed zurückgegeben. Die Anfrage wird nicht berechnet.
cookiesstring | object[]—Cookies für die Zielwebsite, entweder als einzelne Zeile wie sid=abc; theme=dark oder als Array wie [{"name":"sid","value":"abc"}] (optional mit domain und path). Sie werden nur an die Zielwebsite gesendet, nicht an Drittanbieter auf der Seite.
headersobject—Zusätzliche Anfrage-Header, z. B. Authorization: Bearer …. Sie werden nur an die Zielwebsite gesendet. Vom Browser verwaltete Header (Host, Cookie, User-Agent usw.) können nicht gesetzt werden.
local_storageobject—Daten, die in den localStorage der Origin der Ziel-URL geschrieben werden sollen. Schlüssel und Werte müssen Zeichenketten sein.
session_storageobject—Wie local_storage, schreibt die Daten jedoch in den sessionStorage.
login_profilestring—ID des mit der Browser-Erweiterung gespeicherten Anmeldeprofils (lp_8f2c…). Einfacher als die direkte Übergabe von cookies und auch für Batch-Aufträge geeignet (in den Aufträgen werden keine Zugangsdaten gespeichert).

Single-Page-Anwendungen aufnehmen (React, Vue usw.):Die Seite führt JavaScript in einem echten Browser aus, bevor der Screenshot erstellt wird. Die Standardstrategie networkidle wartet, bis die Seite ihre Daten geladen hat. Werden Inhalte erst danach per Timer oder Animation gerendert, geben Sie mit wait_for_selector ein Element an, das signalisiert, dass der Inhalt bereit ist. Gibt es kein geeignetes Element, können Sie mit delay zusätzliche Wartezeit einplanen.

PDF-Endpunkt

GET/v1/pdf
POST/v1/pdf

Jedes PDF verbraucht 2 Kontingenteinheiten. Vor dem Drucken wird die Seite einmal durchgescrollt, um Lazy-Loading-Inhalte zu laden. Zusätzlich zu den gemeinsamen Parametern werden unterstützt:

ParameterTypStandardBeschreibung
paperenuma4Papierformat: a4 oder letter. Enthält die Seite eine eigene @page-Regel, hat diese Vorrang.
print_backgroundbooleantrueDruckt Hintergrundfarben und -bilder.
pdf_mediaenumprintprint verwendet Druckstile; screen verwendet Bildschirmstile (wie im Browser angezeigt).
HTML in PDF umwandeln
curl -X POST "https://glanceshot.com/v1/pdf" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>Quartalsbericht</h1><p>Inhalt …</p>", "paper": "a4"}' \
  -o report.pdf

Antworten

Standardmäßig (response_type=binary) wird die Datei direkt zurückgegeben, mit dem passenden Format in Content-Type. Response-Header:

  • X-Request-Id: ID dieser Anfrage; bitte bei der Fehleranalyse angeben
  • X-Glanceshot-Cache: HIT oder MISS
  • X-Glanceshot-Truncated: true: Die vollständige Seite wurde bei 20,000 Pixeln Höhe abgeschnitten
  • X-Glanceshot-Format-Changed: webp: PNG über 5 MB wurde automatisch in WebP umgewandelt (keine Umwandlung bei expliziter Angabe von format=png)

Mit response_type=json werden die Datei-URL und Metadaten zurückgegeben:

JSON-Antwort
curl -X POST "https://glanceshot.com/v1/screenshot" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "response_type": "json"}'

# Rückgabe
{
  "url": "https://glanceshot.com/i/3f/3f9c….png",
  "cache_hit": false,
  "duration_ms": 1284,
  "format": "png",
  "width": 1280,
  "height": 800,
  "request_id": "req_01j…"
}

Signierte URLs

Sie möchten eine Screenshot-URL direkt in <img src> einbetten, ohne Ihren API Key offenzulegen? Eine signierte URL enthält keinen API Key, sondern nur die öffentliche key_id. Die Signatur berechnen Sie auf Ihrem eigenen Server mit dem zugehörigen secret. Key ID und secret finden Sie in der Konsole auf der Seite „API Key“:

Signaturregeln
canonical = Alle Parameter außer signature lexikografisch nach Parameternamen sortieren,
            jeden Eintrag als k=urlencode(v) kodieren (RFC 3986, Leerzeichen als %20) und mit & verbinden
signature = hex(HMAC-SHA256(secret, canonical))

Eine gültige Signatur authentifiziert die Anfrage. Anfragen mit fehlender oder ungültiger Signatur werden abgelehnt. Jede Parameteränderung (etwa an url) macht die Signatur ungültig. Der optionale Parameter expires (Unix-Zeit in Sekunden) wird in die Signatur einbezogen; nach Ablauf wird signature_expired zurückgegeben. Um den Cache zu aktualisieren, ändern Sie einen bedeutungslosen Parameter (z. B. v=2) und signieren die URL erneut. Signierte URLs unterstützen nur GET-Aufrufe der Screenshot- und PDF-Endpunkte und dürfen keine Proxy-Parameter enthalten.

key_id ist öffentlich und reicht allein nicht für API-Aufrufe aus. Fügen Sie den API Key (access_key) nicht in signierte URLs ein, sonst wird direkt invalid_params zurückgegeben. Falls Sie Ihren API Key bereits in eine Webseite eingebettet haben, deaktivieren Sie ihn in der Konsole und erstellen Sie einen neuen.

import crypto from "node:crypto";

// RFC-3986-Kodierung (Leerzeichen als %20), muss den serverseitigen Regeln entsprechen
const enc = (v) =>
  encodeURIComponent(v).replace(/[!'()*]/g, (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase());

function signedUrl(params, keyId, secret) {
  const all = { ...params, key_id: keyId };
  const canonical = Object.keys(all).sort().map((k) => `${k}=${enc(String(all[k]))}`).join("&");
  const signature = crypto.createHmac("sha256", secret).update(canonical).digest("hex");
  return `https://glanceshot.com/v1/screenshot?${canonical}&signature=${signature}`;
}

const src = signedUrl({ url: "https://example.com", viewport_width: 1200 }, KEY_ID, SECRET);
// <img src={src} alt="Webseitenvorschau" />

Proxy verwenden

Wenn Sie eine Webseite aus einem bestimmten Land oder einer bestimmten Region aufrufen möchten (z. B. um die lokale Sprache, Inhalte und Preise zu sehen), können Sie einen selbst gebuchten Proxy in der Anfrage angeben. Die Proxy-Kosten tragen Sie selbst. Die Seite sowie alle Bilder, Skripte und API-Anfragen der Seite werden über diesen Proxy geladen. Unterstützt werden socks5:// und http://, auch mit Benutzername und Passwort.

curl -X POST "https://glanceshot.com/v1/screenshot" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "proxy": "socks5://user:pass@203.0.113.10:1080"}' \
  -o screenshot.png
  • proxy darf nur im Body einer POST-Anfrage stehen. GET-Anfragen, signierte URLs und Batch-Aufträge unterstützen diesen Parameter nicht, damit die Proxy-Zugangsdaten nicht in URLs, im Browserverlauf oder auf Webseiten erscheinen.
  • Enthalten Benutzername oder Passwort Sonderzeichen wie @ oder :, müssen diese zuerst URL-codiert werden (z. B. @ als %40).
  • Anfragen mit Proxy werden separat zwischengespeichert. Die Ergebnisse werden weder für Anfragen ohne Proxy noch für Anfragen mit anderen Proxys wiederverwendet.
  • Ist der Proxy nicht erreichbar, schlägt die Authentifizierung fehl oder lässt sich die Zielwebsite nicht aufrufen, wird proxy_failed zurückgegeben. Die Anfrage wird nicht berechnet. message enthält die genaue Ursache.
  • Der Proxy muss eine öffentlich erreichbare Adresse haben. Für die Ziel-URL gelten dieselben Einschränkungen wie ohne Proxy: Interne Netzwerkadressen sind nicht zulässig.
  • Beachten Sie beim Zugriff auf Websites über einen Proxy die Nutzungsbedingungen der Zielwebsite und die örtlichen Gesetze.

Seiten nach der Anmeldung erfassen

Um Seiten zu erfassen, die nur nach einer Anmeldung sichtbar sind, können Sie den Anmeldestatus Ihres eigenen Kontos übergeben. Dafür gibt es zwei Möglichkeiten: Übergeben Sie cookies, headers, local_storage und session_storage direkt in der Anfrage, oder speichern Sie den Anmeldestatus mit der Glanceshot-Browser-Erweiterung als „Anmeldeprofil“ und übergeben Sie in der Anfrage nur login_profile.

curl -X POST "https://glanceshot.com/v1/screenshot"   -H "X-Access-Key: $GLANCESHOT_KEY"   -H "Content-Type: application/json"   -d '{
    "url": "https://app.example.com/dashboard",
    "cookies": "sid=YOUR_SESSION; theme=dark",
    "local_storage": {"token": "YOUR_TOKEN"}
  }' -o screenshot.png
  • Die Erweiterung kann Zugangsdaten auslesen, auf die Seitenskripte keinen Zugriff haben (einschließlich HttpOnly-Cookies), sowie localStorage und IndexedDB. Sie eignet sich für die meisten Websites. Installieren und verbinden Sie die Erweiterung auf der Seite „Anmeldeprofile“ in der Konsole.
  • Der Anmeldestatus kann nur im Body einer POST-Anfrage übergeben werden (GET und signierte URLs werden abgelehnt). Er wird weder in Logs noch im Aufrufverlauf gespeichert. Anfragen mit Anmeldestatus werden nach diesem Status getrennt zwischengespeichert; der Cache wird nicht mit anderen Nutzern geteilt.
  • Wenn ein Anmeldestatus übergeben wurde, die Seite jedoch zur Anmeldeseite zurückleitet, wird login_expired zurückgegeben und die Anfrage nicht berechnet. Der Anmeldestatus ist dann abgelaufen; synchronisieren Sie ihn erneut mit der Erweiterung.
  • Bei Websites, deren Sitzung an ein Gerät oder eine IP gebunden ist und deren Anmeldung sich daher nicht in der Cloud wiederherstellen lässt (z. B. Onlinebanking), können Sie mit „Aktuelle Seite erfassen“ in der Erweiterung einen Screenshot in Ihrem eigenen Browser erstellen und anschließend hochladen.

Cache

Anfragen mit identischen Parametern werden aus dem Cache bedient. Weggelassene Parameter gelten als identisch mit explizit angegebenen Standardwerten; Authentifizierungs- und Cache-Parameter werden nicht verglichen. Bei einem Cache-Treffer liefert der Binärmodus eine 302-Weiterleitung zur Datei-URL mit Cache-Control. Der Browser folgt der Weiterleitung automatisch und speichert die Datei im Cache. Im JSON-Modus wird cache_hit: true zurückgegeben.

Cache-Treffer werden nicht berechnet.Gleichzeitige Anfragen mit identischen Parametern lösen nur einen Rendervorgang aus.

Limits und Abrechnung

  • Nur erfolgreiche Anfragen (2xx) ohne Cache-Treffer werden berechnet: 1 Kontingenteinheit pro Screenshot, 2 pro PDF.
  • Bei Zeitüberschreitungen, Rendering-Fehlern, Fehlern oder Zugriffssperren der Zielwebsite, ungültigen Parametern und fehlgeschlagener Authentifizierung wird kein Kontingent abgezogen.
  • Das Kontingent wird zu Beginn jedes Kalendermonats (UTC) zurückgesetzt. Der kostenlose Tarif enthält 100 Kontingenteinheiten pro Monat. Nach Verbrauch wird quota_exceeded zurückgegeben.
  • Bei Überschreitung der Anfragen pro Sekunde oder der gleichzeitigen Anfragen wird 429 zurückgegeben. Der Response-Header Retry-After enthält die empfohlene Wartezeit in Sekunden.
  • Maximale Renderdauer: 30 Sekunden; maximales Downloadvolumen pro Seite: 50 MB; maximale Ausgabedateigröße: 50 MB.

Die genauen Limits der einzelnen Tarife finden Sie unter Preise.

Fehlercodes

Fehlerantworten werden immer als JSON zurückgegeben:

Fehlerformat
{
  "error": {
    "code": "render_failed",
    "message": "target responded with an error status",
    "upstream_status": 404,
    "request_id": "req_01j…"
  }
}
HTTPcodeBedeutungKostenpflichtig
400invalid_paramsParameter fehlt oder liegt außerhalb des zulässigen Bereichs; message nennt den betroffenen ParameterNein
400html_too_largehtml überschreitet 2 MBNein
401unauthorizedAPI Key fehlt, ist ungültig oder wurde deaktiviertNein
401signature_invalidSignatur stimmt nicht überein (Parameter geändert oder falsches Secret)Nein
401signature_expiredDie signierte URL ist seit dem in expires angegebenen Zeitpunkt abgelaufenNein
403url_blockedZugriff auf die Zieladresse nicht erlaubt (z. B. interne Netzwerkadresse oder localhost)Nein
408render_timeoutRenderdauer überschreitet 30 SekundenNein
422render_failedZielwebsite gibt 4xx/5xx zurück, DNS-Auflösung fehlgeschlagen oder Zertifikatsfehler; enthält upstream_statusNein
422selector_not_foundKein Element für selector gefunden oder Zeitüberschreitung bei wait_for_selectorNein
422too_many_redirectsMehr als 5 WeiterleitungenNein
422site_blockedDie Zielwebsite zeigt statt der eigentlichen Inhalte eine Bot-Prüfung, ein CAPTCHA, eine Anmeldeseite oder eine Seite mit verweigertem Zugriff an; wird nicht berechnetNein
422login_expiredEin Anmeldestatus wurde übergeben, die Zielwebsite zeigt jedoch weiterhin die Anmeldeseite an. Der Anmeldestatus ist abgelaufen.Nein
422proxy_failedDer angegebene Proxy ist nicht erreichbar, die Authentifizierung ist fehlgeschlagen oder der Proxy kann die Zielseite nicht erreichen. message nennt den genauen Grund. Die Anfrage wird nicht berechnet.Nein
429rate_limitedLimit für Anfragen pro Sekunde überschritten; gemäß Retry-After erneut versuchenNein
429concurrency_exceededLimit für gleichzeitige Anfragen überschrittenNein
429quota_exceededMonatskontingent aufgebraucht (kostenloser Tarif)Nein
429too_many_batchesMehr als 5 noch nicht abgeschlossene Stapelaufträge gleichzeitigNein
500internalServerfehler; kontaktieren Sie uns und geben Sie request_id anNein

Asynchrone Stapelverarbeitung

POST/v1/batch
GET/v1/batch/{id}

Übermitteln Sie 1–100 URLs auf einmal. Der Endpunkt gibt sofort eine Auftrags-ID zurück (HTTP 202); die Screenshots werden im Hintergrund nacheinander erstellt. Ideal für mehrere Screenshots, ohne die Verbindung offen halten zu müssen. Sie können den Status regelmäßig abfragen oder webhook_url angeben, um nach Abschluss aller Aufgaben benachrichtigt zu werden. Die Authentifizierung entspricht der synchronen API (nur per Request-Header oder Parameter access_key, keine signierten URLs).

ParameterTypStandardBeschreibung
typeenumscreenshotscreenshot (Screenshot) oder pdf.
urlsstring[]—Zu verarbeitende URLs, 1–100. Ist eine davon ungültig, wird die gesamte Anfrage mit 400 abgelehnt. message gibt die Position der ungültigen URL an.
optionsobject{}Parameter, die für alle URLs gelten. Sie entsprechen den Parametern der synchronen API (z. B. full_page, format, viewport_width, cache_ttl). url, html, response_type und proxy sind nicht zulässig.
webhook_urlstring—Optional. URL für die Benachrichtigung nach Abschluss aller Aufgaben, siehe „Webhook bei Abschluss“.
Stapelauftrag erstellen
curl -X POST "https://glanceshot.com/v1/batch" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "screenshot",
    "urls": ["https://example.com", "https://example.org"],
    "options": { "full_page": true, "format": "webp" },
    "webhook_url": "https://your-app.com/hooks/glanceshot"
  }'

# Rückgabe: 202
{
  "id": "bat_01j…",
  "type": "screenshot",
  "status": "queued",
  "total": 2, "succeeded": 0, "failed": 0,
  "created_at": "2026-10-18T09:30:00Z", "completed_at": null,
  "webhook": { "url": "https://your-app.com/hooks/glanceshot", "status": "none", "attempts": 0 },
  "items": [
    { "index": 0, "url": "https://example.com", "status": "pending", "result": null, "error": null },
    { "index": 1, "url": "https://example.org", "status": "pending", "result": null, "error": null }
  ]
}

Fortschritt abfragen: Der Auftragsstatus status durchläuft queued (in der Warteschlange), running (in Bearbeitung) und completed (alles abgeschlossen, unabhängig von Erfolg oder Fehler). Jede URL hat den Status pending, running, succeeded oder failed. Bei Erfolg enthält result die Datei-URL, bei einem Fehler enthält error den Fehlercode (identisch mit den synchronen Endpunkten).

Stapelauftrag abfragen
curl "https://glanceshot.com/v1/batch/bat_01j…" -H "X-Access-Key: $GLANCESHOT_KEY"

{
  "id": "bat_01j…",
  "status": "completed",
  "total": 2, "succeeded": 1, "failed": 1,
  "completed_at": "2026-10-18T09:30:12Z",
  "items": [
    {
      "index": 0, "url": "https://example.com", "status": "succeeded", "duration_ms": 1830,
      "result": { "url": "https://glanceshot.com/i/3f/3f9c….webp", "mime": "image/webp", "width": 1280, "height": 2410, "cache_hit": false },
      "error": null
    },
    {
      "index": 1, "url": "https://example.org", "status": "failed", "duration_ms": 640,
      "result": null,
      "error": { "code": "render_failed", "message": "target responded with an error status" }
    }
  ]
}
  • Es gelten dieselben Abrechnungsregeln wie bei den synchronen Endpunkten: pro erfolgreich verarbeiteter URL 1 Kontingenteinheit für einen Screenshot oder 2 für ein PDF. Cache-Treffer und Fehler verbrauchen kein Kontingent.
  • Ist das Kontingent beim Einreichen bereits aufgebraucht, wird sofort quota_exceeded zurückgegeben. Wird es während der Verarbeitung aufgebraucht, schlagen die verbleibenden URLs mit quota_exceeded fehl.
  • Pro Konto sind höchstens 5 noch nicht abgeschlossene Stapelaufträge gleichzeitig erlaubt. Bei Überschreitung wird too_many_batches zurückgegeben.
  • Die Gültigkeitsdauer der Ergebnisdateien wird durch options.cache_ttl bestimmt (standardmäßig 1 Tag). Laden Sie die Dateien rechtzeitig herunter und speichern Sie sie.
  • In Abfrageergebnissen und Webhooks wird webhook.url nur bis zum Pfad angezeigt, ohne Query-String.

Webhook bei Abschluss

Wenn Sie webhook_url angeben, senden wir nach Abschluss des gesamten Auftrags eine POST-Anfrage an diese URL. Der Request-Body ist JSON: { "event": "batch.completed", "batch": { … } }. Dabei entspricht batch genau der Antwort des Abfrage-Endpunkts. Request-Header:

  • X-Glanceshot-Signature: t=1760779812,v1=5d3f…: t ist der Sendezeitpunkt (Unix-Zeit in Sekunden), v1 die Signatur
  • X-Glanceshot-Event: batch.completed, X-Glanceshot-Delivery-Attempt: 1 (Nummer des Zustellversuchs)
Signaturregeln
v1 = hex(HMAC-SHA256(secret, t + "." + Unveränderter Request-Body))
secret ist das Signatur-Secret des API Key, mit dem der Auftrag eingereicht wurde (in der Konsole auf der Seite „API Key“ einsehbar).
  • Antworten Sie innerhalb von 10 Sekunden mit 2xx, andernfalls gilt die Zustellung als fehlgeschlagen. Bei einem Fehler wird die Zustellung nach 10 Sekunden, 1 Minute und 5 Minuten jeweils einmal wiederholt (insgesamt maximal 4 Versuche).
  • In seltenen Fällen können Sie für denselben Auftrag mehrere Benachrichtigungen erhalten. Erkennen Sie Duplikate anhand von batch.id.
  • Berechnen Sie die Signatur anhand der empfangenen, unveränderten Bytes. Prüfen Sie außerdem, dass t höchstens wenige Minuten von der aktuellen Zeit abweicht, um Replay-Angriffe zu verhindern.
  • Die Callback-URL muss eine öffentlich erreichbare http(s)-Adresse sein und darf nicht auf ein internes Netzwerk verweisen.
import crypto from "node:crypto";

// rawBody muss die empfangenen Originalbytes enthalten. Nicht zuerst mit JSON.parse parsen und anschließend erneut serialisieren.
function verifyGlanceshotWebhook(rawBody, header, secret, toleranceSec = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false; // Schutz vor Replay-Angriffen
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  const got = Buffer.from(parts.v1 ?? "");
  return got.length === expected.length && crypto.timingSafeEqual(Buffer.from(expected), got);
}

// verifyGlanceshotWebhook(req.rawBody, req.headers["x-glanceshot-signature"], GLANCESHOT_SECRET)

Nutzung abfragen

GET/v1/usage
shell
curl "https://glanceshot.com/v1/usage" -H "X-Access-Key: $GLANCESHOT_KEY"

{ "month": "202610", "used": 37, "limit": 100, "remaining": 63, "overage": 0, "resets_at": "2026-11-01T00:00:00Z", ... }

Statusprüfung

GET/v1/health

Keine Authentifizierung erforderlich. Gibt den Knotenstatus und den Status des Browser-Pools zurück (gesamt, belegt, frei).