ScreenshotNeo

BlogHow-to

HTMLCSStoImage API Tutorial: Convert a URL to PNG

Convert a public webpage URL to PNG with the HTML/CSS to Image API. Get runnable cURL, Python, and Node.js examples, options, and troubleshooting tips.

By the ScreenshotNeo team4 October 202610 min read

To convert a public webpage URL to PNG with HTML/CSS to Image, send a POST request to https://hcti.io/v1/image, authenticate with HTTP Basic authentication using your API ID as the username and API key as the password, and pass the fully qualified URL in a JSON body. The response contains a generated image URL; PNG is the default format. You can download that image or use its URL in your application. See the vendor’s Using the API guide and example code.

1. Get credentials and protect them

Obtain your API ID and API key from the HTML/CSS to Image dashboard. Keep both values on a server or in a secret manager. Do not put the API key in browser-side JavaScript, a public repository, or a URL that users can inspect. Use credentials limited to the operations your application needs.

The API uses HTTP Basic authentication. In the examples below, credentials are read from environment variables rather than embedded in source code. Set HCTI_API_ID and HCTI_API_KEY in your server environment before running them.

2. Convert a URL to PNG with cURL

curl -X POST 'https://hcti.io/v1/image' \
  -u "$HCTI_API_ID:$HCTI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com"}'

This sends the URL to capture and prints the JSON response, which includes the generated image URL. The URL must be fully qualified, including https:// or http://. Replace https://example.com with a page you are authorized to capture.

To save the response for inspection, redirect it to a file:

curl -sS -X POST 'https://hcti.io/v1/image' \
  -u "$HCTI_API_ID:$HCTI_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"url":"https://example.com"}' \
  -o response.json

Read the image URL from the returned JSON, then make a separate HTTP request to that URL to download the PNG. The generated image URL remains available while the account is active, according to the API guide.

3. Convert a URL to PNG with Python

Install the HTTP client if needed with python -m pip install requests. Save this as capture.py and run it in an environment where the two credential variables are set.

import os
import requests

api_id = os.environ["HCTI_API_ID"]
api_key = os.environ["HCTI_API_KEY"]

response = requests.post(
    "https://hcti.io/v1/image",
    auth=(api_id, api_key),
    json={"url": "https://example.com"},
    timeout=90,
)
response.raise_for_status()

result = response.json()
image_url = result["url"]

image = requests.get(image_url, timeout=90)
image.raise_for_status()
with open("page.png", "wb") as output:
    output.write(image.content)

print(f"Saved page.png from {image_url}")

The generated URL field is used to download the image. If the response shape changes or your account returns additional fields, inspect result and consult the current API documentation. Keep the output filename as .png when using the default output format.

4. Convert a URL to PNG with Node.js

This example uses the built-in fetch API available in current Node.js releases and writes the downloaded image bytes to page.png.

import { writeFile } from "node:fs/promises";

const apiId = process.env.HCTI_API_ID;
const apiKey = process.env.HCTI_API_KEY;
if (!apiId || !apiKey) {
  throw new Error("Set HCTI_API_ID and HCTI_API_KEY in the environment");
}

const credentials = Buffer.from(`${apiId}:${apiKey}`).toString("base64");
const response = await fetch("https://hcti.io/v1/image", {
  method: "POST",
  headers: {
    Authorization: `Basic ${credentials}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com" }),
});

if (!response.ok) {
  throw new Error(`Image API request failed: ${response.status} ${await response.text()}`);
}

const result = await response.json();
if (!result.url) {
  throw new Error("The API response did not contain an image URL");
}

const imageResponse = await fetch(result.url);
if (!imageResponse.ok) {
  throw new Error(`Image download failed: ${imageResponse.status}`);
}
await writeFile("page.png", Buffer.from(await imageResponse.arrayBuffer()));
console.log(`Saved page.png from ${result.url}`);

For older Node.js versions without global fetch, use an HTTP client supported by your runtime. The credential handling principle is unchanged: make the authenticated request from a trusted server.

5. Understand the request and response

  1. Your application sends the authenticated POST request with a URL to capture.
  2. The service renders the page and returns JSON containing a generated image URL.
  3. Your application downloads the image from that URL or passes the URL to a consumer.

There are two different URLs in this flow: the API endpoint that accepts the capture request, and the generated image URL returned by the API. A successful POST does not itself mean the PNG bytes were saved locally; download the returned image URL if you need a local file.

6. Request inputs and rendering options

Input or option Purpose and notes
url Captures a webpage at a fully qualified URL.
html Alternative input for rendering supplied HTML. The API guide treats url and html as alternatives; provide one, not both. When both are passed, the guide says url takes precedence.
css Optional CSS injection when the request uses a URL.
full_screen Requests a capture covering the full URL page height.
device_scale Controls the rendered pixel ratio.
headers Supplies custom request headers for access to pages you are authorized to view. Header forwarding is restricted to the target origin and explicitly allowed additional origins.
block_consent_banners Blocks common consent banners. Check the current parameter reference for its accepted value and any account or plan conditions.
Output format PNG is the default. JPG, WebP, and PDF are also documented; consult the current parameter guide for the supported way to select an output format.
width, height Documented sizing parameters with a maximum of 5000 pixels each.
dpi Documented metadata setting from 30 through 600.

Use the vendor’s parameter reference for exact accepted types, defaults, and current restrictions before adding less common or plan-dependent controls. The examples here deliberately use only the URL input so the basic conversion path is easy to verify.

Full page versus a sized image

Use full_screen when the output should cover the page’s full height. Use width and height controls when you need fixed image dimensions, such as a card preview. Dimensions are capped at 5000 pixels each in the documented guide. A long page can produce a much taller image than a fixed viewport capture, so choose based on the downstream layout and image size you can handle.

Use URL or HTML input, not both

For a live webpage capture, send url. For a rendering task based on HTML you provide, send html. CSS injection is documented for URL captures. Although the guide says URL takes precedence if both are supplied, applications should avoid sending both because it obscures which source is intended.

7. Capture pages that require authentication

The API does not automate an interactive login flow. If you are authorized to access the target page, the vendor documents supplying a short-lived session cookie or authorization token through the headers parameter. Custom headers are limited to the requested URL’s origin and explicitly allowed additional origins. See the API guide for the current request syntax.

  • Prefer short-lived tokens or session cookies over long-lived account credentials.
  • Send only the headers required for the page to render.
  • Do not put broad access tokens in client-visible code, logs, or generated links.
  • Confirm that redirects and any cross-origin resources have the authorization they need; origin restrictions can affect what headers are sent.

8. Signed GET URLs and the POST flow

The standard flow in this tutorial is an authenticated POST that returns a generated image URL. HTML/CSS to Image also documents a GET endpoint that creates and returns an image on demand using a signed URL. The GET signature is an HMAC-SHA-256 hash of the exact encoded query string using the API key.

Approach Rendering and credential handling Use it when
Authenticated POST Server sends HTTP Basic credentials in a request body flow and receives a generated image URL. Your backend should initiate the render and then store or distribute the resulting URL.
Signed GET Server constructs a URL and signs the exact encoded query string. The resulting URL carries a token and can be requested by a browser. A browser needs an on-demand image URL, and your server can safely generate the signature.

Parameter order, encoding, and whitespace affect the signed string. Use an official client helper where possible, and perform signing on the server. Never expose the API key to browser code. Anyone who obtains a completed signed URL can request the image it authorizes, so treat that URL as a capability and avoid sharing it more broadly than intended. See the vendor’s signed URL documentation.

9. Troubleshooting

Symptom Likely cause What to check
Authentication is rejected The API ID or key is wrong, missing, or not being sent as Basic authentication. Check the environment variables and confirm the ID is the username and key is the password. Keep the values out of logs while debugging.
The API rejects the request body Malformed JSON, missing URL, or incompatible inputs. Send valid JSON with a fully qualified url. Use either url or html, not both.
The target page cannot be rendered as expected The URL is inaccessible to the rendering service, requires an interactive login, or depends on credentials that were not provided. Confirm the page is reachable and use authorized, short-lived cookies or authorization headers where supported. The API does not perform an interactive login.
The downloaded file contains JSON or an error page The API response was saved directly as if it were the image, or the generated image URL request failed. Parse the POST response, extract its image URL, then issue a second request and check that response’s status before writing bytes.
PNG output is not the expected size Default rendering dimensions differ from the intended output, or a dimension exceeds a limit. Review width and height settings, use full_screen when appropriate, and keep each documented dimension at or below 5000 pixels.
Custom headers do not reach a resource Header forwarding is restricted by origin. Verify the resource origin and the API’s allowed additional origins configuration. Avoid sending secrets to unrelated origins.
A signed GET URL fails validation The signed text differs from the transmitted query string because of parameter order, encoding, or whitespace. Generate the signature from the exact encoded query string and prefer the vendor’s official helper.
A signed URL works for someone else who obtained it The URL itself authorizes the image request. Limit distribution and avoid putting sensitive capture URLs into public pages, analytics, or logs.

10. Performance, reliability, and cost considerations

  • Account for two network steps. The POST generates the image URL; downloading the PNG is a separate request. Give both steps appropriate timeouts and surface failures separately.
  • Keep outputs manageable. Full-page captures and large dimensions can produce larger files and take more time to transfer and store. Select dimensions and page height to match the use case.
  • Retry carefully. For transient network failures, retry with a bounded policy and backoff. Avoid unbounded retries that can duplicate capture requests or hide persistent authentication and input errors.
  • Handle generated URL availability. The API guide says the generated URL stays available while the account is active. If your application needs durable assets, download and store the resulting image under your own retention policy.
  • Protect credentials and outputs. Keep API secrets server-side. Treat signed URLs as access-bearing links and consider whether screenshots themselves contain private page content.
  • Check current commercial terms. The research material does not establish current request pricing or quotas. Consult the vendor’s account and pricing information before estimating production cost.

11. Skip the browser setup with ScreenshotNeo

If your goal is to capture a webpage without managing rendering infrastructure, ScreenshotNeo provides a website screenshot API and MCP server. Its API accepts one GET request with a URL and returns PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', image));
  • Cookie banners, popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers say which outcome occurred.
  • An MCP server lets Claude, Cursor, and other MCP clients use screenshot tools.
  • 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Every feature is on every plan.

Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.

12. FAQ

Does the API return PNG bytes directly?

The documented POST flow returns a generated image URL in JSON. Make a second request to that URL to download the image bytes.

Can I embed the result in an HTML page?

Yes. The generated image URL can be used as an image source while it remains available. For long-lived use, download and manage a copy according to your application’s needs.

Can I use the API to log in to a site?

No interactive login automation is documented. For pages you are authorized to access, the guide describes passing short-lived session credentials in supported headers.

What output formats are documented?

PNG is the default, and the guide also lists JPG, WebP, and PDF. Check the current parameter reference for the exact format-selection syntax.