API Documentazione
URL di base: https://glanceshot.com/v1. Tutti gli endpoint usano HTTP standard. I parametri possono essere passati nella query string (GET) o nel corpo JSON (POST).
Guida rapida
- Registrati gratis e crea un'API Key nella pagina «API Key» della console.
- Inserisci l'API Key nell'header
X-Access-Keye chiama l'endpoint screenshot:
curl "https://glanceshot.com/v1/screenshot?url=https://example.com&full_page=true" \
-H "X-Access-Key: $GLANCESHOT_KEY" \
-o screenshot.pngAutenticazione
Ogni richiesta richiede un'API Key, che puoi passare in uno dei seguenti modi:
- Header
X-Access-Key: gls_…(consigliato per le chiamate lato server) - Parametro di query
access_key=gls_…(solo per chiamate lato server, non inserirlo nelle pagine web) - URL firmato (per inserire l'indirizzo in una pagina web senza esporre né l'API Key né il secret)
L'API Key viene mostrata in chiaro una sola volta, al momento della creazione. Conservala al sicuro. Se viene compromessa, puoi disattivarla dalla console.
Endpoint screenshot
/v1/screenshot/v1/screenshotParametri specifici per gli screenshot:
| Parametro | Tipo | Valore predefinito | Descrizione |
|---|---|---|---|
| format | enum | png | png, jpeg o webp. |
| device_scale_factor | number | 1 | Fattore di scala, 1–3. Impostando 2 si ottiene una risoluzione Retina, con dimensioni del file circa 4 volte maggiori. |
| quality | integer | 80 | Qualità JPEG / WebP, 1–100. |
| full_page | boolean | false | Acquisisce l'intera pagina. Scorre una schermata alla volta per attivare il caricamento differito, fino a un'altezza massima di 20,000 pixel. |
| selector | string | — | Acquisisce solo il primo elemento corrispondente a questo selettore CSS. Non può essere usato insieme a full_page. |
Parametri comuni a screenshot e PDF:
| Parametro | Tipo | Valore predefinito | Descrizione |
|---|---|---|---|
| url | string | — | URL della pagina da acquisire, http o https. Usa questo parametro oppure html. Il frammento # dell'URL viene mantenuto: puoi acquisire direttamente la pagina desiderata nelle applicazioni a pagina singola con routing hash, come https://app.com/#/report/1. |
| html | string | — | HTML da inviare direttamente (massimo 2 MB). Supportato solo con POST. |
| viewport_width | integer | 1280 | Larghezza del viewport, 320–3840. Con valori inferiori a 768, la pagina viene renderizzata come su un dispositivo mobile. |
| viewport_height | integer | 800 | Altezza del viewport, 200–3840. |
| wait_until | enum | networkidle | Strategia di attesa: domcontentloaded (la più rapida, ideale per pagine statiche), load, networkidle (monitora tutte le richieste dall'apertura della pagina e, dopo il caricamento, acquisisce lo screenshot quando non ci sono richieste in corso per 500 millisecondi consecutivi; attende al massimo altri 8 secondi, ideale per applicazioni a pagina singola). |
| wait_for_selector | string | — | Dopo il caricamento della pagina, attende fino a 10 secondi che un elemento corrispondente a questo selettore CSS sia presente e visibile prima di acquisire lo screenshot. Se non compare, restituisce selector_not_found (senza addebito). Ideale per applicazioni a pagina singola che renderizzano contenuti in ritardo tramite timer o animazioni, anziché richieste di rete, come .chart-ready. |
| delay | integer | 0 | Ritardo aggiuntivo in millisecondi dopo l'attesa, 0–10000. Utile per animazioni o componenti con caricamento differito. |
| block_ads | boolean | true | Blocca le richieste ai domini pubblicitari e di tracciamento e nasconde gli spazi pubblicitari nella pagina. |
| block_cookie_banners | boolean | true | Nasconde i banner di consenso ai cookie. |
| dark_mode | boolean | false | Simula prefers-color-scheme: dark. |
| hide_selectors | string | — | Elenco di selettori CSS degli elementi da nascondere, ad esempio .ad,#popup. |
| cache | boolean | true | Indica se cercare nella cache. Con false forza un nuovo rendering; il risultato viene comunque salvato nella cache. |
| cache_ttl | integer | 86400 | Durata della cache in secondi, 60–2592000. |
| response_type | enum | binary | binary restituisce direttamente il file; json restituisce l'URL del file e i metadati. |
| proxy | string | — | Facoltativo. Usa un proxy acquistato da te per accedere alla pagina di destinazione (i costi del proxy sono a tuo carico), ad esempio per accedere da un paese o una regione specifici. Supporta socks5:// e http://, anche con nome utente e password, nel formato socks5://user:pass@203.0.113.10:1080. Può essere specificato solo nel corpo di una richiesta POST, non nelle richieste GET, negli URL firmati o nelle operazioni in batch. Le richieste tramite proxy hanno una cache separata; se il proxy non è raggiungibile, l'autenticazione fallisce o il sito di destinazione non è accessibile tramite il proxy, viene restituito proxy_failed senza alcun addebito. |
| cookies | string | object[] | — | Cookie del sito di destinazione, come singola riga nel formato sid=abc; theme=dark oppure come array nel formato [{"name":"sid","value":"abc"}] (con domain e path facoltativi). Vengono inviati solo al sito di destinazione, non alle terze parti presenti nella pagina. |
| headers | object | — | Header da aggiungere alla richiesta, ad esempio Authorization: Bearer …. Vengono inviati solo al sito di destinazione; non è possibile impostare quelli gestiti dal browser (Host, Cookie, User-Agent, ecc.). |
| local_storage | object | — | Dati da scrivere nel localStorage dell'origine dell'URL di destinazione. Chiavi e valori devono essere stringhe. |
| session_storage | object | — | Come local_storage, ma scrive in sessionStorage. |
| login_profile | string | — | ID del profilo di accesso salvato con l'estensione del browser (lp_8f2c…). È più pratico che passare direttamente i cookie e funziona anche nelle operazioni in batch (che non memorizzano alcuna credenziale). |
Acquisire applicazioni a pagina singola (React, Vue, ecc.):La pagina viene eseguita in un browser reale e lo screenshot viene acquisito dopo l'esecuzione di JavaScript. La strategia predefinita networkidle attende il completamento del recupero dei dati. Se i contenuti vengono renderizzati con timer o animazioni dopo la fine delle richieste, aggiungi wait_for_selector per indicare un elemento che segnali che il contenuto è pronto. Se non c'è un elemento adatto, usa delay per attendere ancora.
Endpoint PDF
/v1/pdf/v1/pdfOgni PDF consuma 2 crediti. Prima della stampa, la pagina viene scorsa per attivare i contenuti con caricamento differito. Oltre ai parametri comuni, sono supportati:
| Parametro | Tipo | Valore predefinito | Descrizione |
|---|---|---|---|
| paper | enum | a4 | Formato carta: a4 o letter. Se la pagina definisce regole @page, queste hanno la precedenza. |
| print_background | boolean | true | Stampa colori e immagini di sfondo. |
| pdf_media | enum | print usa gli stili di stampa; screen usa gli stili a schermo (come visualizzati nel browser). |
curl -X POST "https://glanceshot.com/v1/pdf" \
-H "X-Access-Key: $GLANCESHOT_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Report trimestrale</h1><p>Contenuto…</p>", "paper": "a4"}' \
-o report.pdfRisposte
Per impostazione predefinita (response_type=binary), viene restituito direttamente il file con il Content-Type del formato corrispondente. Header della risposta:
X-Request-Id: ID della richiesta, da fornire per la risoluzione dei problemiX-Glanceshot-Cache:HIToMISSX-Glanceshot-Truncated: true: la pagina intera è stata troncata perché supera 20,000 pixelX-Glanceshot-Format-Changed: webp: un PNG superiore a 5 MB è stato convertito automaticamente in WebP (nessuna conversione se format=png è specificato esplicitamente)
Impostando response_type=json, vengono restituiti l'URL del file e i metadati:
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"}'
# Risposta
{
"url": "https://glanceshot.com/i/3f/3f9c….png",
"cache_hit": false,
"duration_ms": 1284,
"format": "png",
"width": 1280,
"height": 800,
"request_id": "req_01j…"
}URL firmati
Vuoi inserire l'URL dello screenshot direttamente in <img src> senza esporre l'API Key? L'URL firmato contiene solo il key_id pubblico, non l'API Key. La firma viene calcolata sul tuo server usando il secret associato alla chiave. Trovi Key ID e secret nella pagina API Key della console:
canonical = Ordina tutti i parametri, tranne signature, in ordine lessicografico per nome.
Codifica ogni coppia come k=urlencode(v) (RFC 3986, con gli spazi codificati come %20) e uniscile con &
signature = hex(HMAC-SHA256(secret, canonical))Una firma valida autentica la richiesta; le richieste con firma mancante o non valida vengono rifiutate. Qualsiasi modifica ai parametri (ad esempio a url) invalida la firma. Il parametro facoltativo expires (timestamp Unix in secondi) è incluso nella firma; dopo la scadenza viene restituito signature_expired. Per aggiornare la cache, basta modificare un parametro senza effetto (come v=2) e ricalcolare la firma. Gli URL firmati supportano solo richieste GET agli endpoint per screenshot e PDF e non possono includere parametri proxy.
key_id è pubblico e da solo non consente di chiamare l'API. Non inserire l'API Key (access_key) nell'URL firmato: se presente, viene restituito subito invalid_params. Se hai già inserito un'API Key in una pagina web, disattivala nella console e creane una nuova.
import crypto from "node:crypto";
// Codifica RFC 3986 (spazi come %20), conforme alle regole del server
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="Anteprima della pagina web" />Uso dei proxy
Se devi accedere a una pagina da un paese o un'area geografica specifici (ad esempio per visualizzare lingua, contenuti e prezzi locali), puoi includere nella richiesta un proxy acquistato da te, a tue spese. La pagina e tutte le relative immagini, script e richieste API verranno caricati tramite questo proxy. Sono supportati i proxy socks5:// e http://, anche con nome utente e password.
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.pngproxypuò essere incluso solo nel corpo di una richiesta POST: non è consentito nelle richieste GET, negli URL firmati o nelle operazioni in batch, per evitare che le credenziali del proxy compaiano negli URL, nella cronologia del browser o nelle pagine web.- Se il nome utente o la password contengono caratteri speciali come
@o:, devi prima applicare la codifica URL (ad esempio,@diventa%40). - Le richieste con proxy vengono memorizzate in una cache separata e non condividono i risultati con richieste senza proxy o con proxy diversi.
- Se la connessione al proxy o l'autenticazione falliscono, oppure il sito di destinazione non è raggiungibile, viene restituito
proxy_failedsenza alcun addebito.messageindica il motivo specifico. - Il proxy deve avere un indirizzo pubblico. Per l'URL di destinazione valgono le stesse restrizioni delle richieste senza proxy: non è consentito accedere a indirizzi di rete privata.
- Quando accedi a un sito tramite proxy, rispetta i termini d'uso del sito e le leggi locali.
Pagine con accesso richiesto
Per acquisire pagine che richiedono l'accesso, puoi fornire i dati della sessione del tuo account. Hai due possibilità: passare cookies, headers, local_storage e session_storage direttamente nella richiesta, oppure usare l'estensione Glanceshot per salvare la sessione in un «profilo di accesso» e includere nella richiesta solo 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- L'estensione può leggere le credenziali di accesso non accessibili agli script della pagina (inclusi i Cookie HttpOnly), oltre a localStorage e IndexedDB, ed è adatta alla maggior parte dei siti. Per installarla e collegarla, vai alla pagina «Profili di accesso» della console.
- I dati di accesso possono essere trasmessi solo nel corpo di una richiesta POST (
GETe gli URL firmati vengono rifiutati) e non vengono salvati nei log né nella cronologia delle chiamate. Le richieste con dati di accesso vengono memorizzate in una cache separata in base a tali dati, mai condivisa con altri utenti. - Se fornisci i dati di accesso ma la pagina reindirizza al login, viene restituito
login_expiredsenza alcun addebito: la sessione non è più valida e va sincronizzata di nuovo tramite l'estensione. - Per i siti che legano la sessione al dispositivo o all'IP e non consentono di riprodurre l'accesso nel cloud (ad esempio i servizi bancari online), usa «Acquisisci la pagina corrente» nell'estensione per acquisire lo screenshot nel tuo browser e poi caricarlo.
Cache
Le richieste con gli stessi parametri usano la cache (omettere un parametro equivale a specificarne il valore predefinito; i parametri di autenticazione e della cache sono esclusi dal confronto). In caso di riscontro nella cache, la modalità binaria restituisce un reindirizzamento 302 all'URL del file con Cache-Control: il browser segue automaticamente il reindirizzamento e memorizza il file nella cache. La modalità JSON restituisce cache_hit: true.
Le risposte dalla cache non vengono addebitate.Le richieste simultanee con gli stessi parametri generano un solo rendering.
Limiti e addebiti
- Vengono addebitate solo le richieste riuscite (2xx) non servite dalla cache: 1 credito per screenshot, 2 crediti per PDF.
- Timeout, errori di rendering, errori o blocchi di accesso del sito di destinazione, parametri non validi e autenticazione non riuscita non consumano crediti.
- I crediti si rinnovano ogni mese solare (UTC). Il piano gratuito include 100 crediti al mese; una volta esauriti, viene restituito quota_exceeded.
- Se superi il limite di richieste al secondo o di richieste simultanee, viene restituito 429. L'header Retry-After indica quanti secondi attendere prima di riprovare.
- Durata massima di un rendering: 30 secondi. Download massimo per pagina: 50 MB. Dimensione massima del file generato: 50 MB.
Consulta i limiti di ogni piano: Prezzi.
Codici di errore
Tutte le risposte di errore sono in JSON:
{
"error": {
"code": "render_failed",
"message": "target responded with an error status",
"upstream_status": 404,
"request_id": "req_01j…"
}
}| HTTP | code | Significato | Addebitato |
|---|---|---|---|
| 400 | invalid_params | Parametro mancante o fuori intervallo; message indica quale | No |
| 400 | html_too_large | html supera 2 MB | No |
| 401 | unauthorized | API Key mancante, non valida o disattivata | No |
| 401 | signature_invalid | Firma non corrispondente (parametri modificati o secret errato) | No |
| 401 | signature_expired | L'URL firmato ha superato la scadenza expires | No |
| 403 | url_blocked | Accesso all'indirizzo di destinazione non consentito (ad esempio indirizzi di rete interna o localhost) | No |
| 408 | render_timeout | Il rendering ha superato 30 secondi | No |
| 422 | render_failed | Il sito di destinazione ha restituito 4xx/5xx, la risoluzione DNS è fallita o si è verificato un errore di certificato; include upstream_status | No |
| 422 | selector_not_found | selector non corrisponde ad alcun elemento oppure l'attesa di wait_for_selector è scaduta | No |
| 422 | too_many_redirects | Superato il limite di 5 reindirizzamenti | No |
| 422 | site_blocked | Il sito di destinazione mostra una verifica anti-bot, un CAPTCHA, una schermata di accesso o una pagina di accesso negato anziché il contenuto previsto; la richiesta non viene addebitata. | No |
| 422 | login_expired | Sono stati forniti dati di accesso, ma il sito di destinazione mostra ancora la pagina di login: la sessione non è più valida. | No |
| 422 | proxy_failed | Il proxy fornito non è raggiungibile, l'autenticazione è fallita oppure il sito di destinazione non è accessibile tramite il proxy. message indica la causa specifica. Nessun addebito. | No |
| 429 | rate_limited | Superato il limite di richieste al secondo; riprova seguendo Retry-After | No |
| 429 | concurrency_exceeded | Superato il limite di richieste simultanee | No |
| 429 | quota_exceeded | Crediti mensili esauriti (piano gratuito) | No |
| 429 | too_many_batches | Superato il limite di 5 batch in corso | No |
| 500 | internal | Errore del server. Contattaci fornendo request_id | No |
Batch asincroni
/v1/batch/v1/batch/{id}Invia da 1 a 100 URL in una sola richiesta: l'endpoint restituisce subito un ID attività (HTTP 202) e acquisisce gli screenshot uno alla volta in background. Ideale per acquisizioni in batch senza mantenere aperta la connessione. Puoi interrogare periodicamente l'endpoint di stato oppure specificare webhook_url per ricevere una notifica al completamento. L'autenticazione è la stessa degli endpoint sincroni (solo tramite header o parametro access_key; gli URL firmati non sono supportati).
| Parametro | Tipo | Valore predefinito | Descrizione |
|---|---|---|---|
| type | enum | screenshot | screenshot (screenshot) o pdf. |
| urls | string[] | — | URL da elaborare, da 1 a 100. Se anche uno solo non è valido, l'intera richiesta restituisce 400; message ne indica la posizione. |
| options | object | {} | Parametri comuni a tutti gli URL, gli stessi dell'API sincrona (ad esempio full_page, format, viewport_width, cache_ttl). Non possono includere url, html, response_type, proxy. |
| webhook_url | string | — | Facoltativo. URL a cui inviare la notifica al termine di tutte le elaborazioni. Vedi «Webhook di completamento». |
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"
}'
# Risposta 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 }
]
}Verifica l'avanzamento: lo stato status dell'attività passa da queued (in coda) a running (in elaborazione), fino a completed (tutte le elaborazioni terminate, riuscite o meno). Ogni URL ha uno stato tra pending, running, succeeded e failed. In caso di successo, result contiene l'URL del file; in caso di errore, error contiene il codice di errore (gli stessi degli endpoint sincroni).
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" }
}
]
}- Gli addebiti seguono le stesse regole degli endpoint sincroni: ogni URL elaborato con successo consuma 1 credito per screenshot o 2 per PDF. Le risposte dalla cache e le elaborazioni non riuscite non consumano crediti.
- Se i crediti sono già esauriti al momento dell'invio, viene restituito subito
quota_exceeded. Se si esauriscono durante l'elaborazione, gli URL rimanenti falliscono conquota_exceeded. - Ogni account può avere al massimo 5 batch in corso. Oltre questo limite viene restituito
too_many_batches. - La validità dei file generati è determinata da
options.cache_ttl(1 giorno per impostazione predefinita). Scaricali e salvali prima della scadenza. - Nelle risposte di stato e nei webhook,
webhook.urlviene mostrato solo fino al percorso, senza la query string.
Webhook di completamento
Se specifichi webhook_url, al completamento di tutte le elaborazioni inviamo a quell'URL una richiesta POST con corpo JSON: { "event": "batch.completed", "batch": { … } }. Il campo batch è identico alla risposta dell'endpoint di stato. Header della richiesta:
X-Glanceshot-Signature: t=1760779812,v1=5d3f…:tè l'ora di invio (secondi Unix),v1è la firmaX-Glanceshot-Event: batch.completed,X-Glanceshot-Delivery-Attempt: 1(numero del tentativo di invio)
v1 = hex(HMAC-SHA256(secret, t + "." + Corpo originale della richiesta))
secret è il segreto di firma associato all’API Key usata per inviare il task (disponibile nella pagina API Key della console)- Restituisci una risposta 2xx entro 10 secondi, altrimenti l’invio sarà considerato fallito. In caso di errore, verranno effettuati nuovi tentativi dopo 10 secondi, 1 minuto e 5 minuti (fino a 4 tentativi in totale).
- In casi molto rari potresti ricevere notifiche duplicate per lo stesso task. Usa
batch.idper deduplicarle. - Per verificare la firma, calcolala sui byte originali ricevuti e controlla che
tnon differisca dall’ora corrente di più di qualche minuto, per prevenire attacchi replay. - L’indirizzo di callback deve essere un indirizzo http(s) accessibile pubblicamente e non può puntare a una rete privata.
import crypto from "node:crypto";
// rawBody deve contenere i byte originali ricevuti, senza eseguire prima JSON.parse e poi serializzare di nuovo
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; // Protezione dagli attacchi replay
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)Verifica dei consumi
/v1/usagecurl "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", ... }Controllo di stato
/v1/healthNon richiede autenticazione. Restituisce lo stato del nodo e del pool di browser (totali, occupati, disponibili).