Errors

This page lists every status the ScreenshotBuddy API answers with, what each one means, and which of them are worth sending again.

The shape of an error

Every error is JSON in the same shape, whatever went wrong.

  • Name
    code
    Type
    string
    Description

    The reason the request was refused, as a short stable string. This is the field to branch on. Every code is listed under error codes below.

  • Name
    message
    Type
    string
    Description

    The same reason in words, written for a person to read. It can be reworded or made more specific at any time, so show it to a human rather than matching your code against it.

  • Name
    errors
    Type
    object
    Description

    Sent only when a particular parameter is at fault. It is keyed by the query parameter, with the messages for that parameter, and it is left out entirely otherwise.

  • Name
    request_id
    Type
    string
    Description

    Identifies that one answer, and it is in our logs against the request that produced it. Quote it when you ask us about a failure and we can look up exactly what happened.

You get JSON whatever Accept header you send, so a client that asks for nothing in particular still gets an error it can parse rather than an HTML page.

The request_id is also sent as the X-Request-Id header, and the two are always the same value. A successful render answers with the file rather than JSON, so the header is the one place the id exists on every answer we send. Log it from there and you have it whether the request worked or not.

Statuses

  • Status
    200
    Worth retrying
    success
    Description

    The rendered file. The body is the image or the PDF itself rather than JSON, so write it to a file instead of parsing it. The Content-Type names the format that was rendered.

  • Status
    401
    Worth retrying
    do not retry
    Codes
    unauthenticated
    Description

    The request carried no bearer token, or a token that is unknown or revoked.

  • Status
    402
    Worth retrying
    do not retry
    Codes
    no_active_plan credit_limit_reached
    Description

    The account has no active plan, or it has used every credit in the current period. The code says which of the two it is.

  • Status
    403
    Worth retrying
    do not retry
    Codes
    email_unverified missing_ability
    Description

    The email address of the account has not been verified yet, or the token is not allowed to ask for the mode the request is in. The code says which of the two it is: a token carries a permission per mode, and one narrowed to screenshots cannot print a PDF.

  • Status
    422
    Worth retrying
    do not retry
    Codes
    validation_failed invalid_url blocked_host target_unreachable
    Description

    A query parameter did not validate, or the target URL could not be reached or loaded ("The target URL could not be reached or loaded. Check that it is publicly available and try again."). The errors object names the parameter at fault. No credit is charged.

  • Status
    429
    Worth retrying
    retry
    Codes
    rate_limited
    Description

    The rate limit of the account was exceeded. Wait for the number of seconds in the Retry-After header before sending the request again.

  • Status
    500
    Worth retrying
    do not retry
    Codes
    render_failed server_error
    Description

    The render failed for a reason we did not recognise. The credit is refunded.

  • Status
    502
    Worth retrying
    retry
    Codes
    upstream_error upstream_quota_exceeded
    Description

    The rendering service failed to process the request. The credit is refunded and the request is worth sending again.

  • Status
    504
    Worth retrying
    retry
    Codes
    render_timeout
    Description

    The render did not finish within its time budget. The credit is refunded and the request is worth sending again.

The statuses marked retry (429, 502 and 504) carry a Retry-After header with the number of seconds to wait before sending the same request again. Wait that long rather than retrying straight away: a retry that arrives sooner is answered the same way.

The others describe a request that would fail the same way every time, so change something before you send it again. A render that fails after the request was accepted refunds its credit, so a retry costs you nothing you were not going to spend.

Error codes

Every code the API can answer with, and the status it comes back on. A status can carry more than one code, because the status alone does not always say what happened: both 402s stop the request, but only one of them is fixed by buying more credits.

  • Code
    unauthenticated
    Status
    401
    Description

    No bearer token was sent, or the token is unknown or revoked.

  • Code
    invalid_signature
    Status
    401
    Description

    A signed URL did not verify. Either the signature does not match the query, or the token it names is unknown, revoked or expired. Rebuild the URL from the canonical form on the signed URLs page, and check that nothing was appended to it after it was signed.

  • Code
    signed_url_expired
    Status
    401
    Description

    A signed URL is past the `expires` moment it was signed with. The signature itself was fine, so sign a new URL with a later expiry.

  • Code
    email_unverified
    Status
    403
    Description

    The account exists but its email address has not been verified yet.

  • Code
    missing_ability
    Status
    403
    Description

    The token is not allowed to ask for this mode. A token carries a permission per mode, `screenshot` and `pdf`, and both are granted unless the token was deliberately narrowed. Widen it in your dashboard, or send the request with a token that holds the permission.

  • Code
    no_active_plan
    Status
    402
    Description

    The account is on no plan, so it has no credits to spend. Pick a plan and the same request works.

  • Code
    credit_limit_reached
    Status
    402
    Description

    Every credit in the current period is spent. It resets at the end of the period.

  • Code
    validation_failed
    Status
    422
    Description

    A query parameter is missing, malformed, or not accepted in the mode the request is in. The errors object names it.

  • Code
    invalid_url
    Status
    422
    Description

    The url is missing or is not a URL the API will accept. Fix the string and send it again.

  • Code
    blocked_host
    Status
    422
    Description

    The url points at a private, loopback or internal address. Reformatting it will not help; only a publicly reachable host is rendered.

  • Code
    target_unreachable
    Status
    422
    Description

    The page itself could not be reached or loaded. Check that it is publicly available.

  • Code
    rate_limited
    Status
    429
    Description

    The account went over its requests per minute. Wait for the Retry-After header and send the request again.

  • Code
    render_failed
    Status
    500
    Description

    The render failed for a reason we did not recognise. The credit is refunded.

  • Code
    server_error
    Status
    500
    Description

    Something failed that we did not expect at all. The catch-all, and always worth reporting with the request id.

  • Code
    upstream_error
    Status
    502
    Description

    The rendering service failed to process the request. The credit is refunded and a retry is worthwhile.

  • Code
    upstream_quota_exceeded
    Status
    502
    Description

    The rendering service has spent its own capacity for the period. Nothing is broken, so back off for longer than you would on an ordinary upstream failure.

  • Code
    render_timeout
    Status
    504
    Description

    The render ran past its time budget. The credit is refunded and the same request may well succeed later.

  • Code
    not_found
    Status
    404
    Description

    No endpoint exists at that path.

  • Code
    method_not_allowed
    Status
    405
    Description

    The endpoint exists but does not accept that HTTP method. The Allow header names the ones it does.

Three of them are not tied to taking a screenshot: not_found, method_not_allowed and server_error can answer any request under api/*, so handle them wherever you call us rather than only around a render.

Codes are a published contract. We add new ones as the API grows, so treat one you do not recognise the way you would treat its status, and keep the request_id either way.

Validation errors

A request that leaves out url, or sends a parameter the mode it is in does not accept, comes back as 422 with the parameter named in the errors object. The code says which kind of failure it was: invalid_url for a url the API will not take, blocked_host for one it will not visit, and validation_failed for any other parameter.

422
application/json
{
    "code": "invalid_url",
    "message": "The url query parameter is required.",
    "errors": {
        "url": [
            "The url query parameter is required."
        ]
    },
    "request_id": "1f3c0e6a-6a5d-4a4c-9a3f-0a3f7d1c2b84"
}

Which parameters a mode accepts is on the taking screenshots and creating PDFs pages. The 429 status has a page of its own under rate limits.