- Docs
- Getting started
- Signed image URLs
Signed image URLs
Generate images from HTML/CSS, URLs, or templates in a single request with signed URLs.
Key benefits
Section titled “Key benefits”This endpoint allows you to generate image URLs that directly render images when accessed:
- No POST request needed: Generate signed URLs locally on your server or during a build, without an API call
- Browser-ready URLs: Embed the finished URL without exposing your API Key
- On-demand rendering: The first image request triggers generation
- Template ready: Create reusable signed image URLs from template values
Unlike the standard endpoint that requires a POST request followed by using the returned URL, this endpoint lets you construct a signed URL that will generate and return the image when accessed.
Each API key has an associated API ID (public) and API Key (secret). The token is generated by creating an HMAC SHA256 hash of the query string (without the ?) using your API Key as the secret. For HTML/CSS and URL renders, the signed URL includes your API ID. For templated image URLs, the signed URL uses the template_id instead.
Creating an image
Section titled “Creating an image”To generate an image with a signed URL, construct a URL with your API ID and token:
https://hcti.io/v1/image/create-and-render/:api_id/:token/:formatURL components
Section titled “URL components”| Component | Description |
|---|---|
api_id |
Your public API ID from the dashboard |
token |
HMAC SHA256 hash of the query string using your API Key (see below for how to generate) |
format |
Optional file format: png (default), jpg, webp, or pdf |
Parameters
Section titled “Parameters”The parameters are the same as the standard API endpoint, but they must be passed as query parameters in the URL.
| Name | Type | Description |
|---|---|---|
html† |
String |
This is the HTML you want to render. You can send an HTML snippet (<div>Your content</div>) or an entire webpage. |
css |
String |
The CSS for your image. When using with url it will be injected into the page. |
url† |
String |
The fully qualified URL to a public webpage. When passed this will override the html param and will generate a screenshot of the url. |
Additional parameters
Section titled “Additional parameters”Optional parameters for greater control over your image.
| Name | Type | Description |
|---|---|---|
additional_header_origins | Array | Allow custom headers on requests to specific additional HTTP or HTTPS origins. |
block_consent_banners | Boolean | When set to true, automatically blocks cookie consent banners and popups on websites. Most useful for URL screenshots. |
color_scheme | String | Set Chrome to render in light or dark mode. Affects websites using prefers-color-scheme. |
device_scale | Double | Control resolution by adjusting the pixel ratio from 0.1 to 3. Higher values increase image quality and file size. |
disable_twemoji | Boolean | Set to true to use native emoji fonts instead of Twemoji. |
full_screen | Boolean | Generate an image of the entire height of a URL page. |
google_fonts | String | Load one or more Google fonts, such as Roboto|Open Sans. |
headers | Object | Add custom HTTP headers when screenshotting a URL. Headers are restricted to the requested URL's origin and any additional_header_origins. |
identify_as_hcti | Boolean | Add X-HCTI-SCREENSHOT: 1 to the top-level request when screenshotting a URL. |
include_headers_on_subrequests | Boolean | Also add custom headers to same-origin subrequests and subrequests matching additional_header_origins. |
jumbo_max_height | Integer | Maximum output height in jumbo mode, up to 80,000 pixels. Must be set with jumbo_max_width and consumes additional image credits. |
jumbo_max_width | Integer | Maximum output width in jumbo mode, up to 80,000 pixels. Must be set with jumbo_max_height and consumes additional image credits. |
max_wait_ms | Integer | Set a maximum time limit from 500 to 10000 milliseconds for waiting before taking the screenshot. |
media_type | String | Set Chrome to render using screen or print CSS media styles. |
ms_delay | Integer | Delay before generating the image. Useful when waiting for JavaScript; start with 500 milliseconds. |
proxy_id | String | Route outbound traffic through one of your organization's configured HTTP proxies. Available on the 10,000 images/month plan or higher. |
render_when_ready | Boolean | Wait to generate the image until JavaScript calls ScreenshotReady(). |
selector | String | Crop the image to an element matching this CSS selector, such as section#complete-toolkit.container-lg. |
storage_destination_id | String | Save rendered files to one of your organization's configured storage destinations. Available on the 10,000 images/month plan or higher. |
timezone | String | Set Chrome's timezone with an IANA identifier such as America/New_York. |
transparent_background | Boolean | Set to true to render with a transparent background. |
viewport_height | Integer | Set the height of Chrome's viewport. Both dimensions must be set when using either. |
viewport_landscape | Boolean | Set Chrome's viewport to landscape mode. |
viewport_mobile | Boolean | Set Chrome's viewport to emulate a mobile device. |
viewport_touch | Boolean | Set Chrome's viewport to support touch events. |
viewport_width | Integer | Set the width of Chrome's viewport. Both dimensions must be set when using either. |
Creating a templated image URL
Section titled “Creating a templated image URL”To generate an image from a template with a signed URL, construct a URL with your template_id and token. You do not need to include your API ID in the path.
https://hcti.io/v1/image/:template_id/:token/:formatURL components
Section titled “URL components”| Component | Description |
|---|---|
template_id |
The template ID returned by the template API |
token |
HMAC SHA256 hash of the query string using your API Key |
format |
Optional file format: png (default), jpg, webp, or pdf. |
Parameters
Section titled “Parameters”Template values are passed as query string parameters. Each query parameter name maps to a variable in your template.
| Name | Type | Description |
|---|---|---|
template values |
String, Number, Boolean, or JSON |
Values for the variables in your template. For editor templates, see the Variables guide. |
template_version |
Integer |
Optional. Render a specific version of the template. Include this in the query string before generating the token. |
Nested objects and arrays should be serialized as JSON and URL encoded. The token must be generated from the exact encoded query string you put after ?.
For example, these template values:
{ "title": "Launch", "author": { "name": "Jeff" }}Could be encoded as:
author=%7B%22name%22%3A%22Jeff%22%7D&title=%22Launch%22The author value decodes to {"name":"Jeff"}. The title value decodes to "Launch".
Understanding HMAC authentication
Section titled “Understanding HMAC authentication”HMAC (Hash-based Message Authentication Code) is a mechanism for calculating a message authentication code involving a hash function in combination with a secret key. In this API:
- The message is your query string (without the leading
?), e.g.,html=%3Cdiv%3EHello%3C%2Fdiv%3E - The secret key is your API Key
- The hash function used is SHA-256
- The resulting token is used in the URL path to authenticate the request
This allows you to create signed URLs without exposing your API Key. If any part of the query string is changed without updating the token, the URL will be invalid. Query parameter order, encoding style, and whitespace all matter because the token is based on the exact query string.
Testing token generation online
Section titled “Testing token generation online”Use our HMAC SHA-256 Generator to test token generation. It runs entirely in your browser; your API key and query string are never sent to our servers.
- Enter your query string (e.g.,
html=%3Cdiv%3EHello%3C%2Fdiv%3E) as the String - Enter your API Key as the Secret Key
- Copy the generated lowercase hexadecimal token
For example:
- Input String:
html=%3Cdiv%3EHello%3C%2Fdiv%3E - Secret Key:
your-api-key-here - Computed MAC:
ac5553c5a9031e09f4580101080045e7e4cbd1734aa1b53a94f1006c3496ca21
Your final URL would be:
https://hcti.io/v1/image/create-and-render/your-api-id-here/ac5553c5a9031e09f4580101080045e7e4cbd1734aa1b53a94f1006c3496ca21/png?html=%3Cdiv%3EHello%3C%2Fdiv%3EExamples
Section titled “Examples”Official client helpers
Section titled “Official client helpers”The official clients generate the signed URL for you and keep the API Key on your server.
import { HtmlCssToImageClient } from '@html-css-to-image/client';
const client = HtmlCssToImageClient.fromEnv();
const imageUrl = client.generateTemplatedImageUrl('t-b0354248-e7f6-4cca-81c6-2b4a70a16388', { title: 'Launch', author: { name: 'Avery' }});using HtmlCssToImage;using HtmlCssToImage.Models;
var client = new HtmlCssToImageClient( new HttpClient(), new HtmlCssToImageOptions { ApiId = "your-api-id", ApiKey = "your-api-key" });
var imageUrl = client.CreateTemplatedImageUrl( "t-b0354248-e7f6-4cca-81c6-2b4a70a16388", new { title = "Launch", author = new { name = "Avery" } });from html_css_to_image import HtmlCssToImageClient
with HtmlCssToImageClient.from_env() as client: image_url = client.generate_templated_image_url_from_values( "t-b0354248-e7f6-4cca-81c6-2b4a70a16388", { "title": "Launch", "author": {"name": "Avery"}, }, )use HtmlCssToImage\HtmlCssToImageClient;
$client = HtmlCssToImageClient::fromEnvironment();
$imageUrl = $client->generateTemplatedImageUrlFromValues( 't-b0354248-e7f6-4cca-81c6-2b4a70a16388', [ 'title' => 'Launch', 'author' => ['name' => 'Avery'], ],);JavaScript example
Section titled “JavaScript example”const crypto = require('crypto');
function generateToken(queryString, apiKey) { return crypto .createHmac('sha256', apiKey) .update(queryString) .digest('hex');}
const apiId = 'your_api_id_here';const apiKey = 'your_api_key_here';const format = 'png';
// Example 1: Using HTML and CSSconst params = new URLSearchParams({ html: '<div>Hello World</div>', css: 'div{color:red}'});const queryString = params.toString();const token = generateToken(queryString, apiKey);
// Generate the URLconst imageUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${token}/${format}?${queryString}`;
// Example 2: Using a URL parameterconst urlParams = new URLSearchParams({ url: 'https://example.com'});const urlQueryString = urlParams.toString();const urlToken = generateToken(urlQueryString, apiKey);
// Generate the URL for website screenshotconst screenshotUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${urlToken}/${format}?${urlQueryString}`;
// Example 3: Using a templateconst templateId = 't-b0354248-e7f6-4cca-81c6-2b4a70a16388';const templateValues = { title: 'Launch', author: { name: 'Avery' }};
const templateParams = new URLSearchParams();Object.keys(templateValues) .sort() .forEach((key) => { templateParams.append(key, JSON.stringify(templateValues[key])); });
const templateQueryString = templateParams.toString();const templateToken = generateToken(templateQueryString, apiKey);const templatedImageUrl = `https://hcti.io/v1/image/${templateId}/${templateToken}/${format}?${templateQueryString}`;
// Now these URLs can be used directly in an <img> tag or as a link// <img src="imageUrl" alt="Generated image" />PHP example
Section titled “PHP example”<?php$apiId = 'your_api_id_here';$apiKey = 'your_api_key_here';$format = 'png';
// Example 1: Using HTML and CSS// Create query string$html = '<div>Hello from PHP</div>';$css = 'div{color:blue;font-family:Arial}';$queryString = http_build_query([ 'html' => $html, 'css' => $css,], '', '&', PHP_QUERY_RFC3986);
// Generate token$token = hash_hmac('sha256', $queryString, $apiKey);
// Generate the URL$imageUrl = "https://hcti.io/v1/image/create-and-render/$apiId/$token/$format?$queryString";echo "Generated image URL: $imageUrl\n";
// Example 2: Using a URL parameter$websiteUrl = 'https://example.com';$urlQueryString = http_build_query([ 'url' => $websiteUrl,], '', '&', PHP_QUERY_RFC3986);$urlToken = hash_hmac('sha256', $urlQueryString, $apiKey);
// Generate the URL for website screenshot$screenshotUrl = "https://hcti.io/v1/image/create-and-render/$apiId/$urlToken/$format?$urlQueryString";echo "Screenshot URL: $screenshotUrl\n";
// Example 3: Using a template$templateId = 't-b0354248-e7f6-4cca-81c6-2b4a70a16388';$templateValues = [ 'title' => 'Launch', 'author' => ['name' => 'Avery'],];ksort($templateValues);
$templateParams = [];foreach ($templateValues as $key => $value) { $templateParams[$key] = json_encode($value);}
$templateQueryString = http_build_query($templateParams, '', '&', PHP_QUERY_RFC3986);$templateToken = hash_hmac('sha256', $templateQueryString, $apiKey);$templatedImageUrl = "https://hcti.io/v1/image/$templateId/$templateToken/$format?$templateQueryString";echo "Templated image URL: $templatedImageUrl\n";
// Use the URLs directly in your HTML// echo '<img src="' . htmlspecialchars($imageUrl) . '" alt="Generated image">';Example response
Section titled “Example response”When you access a valid signed URL, the API returns the generated file directly with the appropriate content type: image/png, image/jpeg, image/webp, or application/pdf.
If there’s an error, you’ll receive a JSON response:
STATUS: 400 BAD REQUEST{ "error": "Bad Request", "statusCode": 400, "message": "HTML is Required"}STATUS: 401 UNAUTHORIZED{ "error": "Unauthorized", "statusCode": 401, "message": "Invalid token"}The signing key must be enabled and grant images:create. See API key management when replacing or disabling signing credentials.
Need help?
Talk to a human. Email support@htmlcsstoimage.com and we’ll help you get started.