Glanceshot
Документация для разработчиков

API Документация

Базовый адрес: https://glanceshot.com/v1. Все методы используют стандартный HTTP. Параметры можно передавать в строке запроса (GET) или в теле JSON (POST).

Быстрый старт

  1. Зарегистрируйтесь бесплатно и создайте ключ на странице «API Key» в консоли.
  2. Передайте ключ в заголовке 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 (если URL нужно разместить на веб-странице — API Key и секрет останутся скрыты)

API Key показывается в открытом виде только один раз — при создании. Сохраните его в надёжном месте. При утечке ключ можно отключить в консоли.

Создание скриншотов

GET/v1/screenshot
POST/v1/screenshot

Параметры только для скриншотов:

ПараметрТипПо умолчаниюОписание
formatenumpngpng, jpeg или webp.
device_scale_factornumber1Коэффициент масштабирования: 1–3. Значение 2 даёт чёткость Retina, размер файла увеличивается примерно в 4 раза.
qualityinteger80Качество JPEG / WebP: 1–100.
full_pagebooleanfalseСкриншот всей страницы. Страница прокручивается экран за экраном для запуска отложенной загрузки. Максимальная высота — 20,000 пикселей.
selectorstring—Скриншот только первого элемента, соответствующего CSS-селектору. Нельзя использовать вместе с full_page.

Общие параметры для скриншотов и PDF:

ПараметрТипПо умолчаниюОписание
urlstring—Адрес страницы для скриншота: http или https. Укажите либо этот параметр, либо html. Фрагмент # в URL сохраняется: можно сразу снять нужную страницу одностраничного приложения с 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 источника (origin) целевого URL. Ключи и значения должны быть строками.
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

Ответ API

По умолчанию (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

Хотите вставить URL скриншота прямо в <img src>, не раскрывая API Key? Подписанный URL содержит только публичный key_id, без API Key. Подпись вычисляется на вашем сервере с помощью секрета, соответствующего ключу. ID ключа и секрет доступны в консоли на странице API Key:

Правила подписи
canonical = Отсортируйте все параметры, кроме signature, в лексикографическом порядке по имени.
            Представьте каждый параметр как k=urlencode(v) (RFC 3986, пробел кодируется как %20) и соедините через &
signature = hex(HMAC-SHA256(secret, canonical))

Корректная подпись подтверждает авторизацию. Запросы без подписи или с неверной подписью отклоняются. Изменение любого параметра (например, url) делает подпись недействительной. Необязательный параметр expires (в секундах Unix) участвует в подписи; после истечения срока возвращается signature_expired. Чтобы обновить кеш, измените любой незначащий параметр (например, v=2) и заново подпишите URL. Подписанные URL поддерживают только GET-запросы к API скриншотов и PDF; параметры прокси не поддерживаются.

key_id — публичный идентификатор, одного его недостаточно для вызова API. Не добавляйте API Key (access_key) в подписанный URL: такой запрос сразу вернёт invalid_params. Если вы уже размещали API 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, историю браузера или на веб-страницы.
  • Если имя пользователя или пароль содержат специальные символы, такие как @ или :, их нужно предварительно закодировать для URL (например, заменить @ на %40).
  • Запросы с прокси кешируются отдельно: их результаты не используются для запросов без прокси или с другим прокси.
  • Если не удалось подключиться к прокси, пройти аутентификацию или открыть целевой сайт, возвращается proxy_failed. Такие запросы не оплачиваются. Конкретная причина указана в message.
  • У прокси должен быть публичный адрес. Для целевого URL действуют те же ограничения, что и без прокси: доступ к адресам внутренней сети запрещён.
  • При доступе к сайтам через прокси соблюдайте условия использования целевого сайта и местное законодательство.

Скриншоты после входа

Чтобы сделать скриншот страницы, доступной только после входа, передайте данные сеанса своей учётной записи. Есть два способа: передать 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Нет
401unauthorizedAPI Key отсутствует, недействителен или отключёнНет
401signature_invalidПодпись не совпадает (параметры изменены или секрет неверен)Нет
401signature_expiredСрок действия подписанного URL, заданный в expires, истёкНет
403url_blockedДоступ к целевому адресу запрещён (например, адрес внутренней сети или localhost)Нет
408render_timeoutРендеринг превысил 30 секундНет
422render_failedЦелевой сайт вернул 4xx/5xx, произошёл сбой DNS или ошибка сертификата; ответ содержит upstream_statusНет
422selector_not_foundПо selector не найден элемент или истекло время ожидания 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{}Общие параметры для всех URL, совпадающие с параметрами синхронного 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 единица квоты для скриншота или 2 для PDF. Результаты из кеша и ошибки квоту не расходуют.
  • Если квота исчерпана при отправке задания, сразу возвращается 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 в консоли).
  • Верните ответ 2xx в течение 10 секунд, иначе доставка считается неудачной. При сбое выполняется по одной повторной попытке через 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

Не требует авторизации. Возвращает состояние узла и пула браузеров: общее число, занятые и свободные.