Скриншоты веб-страниц: Screenshot API
Снимок веб-страницы через headless Chromium с российских серверов. Ответ — само изображение, а не JSON со ссылкой. Две формы вызова:
| Операция | Когда использовать |
|---|---|
POST /v1/browser/screenshot |
основной вариант, формат Browserless: все параметры страницы, ожидания, внедрение скриптов, прозрачный фон |
GET /v1/browser/screenshot |
простой снимок по URL одной строкой, например для <img src> на своём бэкенде |
curl -X POST "https://proxy.seyka.ru/v1/browser/screenshot" \ -H "Authorization: Bearer $SEYKA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "viewport": {"width": 1920, "height": 1080}, "options": {"type": "png", "fullPage": true} }' \ --output screenshot.pngТело — общие параметры страницы (url или html,
viewport, gotoOptions, waitForSelector и другие) плюс объект options:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
options.type |
string |
jpeg |
jpeg, png или webp |
options.quality |
integer |
80 |
качество 0–100; применяется к JPEG и WebP |
options.fullPage |
boolean |
false |
снять страницу целиком, а не только видимую область |
options.omitBackground |
boolean |
false |
прозрачный фон вместо белого (для PNG и WebP) |
viewport.width, viewport.height |
integer |
1280, 800 |
размер окна, 1–4096 |
Вместо url можно передать готовую разметку — удобно для генерации картинок из шаблона:
curl -X POST "https://proxy.seyka.ru/v1/browser/screenshot" \ -H "Authorization: Bearer $SEYKA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "html": "<html><body style=\"font: 64px sans-serif\"><h1>Привет</h1></body></html>", "viewport": {"width": 1200, "height": 630}, "options": {"type": "png"} }' \ --output og.pngДля страниц, которые дорисовываются JavaScript, дождитесь нужного элемента:
{ "url": "https://example.com", "waitForSelector": {"selector": ".content-loaded", "timeout": 5000}, "gotoOptions": {"waitUntil": "networkidle"}, "bestAttempt": true}С bestAttempt: true снимок будет сделан, даже если селектор так и не появился.
curl "https://proxy.seyka.ru/v1/browser/screenshot?url=https://example.com&width=1280&height=800&type=png" \ -H "Authorization: Bearer $SEYKA_API_KEY" \ --output screenshot.png| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
url |
string |
— | обязательный, адрес страницы |
width |
integer |
1280 |
ширина окна, 320–1920 |
height |
integer |
800 |
высота окна, 240–1080 |
type |
string |
jpeg |
jpeg, png или webp |
quality |
integer |
80 |
качество 10–100; применяется к JPEG и WebP |
fullPage |
string |
0 |
1 или true — страница целиком; 0, false или без параметра — только видимая область |
reload |
string |
0 |
1 или true — снять заново, минуя кэш снимков |
GET ждёт события load и не принимает остальные параметры страницы — для ожиданий, куки и заголовков
используйте POST.
200 с телом-изображением и Content-Type image/jpeg, image/png или image/webp. Заголовки
X-Response-Code, X-Response-Status и X-Response-URL сообщают, что ответил сам сайт; GET-снимок из кэша
снимков приходит только с X-Cache: HIT, без этих заголовков. При ошибке приходит
JSON с полями error, errorKind и code — см. ошибки Browser API.
Снимок WebP страницы целиком обрезается до 16383 px по каждой стороне — это предел формата WebP.
const response = await fetch('https://proxy.seyka.ru/v1/browser/screenshot', { method: 'POST', headers: { Authorization: `Bearer ${process.env.SEYKA_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ url: 'https://example.com', options: { type: 'png' } }),});if (!response.ok) throw new Error((await response.json()).error);await Bun.write('screenshot.png', await response.arrayBuffer());console.log(response.headers.get('X-Response-Code')); // код ответа сайтаКэш ответов шлюза у скриншотов выключен: каждый вызов оплачивается полностью, X-Cache: DISABLED.
У GET есть собственный кэш снимков в памяти сервиса: одинаковый запрос (тот же url, размеры, type,
quality, fullPage) может вернуться без нового рендера. Тогда в ответе два заголовка X-Cache: первый —
DISABLED от шлюза, второй — HIT или MISS от кэша снимков; клиент, который склеивает повторяющиеся
заголовки, увидит DISABLED, HIT. Цена вызова от этого не меняется. Чтобы гарантированно получить свежий
снимок, передайте reload=1. У POST собственного кэша нет.
Каждый вызов — по цене скриншота, см. таблицу цен.