Glanceshot
開發者文件

API 文件

基底 URL 為 https://glanceshot.com/v1。所有端點皆使用標準 HTTP,參數可放在查詢字串(GET)或 JSON 本文(POST)中。

快速開始

  1. 免費註冊,並在控制台的「API Key」頁面建立 Key。
  2. 將 Key 放入 X-Access-Key 請求標頭,呼叫截圖端點:
curl "https://glanceshot.com/v1/screenshot?url=https://example.com&full_page=true" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -o screenshot.png

身分驗證

每個請求都需要 API Key,可透過以下任一方式傳遞:

  • 請求標頭 X-Access-Key: gls_…(建議使用,適合伺服器端呼叫)
  • 查詢參數 access_key=gls_…(僅限伺服器端呼叫,請勿放入網頁)
  • 簽章 URL(需要將網址放入網頁時使用,不會洩露 API Key 或 secret)

API Key 的明文只會在建立時顯示一次,請妥善保存。若外洩,可在控制台停用。

截圖端點

GET/v1/screenshot
POST/v1/screenshot

截圖專用參數:

參數類型預設值說明
formatenumpngpng、jpeg 或 webp。
device_scale_factornumber1縮放比例 1–3。設為 2 可達 Retina 清晰度,檔案大小約為 4 倍。
qualityinteger80JPEG / WebP 品質,1–100。
full_pagebooleanfalse擷取整頁。會逐屏捲動以觸發延遲載入,高度上限為 20,000 像素。
selectorstring—僅擷取符合此 CSS 選擇器的第一個元素。不可與 full_page 同時使用。

截圖與 PDF 共用參數:

參數類型預設值說明
urlstring—要擷取的網頁網址,使用 http 或 https。與 html 擇一使用。網址中的 # 片段會保留,使用 hash 路由的單頁應用程式(如 https://app.com/#/report/1)可直接擷取對應頁面。
htmlstring—直接傳入 HTML(上限 2 MB),僅支援 POST。
viewport_widthinteger1280檢視區寬度,320–3840。小於 768 時以行動裝置模式算繪。
viewport_heightinteger800檢視區高度,200–3840。
wait_untilenumnetworkidle等待策略:domcontentloaded(最快,適合靜態頁面)、load、networkidle(從開啟頁面起追蹤所有請求,頁面載入後,連續 500 毫秒沒有進行中的請求才截圖,最多額外等待 8 秒,適合單頁應用程式)。
wait_for_selectorstring—頁面載入後,等待符合此 CSS 選擇器的元素出現且可見再截圖,最多等待 10 秒;若未出現則回傳 selector_not_found(不計費)。適合不依賴網路請求,而是透過計時器或動畫延遲算繪內容的單頁應用程式,例如 .chart-ready。
delayinteger0等待完成後額外延遲的毫秒數,0–10000。可用於等待動畫或延遲載入元件。
block_adsbooleantrue封鎖廣告與追蹤網域的請求,並隱藏頁面上的廣告版位。
block_cookie_bannersbooleantrue隱藏 Cookie 同意彈窗。
dark_modebooleanfalse模擬 prefers-color-scheme: dark。
hide_selectorsstring—要隱藏的元素,以 CSS 選擇器清單指定,例如 .ad,#popup。
cachebooleantrue是否查詢快取。設為 false 時強制重新算繪,結果仍會寫入快取。
cache_ttlinteger86400快取有效期限(秒),60–2592000。
response_typeenumbinarybinary 直接回傳檔案;json 回傳檔案網址與中繼資料。
proxystring—選填,使用自行購買的代理伺服器存取目標網頁(代理費用由你負擔),例如需要從指定國家或地區存取時。支援 socks5:// 和 http://,可包含帳號密碼,格式如 socks5://user:pass@203.0.113.10:1080。只能放在 POST 請求主體中,不適用於 GET 請求、簽署 URL 和批次工作。使用代理伺服器的請求會分開快取;若無法連線至代理伺服器、驗證失敗或無法存取目標網站,則回傳 proxy_failed,不計費。
cookiesstring | object[]—目標網站的 Cookie,可以是 sid=abc; theme=dark 這樣的單行字串,也可以是 [{"name":"sid","value":"abc"}] 這樣的陣列(可帶 domain、path)。只會傳送給目標網站,不會傳送給頁面中的第三方。
headersobject—要附加的請求標頭,例如 Authorization: Bearer …。只會傳送給目標網站;由瀏覽器管理的標頭(Host、Cookie、User-Agent 等)無法設定。
local_storageobject—要寫入目標網址所屬來源的 localStorage,鍵和值皆為字串。
session_storageobject—同 local_storage,寫入 sessionStorage。
login_profilestring—透過瀏覽器擴充功能儲存的登入設定檔編號(lp_8f2c…)。比直接傳入 cookies 更方便,也能用於批次任務(任務中不會儲存任何憑證)。

擷取單頁應用程式(React、Vue 等):頁面會在真實瀏覽器中執行完 JavaScript 後再截圖。預設的 networkidle 會等待頁面取得資料;若內容是在請求結束後才透過計時器或動畫算繪,請加上 wait_for_selector,指定代表「內容已就緒」的元素;若沒有合適的元素,再用 delay 多等一會。

PDF 端點

GET/v1/pdf
POST/v1/pdf

每次產生 PDF 會扣除 2 次額度。列印前會先捲動整個頁面,以觸發延遲載入的內容。除共用參數外,也支援:

參數類型預設值說明
paperenuma4紙張:a4 或 letter。頁面自帶 @page 規則時,優先使用頁面設定。
print_backgroundbooleantrue列印背景色與背景圖片。
pdf_mediaenumprintprint 使用列印樣式;screen 使用螢幕樣式(所見即所得)。
HTML 轉 PDF
curl -X POST "https://glanceshot.com/v1/pdf" \
  -H "X-Access-Key: $GLANCESHOT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html": "<h1>季度報告</h1><p>內文……</p>", "paper": "a4"}' \
  -o report.pdf

回傳結果

預設(response_type=binary)直接回傳檔案,Content-Type 為對應格式。回應標頭:

  • X-Request-Id:本次請求 ID,排查問題時請提供
  • X-Glanceshot-Cache:HIT 或 MISS
  • X-Glanceshot-Truncated: true:整頁高度超過 20,000 像素,已截斷
  • X-Glanceshot-Format-Changed: webp:PNG 超過 5 MB 時自動轉為 WebP(明確指定 format=png 時不會轉換)

設定 response_type=json 時,會回傳檔案網址與中繼資料:

JSON 回應
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"}'

# 回傳
{
  "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

想將截圖網址直接放入 <img src>,又不想洩露 API Key?簽章 URL 不含 API Key,只包含公開的 key_id,再由你自己的伺服器使用該 Key 對應的 secret 計算簽章。Key ID 和 secret 都可在控制台的 API Key 頁面查看:

簽章規則
canonical = 將 signature 以外的所有參數,依參數名稱的字典順序排序,
            每項格式為 k=urlencode(v)(RFC 3986,空格編碼為 %20),並以 & 串接
signature = hex(HMAC-SHA256(secret, canonical))

簽章正確即視為通過驗證,缺少簽章或簽章錯誤的請求都會遭到拒絕。任何參數遭到變更(例如更換 url),簽章都會失效。選用參數 expires(Unix 秒)也會納入簽章計算,過期後會回傳 signature_expired。若要更新快取,只要變更一個不影響內容的參數(如 v=2),再重新簽章即可。簽章 URL 僅支援以 GET 方式呼叫截圖和 PDF API,且不可包含代理伺服器參數。

key_id 是公開資訊,僅憑它無法呼叫 API。請勿將 API Key(access_key)放入簽章 URL,否則會直接回傳 invalid_params。如果曾將 API Key 放入網頁,請在控制台停用該 Key,並建立新的 Key。

import crypto from "node:crypto";

// RFC 3986 編碼(空格為 %20),必須與伺服器端規則一致
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="網頁預覽" />

使用代理伺服器

需要從指定國家或地區存取網頁時(例如查看當地的語言、內容和價格),可以在請求中帶入自行購買的代理伺服器,費用由你負擔。網頁及其中的圖片、指令碼和 API 請求都會透過此代理伺服器載入。支援 socks5:// 和 http:// 兩種代理伺服器,可使用帳號和密碼。

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 只能放在 POST 請求主體中:GET 請求、簽章 URL 和批次工作都不能帶入,以免代理伺服器的帳號密碼出現在網址、瀏覽紀錄或網頁中。
  • 帳號或密碼含有 @、: 等特殊字元時,須先進行 URL 編碼(例如將 @ 寫成 %40)。
  • 使用代理伺服器的請求會獨立快取,不會與未使用代理伺服器或使用其他代理伺服器的請求共用結果。
  • 代理伺服器無法連線、驗證失敗或無法存取目標網站時,會傳回 proxy_failed,且不計費。message 會說明具體原因。
  • 代理伺服器必須使用公用網路位址。目標網址的限制與未使用代理伺服器時相同,不能存取內部網路位址。
  • 透過代理伺服器存取網站時,請遵守目標網站的使用條款及當地法律。

擷取登入後的頁面

若要擷取需登入才能瀏覽的頁面,可以附上自己帳號的登入狀態。有兩種方式:直接在請求中傳入 cookies、headers、local_storage、session_storage,或使用 Glanceshot 瀏覽器擴充功能,將登入狀態儲存為「登入設定檔」,請求中只需填入 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
  • 擴充功能可讀取網頁指令碼無法存取的登入憑證(包括 HttpOnly Cookie),以及 localStorage、IndexedDB,適用於大多數網站。請前往控制台的「登入設定檔」頁面安裝並連接擴充功能。
  • 登入狀態只能透過 POST 請求主體傳送(GET、簽署 URL 都會被拒絕),不會寫入日誌或呼叫紀錄;附有登入狀態的請求會依該狀態獨立快取,不會與他人共用。
  • 若已附上登入狀態,頁面卻跳回登入頁面,會回傳 login_expired,且不計費(表示登入已失效,請使用擴充功能重新同步)。
  • 對於工作階段綁定裝置或 IP、無法在雲端重現登入狀態的網站(如網路銀行),請使用擴充功能的「擷取目前頁面」,在自己的瀏覽器中擷取畫面後上傳。

快取

參數完全相同的請求會命中快取(省略參數與明確傳入預設值視為相同;驗證參數與快取參數不納入比較)。命中時,二進位模式會回傳 302,重新導向至檔案網址,並附上 Cache-Control;瀏覽器會自動跟隨重新導向並快取。JSON 模式則回傳 cache_hit: true。

命中快取不計費。相同參數的並行請求只會算繪一次。

限額與計費

  • 僅對成功(2xx)且未命中快取的請求計費:截圖扣除 1 次額度,PDF 扣除 2 次。
  • 逾時、渲染失敗、目標網站發生錯誤或封鎖存取、參數錯誤、驗證失敗,皆不扣除額度。
  • 額度於每個曆月(UTC)重設。免費方案每月提供 100 次額度,用完後回傳 quota_exceeded。
  • 超過每秒請求數或並行請求數上限時,會回傳 429;回應標頭 Retry-After 會提供建議等待的秒數。
  • 單次算繪最長 30 秒;單頁下載量上限 50 MB;輸出檔案上限 50 MB。

查看各方案的詳細限額:價格。

錯誤碼

錯誤回應一律為 JSON:

錯誤格式
{
  "error": {
    "code": "render_failed",
    "message": "target responded with an error status",
    "upstream_status": 404,
    "request_id": "req_01j…"
  }
}
HTTPcode意義計費
400invalid_params參數缺漏或超出範圍,message 會指出具體參數否
400html_too_largehtml 超過 2 MB否
401unauthorized缺少 API Key,或 Key 無效/已停用否
401signature_invalid簽章不符(參數遭到變更或 secret 錯誤)否
401signature_expired簽章 URL 已超過 expires 指定的時間否
403url_blocked不允許存取目標網址(例如內部網路位址、localhost)否
408render_timeout算繪超過 30 秒否
422render_failed目標網站回傳 4xx/5xx、DNS 解析失敗或憑證錯誤;附帶 upstream_status否
422selector_not_foundselector 未符合任何元素,或 wait_for_selector 等待逾時否
422too_many_redirects重新導向超過 5 次否
422site_blocked目標網站未顯示正常內容,而是顯示人機驗證、驗證碼、要求登入或拒絕存取的頁面;不計費否
422login_expired已附上登入狀態,但目標網站仍顯示登入頁面,表示登入狀態已失效。否
422proxy_failed無法連線至你提供的代理伺服器、驗證失敗,或代理伺服器無法存取目標網站;message 會說明具體原因,不計費否
429rate_limited超過每秒請求數上限,請依 Retry-After 重試否
429concurrency_exceeded超過並行請求數上限否
429quota_exceeded本月額度已用完(免費方案)否
429too_many_batches同時未完成的批次工作超過 5 個否
500internal伺服器端錯誤,請提供 request_id 並聯絡我們否

非同步批次

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

一次提交 1–100 個網址,端點會立即回傳工作 ID(HTTP 202),並在背景逐一完成截圖。適合批次截圖、不想持續保持連線等待的情境。可輪詢查詢端點,也可填入 webhook_url,全部完成後我們會主動通知你。身分驗證方式與同步端點相同(僅支援請求標頭或 access_key 參數,不支援簽章 URL)。

參數類型預設值說明
typeenumscreenshotscreenshot(截圖)或 pdf。
urlsstring[]—要處理的網址,1–100 個。任一網址無效時,整個請求會回傳 400,message 會指出是第幾個網址。
optionsobject{}所有網址共用的參數,與同步 API 的參數相同(如 full_page、format、viewport_width、cache_ttl),不可包含 url、html、response_type、proxy。
webhook_urlstring—選填。全部完成後接收通知的網址,請參閱「完成回呼」。
提交批次工作
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"
  }'

# 回傳 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 }
  ]
}

查詢進度:工作狀態 status 依序為 queued(排隊中)、running(處理中)、completed(全部完成,不論成功或失敗)。每個網址的狀態為 pending、running、succeeded 或 failed;成功時會在 result 中提供檔案網址,失敗時則在 error 中提供錯誤碼(與同步端點的錯誤碼相同)。

查詢批次工作
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" }
    }
  ]
}
  • 計費規則與同步端點相同:每個成功的網址,截圖扣除 1 次額度,PDF 扣除 2 次;命中快取或失敗則不扣除額度。
  • 提交時若額度已用完,會直接回傳 quota_exceeded;若處理過程中額度用完,其餘網址會以 quota_exceeded 回報失敗。
  • 每個帳號同時最多可有 5 個未完成的批次工作,超過時回傳 too_many_batches。
  • 結果檔案的有效期限由 options.cache_ttl 決定(預設 1 天),請及時下載保存。
  • 查詢結果與回呼中的 webhook.url 僅顯示至路徑,不會回傳查詢字串。

完成回呼

若填入 webhook_url,所有工作完成後,我們會向該網址傳送 POST 請求,請求本文為 JSON:{ "event": "batch.completed", "batch": { … } },其中 batch 與查詢端點的回傳內容完全相同。請求標頭:

  • X-Glanceshot-Signature: t=1760779812,v1=5d3f…:t 為傳送時間(Unix 秒),v1 為簽章
  • X-Glanceshot-Event: batch.completed、X-Glanceshot-Delivery-Attempt: 1(第幾次傳送)
簽章規則
v1 = hex(HMAC-SHA256(secret, t + "." + 原始請求本文))
secret 是提交任務時使用的 API Key 所對應的簽章密鑰(可在控制台的 API Key 頁面查看)
  • 請在 10 秒內回傳 2xx,否則視為失敗。失敗後會在 10 秒、1 分鐘、5 分鐘後各重試一次(總計最多 4 次)。
  • 極少數情況下,同一個任務可能會收到重複通知,請依 batch.id 排除重複通知。
  • 驗證簽章時,請使用收到的原始位元組計算,並確認 t 與目前時間相差不超過幾分鐘,以防止重放攻擊。
  • 回呼網址必須是可從公網存取的 http(s) 網址,不得指向內部網路。
import crypto from "node:crypto";

// rawBody 必須是收到的原始位元組,不可先 JSON.parse 再序列化
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; // 防重播攻擊
  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)

用量查詢

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", ... }

健康檢查

GET/v1/health

無須驗證身分,回傳節點狀態與瀏覽器集區狀態(總數、忙碌、閒置)。