ViperCapture
API documentation

Errors and request IDs

Error response format, retry behavior, and request IDs.

Error shape

request.json
{
  "error": {
    "code": "render_timeout",
    "message": "The target did not become ready before the timeout.",
    "retryable": true,
    "request_id": "01J…",
    "details": {}
  }
}

Retry rules

Retry only when retryable is true. Use exponential backoff with jitter. On HTTP 429, wait for Retry-After. HTTP 503 with capture_queue_busy means the separate 30 API or 10 website request queue was full, the website account/IP already had an active-or-queued request, or the request waited 60 seconds without receiving one of the 3 browser slots. temporary_delivery_unavailable means an oversized signed-in website image could not be placed in the temporary cache and may be retried. Client errors such as invalid selectors, private targets, oversized dimensions, outputs above 50 MiB, or malformed JSON should be fixed instead of retried.

CAPTCHA decisions

A detected page-level challenge returns HTTP 409 with code captcha_detected, provider details, and retryable: false. If displaying the challenge is acceptable, repeat the request with proceed_on_captcha: true. If you administer the target, the site access guide explains narrow access rules and caller-managed external tool use without disabling protection globally. ViperCapture never invokes an external tool or accepts its credentials.

Feature-specific failures

  • target_status_failed (424): main navigation matched fail_on_status. Retryable only for 429 or 5xx.
  • clip_out_of_bounds (422): crop extends past the final document; use returned document dimensions.
  • custom_css_invalid (422): the browser could not apply the supplied style.
  • selector_not_found (404): first selector match was absent or not visible.
  • output_dimensions_exceeded, pixel_limit_exceeded, page_too_tall, or output_too_large (413): reduce viewport, density, page scope, pack count, or content.
  • async_output_unsupported / async_cache_unsupported (422): the job endpoint requires one uncached PNG, JPEG, or WebP.
  • async_account_limit (429) / async_queue_full (503): account or global active-job capacity is full.
  • idempotency_key_conflict (409): an async X-Request-Id was reused with a different request body.
  • job_not_ready / job_already_running (409): poll later or allow the running job to finish.
  • async_attempts_exhausted: all 3 bounded async execution attempts failed; the terminal job is not retryable.
  • async_result_expired (410): the four-hour result window ended.
  • Any viewport-pack member failure aborts the whole ZIP and releases all reserved credits.

Request IDs

You may send your own valid X-Request-Id; otherwise ViperCapture creates one. For POST /v1/jobs, reuse the same ID only with the exact same body: that safely returns the original job, while a different body returns idempotency_key_conflict. Keep request IDs in logs and support reports. They never contain account or target secrets.