Skip to content

Async and Webhooks

ScreenshotOne supports asynchronous screenshot rendering and webhooks. The document describes both of them in one place since usually they are used together.

The main current supported use case is to render screenshots asynchronously, upload them to S3 and return the file location to the specified webhook. That’s what customers asked to implement first.


You can literally execute any request asynchronously by setting the async option to true. But not every request makes sense to execute asynchronously.

Once you set async=true, the API checks your access key and limits and returns the response immediately but continues to execute the request.

One of the top use cases for which it was requested is uploading files to S3 asynchronously without waiting for screenshots to be rendered.

An example of such a request could be:

You request rendering but don’t wait for the response. What if you want to get the result of uploading? You can do it by using webhooks.


Using webhooks with ScreenshotOne allows you to deliver the results of the request execution to your URL as a POST body.

Currently, caching is not supported for webhooks since it doesn’t make much sense. If you need its support for other use cases, please, send a chat message or email to

You can use webhooks with both synchronous and asynchronous requests. But usually, it is used in combination with asynchronous requests.

An example of an asynchronous request that uploads rendered screenshot to S3 and sends a webhook might look like this:

Not that, to get the location, you must specify the storage_return_location parameter as true.

An example of the webhook request body you will receive:

// ...
"store": {
// ...
"location": "..."

You also receive the X-ScreenshotOne-Signature (x-screenshotone-signature) header that you should use to validate the webhook request body and make sure that ScreenshotOne sent the request.

Verifying Signature

To ensure that ScreenshotOne sent the request, you should get the signature from the X-ScreenshotOne-Signature header and verify it with your secret key from the access page by applying the HMAC SHA-256 algorithm.

Never share your secret key with any party. In case it is leaked, you can quickly regenerate it on the access page.

A pseudo-code on TypeScript (Node.js) of how you can do it:

import * as crypto from "crypto";
const receivedSignature = request.headers.get("x-screenshotone-signature");
const requestBody = await request.rawText();
const calculatedSignature = crypto
.createHmac("sha256", yourSecretKey)
.update(requestBody, "utf-8")
if (calculatedSignature !== receivedSignature) {
// the signature is not valid
// you should not process this request and reject it immediately
throw new Error("...");
// it is safe to process the request
// you can do something with the webhook request body

Disable Signing

Singing webhook request body takes time. If you are sure that your webhooks are unique and secret, you might want to disable signing to improve performance by using webhook_sign=false.

Debugging and support headers

There are a few headers that are not part of the body and are not participating in the signing. They must not be used for any logic; it is just for debugging and support purposes:

  • x-screenshotone-rendering-seconds—screenshot rendering time in seconds with fractions, e.g. 2.56;
  • x-screenshotone-size-bytes—screenshot size if available (not streaming), e.g. 30033;
  • x-screenshotone-trace-id—unique request trace id when reaching out to the ScreenshotOne support;
  • x-screenshotone-reference—screenshot or video id (if available) that can be seen in the history or used when reaching out to the ScreenshotOne support.


That’s it. In case you have any questions or problems, feel free to write to