RELIABILITY GUIDE

Turn screenshot failures into specific, recoverable application states

Check the HTTP status and response body, preserve a safe request identifier, and classify the failure before choosing retry, user action, or escalation. Do not retry every error.

Classify
Actionable failures
Backoff
Bounded retries
Redact
Safe diagnostics
Install:if (!response.ok) classify(response.status, body)
Auth:SNAPSHOT_SITE_API_KEY
Get started for free
Screenshot error handling flow
Snapshot Site themed screenshot API error handling illustration
Good fits
Production APIs normalizing provider failures
Queue workers with retry and dead-letter handling
User interfaces that need useful job states
Support teams diagnosing capture incidents

Failure location determines the response

A request can fail before rendering, while loading the target, during provider work, or after success when your application stores the result.

1

Request errors

Invalid JSON, unsupported fields, or disallowed targets require a code or user change rather than retry.

2

Authentication errors

Missing or rejected credentials require configuration correction and possible incident response.

3

Transient conditions

Rate, network, capacity, and some timeout failures may justify delayed bounded retry.

4

Downstream failures

A valid provider response can still fail validation, download, database, or storage and must remain observable.

Implementation workflow

Implement normalized failure handling

1

Check response status before reading success fields

2

Parse the error body defensively and redact sensitive inputs

3

Map the failure to retryable, terminal, or user-action categories

4

Record attempts and stop at a defined budget

Screenshot API error handling example

JavaScript

Classify a failed request

The application keeps provider detail for protected diagnostics while returning a stable internal category.

async function capture(payload) {
  const response = await fetch(endpoint, requestFor(payload));
  const text = await response.text();
  const body = safeJson(text);

  if (response.ok) return validateCapture(body);

  const retryable =
    response.status === 429 || response.status >= 500;

  throw new CaptureError({
    category: response.status === 401 ? "authentication" :
      response.status === 429 ? "rate_limit" :
      response.status >= 500 ? "provider" : "request",
    retryable,
    status: response.status,
    safeMessage: body?.error ?? "Capture request failed",
  });
}

A failed job has several possible owners

The caller can submit an invalid field. Deployment can omit the credential. The target can reject navigation or remain incomplete. The provider can return a temporary capacity response. Finally, your database or object store can fail after a successful capture.

Represent these stages separately. A single generic error makes dashboards noisy and encourages unsafe retry.

Retry with a budget

Retries are appropriate only when another attempt can plausibly succeed without changing input. Apply exponential backoff with jitter, respect rate guidance, and cap both attempts and total age. Use application idempotency so a delayed response and a retry cannot create conflicting records.

Move exhausted jobs to a visible terminal or dead-letter state. Operators need the request context and safe error classification to decide whether to replay them.

Log enough, but not secrets

Record an internal job identifier, operation, timing, attempt, HTTP status, and normalized category. Redact the API key, signed tokens, private query parameters, and sensitive output URLs. Limit raw response excerpts and keep them in protected logs.

UI copy should state what the user can do: correct a URL, try later, contact an administrator, or review access. It should not expose provider internals.

Read the rate limit guide before setting concurrency and retry policy.

Screenshot API Error Handling FAQ

Should every screenshot API error be retried?

No. Invalid requests and authentication failures need correction. Retry only transient categories with backoff, jitter, a cap, and idempotent application behavior.

How should HTTP 429 be handled?

Reduce request rate, honor retry guidance when present, delay with jitter, and shape concurrency before resubmitting.

What should happen on a 401 or authentication failure?

Stop retrying with the same configuration, verify secret injection and header use, and rotate the credential if exposure is possible.

How should response JSON be parsed?

Read defensively because proxies and upstream systems can return non-JSON bodies. Preserve a bounded safe excerpt in protected diagnostics.

What should a user-facing error say?

Use a stable category and an actionable message without revealing credentials, internal endpoints, signed URLs, or raw provider internals.

How are target timeouts different from provider errors?

A target may be slow or never reach readiness even while the service is available. Keep target and provider categories separate for useful remediation.

What if downloading the returned asset fails?

Record capture success separately from application storage failure, retry the storage stage safely, and do not mark the overall job ready prematurely.

What belongs in an error record?

Include internal job ID, safe target identity, endpoint operation, status, category, attempt, timing, and correlation data while redacting sensitive values.

Define your capture failure taxonomy

Separate terminal, retryable, and user-action failures before increasing traffic or automating retries.