К содержанию

Скриншоты

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

/take доступен только на PAID. На FREE API возвращает 402 PAID_PLAN_REQUIRED — используйте асинхронный API.

Отправьте POST-запрос

POST /take принимает параметры скриншота в JSON. API-ключ передавайте только в X-API-Key. Неизвестные поля JSON и любые параметры в строке запроса отклоняются.

Добавьте Idempotency-Key, если клиент может повторить запрос после сетевой ошибки. При повторе используйте тот же ключ и те же параметры.

Создайте новый ключ для новой операции. Если повторяете тот же запрос после сетевой ошибки, используйте прежнее значение.

Полные правила повторов описаны в разделе «Идемпотентность».

curl
IDEMPOTENCY_KEY="docs-$(date +%s)-$$"

curl --silent --show-error \
  --request POST "https://api.shotly.cloud/take" \
  --header "X-API-Key: $SHOTLY_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $IDEMPOTENCY_KEY" \
  --dump-header response.headers \
  --output response.body \
  --data '{
    "url": "https://example.com",
    "browser": "chromium",
    "format": "png",
    "fullPage": true
  }'

Проверьте статус и Content-Type

Не записывайте ответ сразу в screenshot.png: при ответе 202 в файл попадёт JSON. В примере выше заголовки и тело сохранены отдельно. После запроса проверьте их:

shell
STATUS=$(awk 'toupper($1) ~ /^HTTP\// { code=$2 } END { print code }' response.headers)
CONTENT_TYPE=$(awk -F ': *' 'tolower($1) == "content-type" { print tolower($2) }' response.headers | tr -d '\r')

if [ "$STATUS" = "200" ] && printf '%s' "$CONTENT_TYPE" | grep -Eq '^image/png'; then
  mv response.body screenshot.png
elif [ "$STATUS" = "200" ] && printf '%s' "$CONTENT_TYPE" | grep -Eq '^image/jpeg'; then
  mv response.body screenshot.jpeg
elif [ "$STATUS" = "200" ] && printf '%s' "$CONTENT_TYPE" | grep -Eq '^image/webp'; then
  mv response.body screenshot.webp
elif [ "$STATUS" = "202" ] && printf '%s' "$CONTENT_TYPE" | grep -Eq '^application/json'; then
  cat response.body
else
  cat response.body >&2
  exit 1
fi

При 200 OK API возвращает image/png, image/jpeg или image/webp. В ответе также есть Content-Disposition: inline, Content-Length, X-Shotly-Task-Id и Cache-Control: private, no-store.

Если запрос содержал Idempotency-Key, ответ 200 также содержит заголовки Idempotency-Key и X-Idempotency-Replayed.

Продолжите после 202 Accepted

Если задача не завершилась за время ожидания, API возвращает Retry-After: 2, X-Shotly-Task-Id, Cache-Control: private, no-store и JSON:

json
{
  "taskId": "9f0c6a7e-7d7f-4a62-9d70-7c7ddf4c8e52",
  "status": "PENDING",
  "statusUrl": "/v1/screenshots/9f0c6a7e-7d7f-4a62-9d70-7c7ddf4c8e52",
  "message": "Скриншот ещё создаётся. Продолжите проверку по statusUrl."
}

Если запрос содержал Idempotency-Key, ответ 202 также содержит Idempotency-Key и X-Idempotency-Replayed.

Задача продолжает выполняться после завершения HTTP-запроса. Сформируйте полный URL из https://api.shotly.cloud и относительного statusUrl, затем проверяйте статус задачи. Эти проверки не расходуют квоту повторно.

Повтор POST /take без того же Idempotency-Key может создать ещё одну оплачиваемую задачу.

Задайте клиентский таймаут с запасом

Сервер ждёт до 70 секунд. Это не гарантия завершения: очередь и создание скриншота могут занять больше времени. Задайте клиентский таймаут больше 70 секунд, чтобы API успел вернуть изображение или ответ 202.

Ограничение одновременных ожиданий

Число одновременных синхронных ожиданий ограничено. Новый запрос может получить 429 SYNC_WAIT_CAPACITY_EXCEEDED. Подождите время из Retry-After, если заголовок присутствует.

При повторе уже выполняющейся задачи с тем же Idempotency-Key API может сразу вернуть 202, не создавая новую задачу.

Обработайте ошибки задачи

422 SCREENSHOT_TASK_FAILED означает, что скриншот создать не удалось. 503 SCREENSHOT_OBJECT_UNAVAILABLE означает, что готовое изображение временно недоступно.

Решение для остальных кодов приведено в разделе «Ошибки и повторы».

GET /take — вариант для совместимости

GET /take принимает те же параметры в URL:

curl
curl --get "https://api.shotly.cloud/take" \
  --header "X-API-Key: $SHOTLY_API_KEY" \
  --data-urlencode "url=https://example.com" \
  --data-urlencode "browser=chromium" \
  --data-urlencode "format=png" \
  --data-urlencode "fullPage=true"