REST API vs Render Links

REST API vs Render Links

Explaining differences between generating renders using render links and via the REST API

Renders can be generated with Urlbox in two main ways, directly through render links or through calling endpoints on the REST API.

Here we'll call out some of the differences between the two methods.

Render links are a specific URL format that contains your api key, an auth token, an output format followed by a query string of url-encoded options.

The main advantage of using render links is that you can embed them right inside an <img> tag on your page or in an email, or anywhere that an image can be rendered.

Render links are also great for:

  • Embedding screenshots in emails
  • Embedding screenshots in slack messages, tweets, etc.
  • Embedding screenshots in your HTML for example, Open Graph tags.
  • Quick sharing of a urlbox request with all of the options in one string.

The typical workflow is:

  1. The render link is generated on the server using the server side language of your choice. We have example code to help with this step in various languages.
  2. The render link is then embedded in a HTML template (or email template) and sent to the browser.
  3. When the page gets loaded by a users browser..
  4. If the render is already cached in our CDN, it will be returned immediately.
  5. Otherwise, the API will be called and a fresh screenshot or render will be generated.

If you're using a frontend framework such as React, Svelt, Vue or Angular, it's recommended to have a server-side component that generates the render link and passes it back to your frontend, as you don't want to leak your secret key in the browser.

Meta frameworks like Next.js, Remix, Nuxt.js and SvelteKit make adding a server function like this very easy.

Render links are cached for 30 days. This means that if you generate a render link for a given URL and options, the next time you generate a render link for the same URL and options, it will be returned immediately from our cache.

Once the cache expires, the next time the render link is requested, a fresh render will be generated.

Requests to cached render links do not count against your monthly quota.

It's possible to change the duration that we cache the render links for. You can do that by passing in the number of seconds into the ttl option. (ttl stands for time to live and is a common term in caching).

For example, if you wanted to cache the render link for 1 day, you would pass in a ttl of 86400 seconds.

Changing the response type

By default the response type of a render link is going to be the binary data of the render itself, so that an img or meta tag can render it. If you prefer to get a JSON response similar to the REST API, you can pass in the response_type option and set it to json.

Busting the cache

The cache key is based on the query options combined with the format in the render link. The order of query options doesn't matter for caching purposes.

If you want to get up to date screenshots before the cache expires, one way to bust the cache is to use the unique parameter by passing in a unique string, such as a timestamp.

Forcing a fresh screenshot

If you want to force a fresh screenshot, you can pass in the force parameter with a value of true.

We don't recommend using this option when embedding the URL's directly in your HTML as it will cause the screenshot to be regenerated every time the page is loaded.

It's possible to remove a cached render link from our cache by sending a DELETE to the same URL. This will remove it both from our cache and also expire it in cloudflares CDN.

Because the typical use case for render links is to embed them in HTML, if there are two or more requests made for the same combination of options, we will only generate one screenshot and duplicate, in-flight requests will receive a 307 temporary redirect, which will end up receiving the same response as the original request.

Always Synchronous

Render links are always synchronous. You can still use a webhook_url in a render link, but it makes more sense to use them with the asynchronous API.

You can also call the render link with HEAD rather than GET if you just want to generate the render but not download it.

Error handling

Error responses will always be returned in JSON format. When using render links embedded in an image tag, it's more difficult to handle errors as the browser will just display a broken image. If you want to make it easier to handle errors, it's better to use the REST API or call the render link directly using a GET or HEAD request.

Accessing response headers

It's also not easy to access response headers if the render link is embedded in an image tag. If you want to access response headers, it's better to use the REST API or explicitly call the render link with HEAD or GET.

URL length

Because of various limits on URL length, render links are not a great option for rendering from HTML, or when passing options with large payloads, such as custom javascript or css. For these types of requests it's better to use the REST API.


The API is made up of various endpoints that accept a JSON (or form encoded) payload of options that are POSTed to them and returns a JSON response with the URL to the render.

The API is again intended to be used on the server side, as it uses your projects secret key for authentication in the Authorization response header.

One advantage of using the API is that you can pass in larger payloads of options, such as custom javascript, or HTML to render.

Asynchronous or synchronous

Depending on the endpoint you call, the API can be used either synchronously (/v1/render/sync) or asynchronously (/v1/render/async). The synchronous endpoint will return the render in the response, whereas the asynchronous endpoint will return a status URL which can be polled.

Webhooks can also be triggered by passing in a webhook_url option.

Caching of API requests

API requests are not cached, so every request will generate a fresh render.

Deduplication of API requests

Requests through the API endpoints are not deduplicated, so if you make two requests for the same URL with the same options, two renders will be generated.

Response format

The default response is JSON, but you can also request a binary response by passing in the response_type option and setting it to binary.

Response headers

Several useful response headers are returned when calling either sync or async endpoints.