Link Search Menu Expand Document

Single-Request Image Generation

Generate images from HTML/CSS, URLs, or templates in a single request with signed URLs.


Recommendation

We recommend using the standard API endpoint for most use cases. Only use this endpoint if you specifically need to generate image URLs from client-side code or need to avoid the two-step create-then-fetch process.

Publishing social cards?

If each image corresponds to a public page on your website or CMS, an OG Image Config is usually simpler. It maps page paths to stable image URLs and does not require an HMAC token for every page.

Key benefits

This endpoint allows you to generate image URLs that directly render images when accessed:

  • No POST request needed: Generate image URLs client-side without making API calls
  • Client-side friendly: Use signed URLs to keep your API Key secure
  • Simplified workflow: Skip the image creation step and go straight to image rendering
  • 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.

Security note

Never expose your API Key in client-side code. The API ID and generated token are safe to use client-side.

Creating an image

To generate an image with a signed URL, construct a URL with your API ID and token:

  get https://hcti.io/v1/image/create-and-render/:api_id/:token/:format

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

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.

Required params

† Either url OR html is required, but not both. css is optional.


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

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.

  get https://hcti.io/v1/image/:template_id/:token/:format?

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

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%22

The author value decodes to {"name":"Jeff"}. The title value decodes to "Launch".

Use an official client

The TypeScript and .NET clients include signed URL helpers (generateTemplatedImageUrl and CreateTemplatedImageUrl) so you do not need to hand-build the query string or HMAC token.


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:

  1. The message is your query string (without the leading ?), e.g., html=%3Cdiv%3EHello%3C%2Fdiv%3E
  2. The secret key is your API Key
  3. The hash function used is SHA-256
  4. 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

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.

  1. Enter your query string (e.g., html=%3Cdiv%3EHello%3C%2Fdiv%3E) as the String
  2. Enter your API Key as the Secret Key
  3. 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%3E

Examples

Official client helpers

The official clients generate the signed URL for you and keep the API Key on your server.

TypeScript Client

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' }
});

.Net Client

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" }
    });

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 CSS
const params = new URLSearchParams({
  html: '<div>Hello World</div>',
  css: 'div{color:red}'
});
const queryString = params.toString();
const token = generateToken(queryString, apiKey);

// Generate the URL
const imageUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${token}/${format}?${queryString}`;

// Example 2: Using a URL parameter
const urlParams = new URLSearchParams({
  url: 'https://example.com'
});
const urlQueryString = urlParams.toString();
const urlToken = generateToken(urlQueryString, apiKey);

// Generate the URL for website screenshot
const screenshotUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${urlToken}/${format}?${urlQueryString}`;

// Example 3: Using a template
const 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

<?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

When you access a valid signed URL, the API will return the generated image directly with the appropriate content type header (image/png, image/jpeg, or image/webp depending on the format).

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"
}

Need help?

Talk to a human. Please email us support@htmlcsstoimage.com with any questions and we’ll gladly help you get started.


Back to top

Built with extensive integration tests and serious care for developer happiness.
© 2018-2026 Code Happy, LLC.

Page last modified: Aug 21 2026 at 09:53 PM.

Edit this page on GitHub.