Webhooks

Webhooks

Get notified when a screenshot has been rendered.

Webhooks allow your application to receive information when a render, such as a screenshot, has been generated. This allows you to request renders asynchronously.

Using webhooks

Pass a webhook URL in as the webhook_url option and Urlbox will send a POST request to that URL with data about the render once it has completed rendering, or an error has occurred.

curl -X POST \
https://api.urlbox.io/v1/render \
-H 'Authorization: Bearer your-urlbox-secret' \
-H 'Content-Type: application/json' \
-d '{"url":"example.com", "webhook_url":"https://example.com/webhooks/urlbox"}'

This will result in a response like the following being POSTed to https://example.com/webhooks/urlbox once the render is complete:

{
  "event": "render.succeeded",
  "renderId": "19a59ab6-a5aa-4cde-86cb-d2b23302fd84",
  "result": {
    "renderUrl": "https://renders.urlbox.io/urlbox1/renders/6215a3df94d7588f7d910513/2024/1/11/19a59ab6-a5aa-4cde-86cb-d2b23302fd84.png",
    "size": 34097
  },
  "meta": {
    "startTime": "2024-01-11T17:49:18.593Z",
    "endTime": "2024-01-11T17:49:21.103Z"
  }
}

If there is an error during rendering, an example webhook payload will look similar to:

{
  "event": "render.failed",
  "renderId": "30044645-cfa3-45d6-b7c1-3c6dc3272af6",
  "error": {
    "message": "Page returned 400 and fail_on_4xx was true"
  },
  "meta": {
    "startTime": "2024-01-11T22:57:34.265Z",
    "endTime": "2024-01-11T22:57:36.328Z"
  },
}

Webhooks are often used in combination with our S3-compatible storage making it easy for you to gather large numbers of screenshots asynchronously.

Verify Webhook

In order to verify that the webhook is being sent by Urlbox, you can use the X-Urlbox-Signature header sent with the webhook.

You will require your webhook secret, which you can find in the Urlbox dashboard in the project settings.

The webhook signature is sent in the form t={timestamp},sha256={token}.

Your code should extract the timestamp and token values from the received header.

You should then generate a HMAC-SHA256 of the timestamp value appended with a full-stop (period i.e. '.' ), which is then appended to the JSON stringified body of the webhook request body:

{timestamp}.{JSON stringified webhook payload}

Example

For example, let's say the webhook payload you received was:

{
  "event": "render.succeeded",
  "renderId": "e9617143-2a95-4962-9cc9-d72f3c413b9c",
  "result": {
    "renderUrl": "https://renders.urlbox.io/urlbox1/renders/571f54138cd8b877077d3788/2024/1/11/e9617143-2a95-4962-9cc9-d72f3c413b9c.png",
    "size": 359081
  },
  "meta": {
    "startTime": "2024-01-11T23:32:11.908Z",
    "endTime": "2024-01-11T23:33:32.500Z"
  }
}

and the timestamp is 1705016013, then the timestamp value appended with a full-stop (period i.e. '.' ) and with the JSON stringified webhook payload would look like:

let payload = `1705016013.{"event":"render.succeeded","renderId":"e9617143-2a95-4962-9cc9-d72f3c413b9c","result":{"renderUrl":"https://renders.urlbox.io/urlbox1/renders/571f54138cd8b877077d3788/2024/1/11/e9617143-2a95-4962-9cc9-d72f3c413b9c.png","size":359081},"meta":{"startTime":"2024-01-11T23:32:11.908Z","endTime":"2024-01-11T23:33:32.500Z"}}`;

We then create a HMAC-SHA256 token of the above string using your webhook secret as the key:

let ourToken = crypto
  .createHmac("sha256", YOUR_WEBHOOK_SECRET)
  .update(payload)
  .digest("hex");

(This example is using nodejs, but every language will have equivalent functionality to create a HMAC-SHA256 token)

Now we can compare the token we have generated, with the token embedded in the X-Urlbox-Signature header.

If they match, we know that the request has been legitimately sent from Urlbox.

Command Line

If you need a way to test your own token generation code, you can generate a HMAC-SHA256 on the command line with the following command:

echo -n '1705016013.{"event":"render.succeeded","renderId":"e9617143-2a95-4962-9cc9-d72f3c413b9c","result":{"renderUrl":"https://renders.urlbox.io/urlbox1/renders/571f54138cd8b877077d3788/2024/1/11/e9617143-2a95-4962-9cc9-d72f3c413b9c.png","size":359081},"meta":{"startTime":"2024-01-11T23:32:11.908Z","endTime":"2024-01-11T23:33:32.500Z"}}' | openssl dgst -sha256 -hmac 'your_webhook_secret'
 
> SHA2-256(stdin)= 861986740b3b3c8afee299afe74ff7a6249271c776b3efe5b5fd184201f1a07e

This token would match the X-Urlbox-Signature header's token:

X-Urlbox-Signature: t=1705016013,sha256=861986740b3b3c8afee299afe74ff7a6249271c776b3efe5b5fd184201f1a07e