ScreenshotNeo

BlogHow-to

How to Set Cookies and Headers in an HTMLCSStoImage API Request

Send cookies and custom headers with HTMLCSStoImage URL screenshots. Learn JSON and form requests, origin controls, subrequests, and safe credential handling.

By the ScreenshotNeo team4 October 20266 min read

To set cookies or custom headers in an HTMLCSStoImage API request, add them to the headers parameter when rendering a URL. In a JSON body, headers is a flat object of header names and string values. In a form request, send one repeated headers field per header as name:value. These headers are for URL screenshots; they do not apply to HTML/CSS or template renders.

The API endpoint is POST https://hcti.io/v1/image. Authenticate with HTTP Basic authentication, using your API ID as the username and API key as the password. Send either url or html to create an image, not both; use url for the cookie and request-header examples below. See the HTMLCSStoImage documentation for the service’s current request details.

JSON request: cookies and headers

Use a flat JSON object. Header names are keys and values are strings. A cookie is sent as the value of the standard Cookie header:

{
  "url": "https://example.com/account",
  "headers": {
    "Cookie": "session=short-lived-session-value",
    "X-Preview-Mode": "enabled"
  }
}

For a bearer token, use the conventional authorization header:

{
  "url": "https://example.com/account",
  "headers": {
    "Authorization": "Bearer short-lived-access-token"
  }
}

Keep the object flat: nested objects and arrays are not supported. Header values must be strings. If you need multiple cookies, format the Cookie value as a semicolon-separated cookie string, for example session=abc; preference=compact.

Runnable examples

cURL with form fields

For form submission, repeat headers once for each header. The service splits each field at its first colon, so colons later in the value are preserved.

curl -X POST https://hcti.io/v1/image \
  -u 'API_ID:API_KEY' \
  --data-urlencode 'url=https://example.com/account' \
  --data-urlencode 'headers=Cookie:session=short-lived-session-value' \
  --data-urlencode 'headers=X-Preview-Mode:enabled'

Replace the example URL and credentials with values for your authorized page and account. --data-urlencode safely encodes form values, including spaces and punctuation.

Python with JSON

import requests

response = requests.post(
    "https://hcti.io/v1/image",
    auth=("API_ID", "API_KEY"),
    json={
        "url": "https://example.com/account",
        "headers": {
            "Cookie": "session=short-lived-session-value",
            "X-Preview-Mode": "enabled",
        },
    },
    timeout=90,
)
response.raise_for_status()

result = response.json()
print(result)

The response contains the image result information. Handle the returned image URL or other response fields according to the API’s response format and your application needs.

Node.js with JSON

const credentials = Buffer.from('API_ID:API_KEY').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/account',
    headers: {
      Cookie: 'session=short-lived-session-value',
      'X-Preview-Mode': 'enabled',
    },
  }),
});

if (!response.ok) {
  throw new Error(`HTMLCSStoImage returned ${response.status}: ${await response.text()}`);
}

const result = await response.json();
console.log(result);

Run this in a server environment. Do not embed the API key in browser JavaScript.

Where custom headers are sent

By default, custom headers accompany the top-level navigation to the requested URL’s origin. An origin consists of the scheme, host, and optional port. For example, https://example.com and http://example.com are different origins, as are https://example.com and https://example.com:8443.

To authorize delivery to another origin, include that exact origin in additional_header_origins. Headers are not sent to CSS, images, JavaScript, and other subrequests unless include_headers_on_subrequests is enabled. When enabled, they apply only to the requested origin and listed additional origins. Leave it disabled when only the main document needs authentication; this reduces the chance of credentials reaching third-party resources or cross-origin redirects.

These are request options alongside url and headers. The exact serialized syntax depends on whether you are sending JSON or form fields; follow the API’s request format when adding them.

Limits and validation

Constraint Documented limit or behavior
Header count Up to 20 custom headers per request
Header names Case-insensitive unique names; up to 512 ASCII characters
Header values Up to 8,192 UTF-8 bytes
Control characters Disallowed except horizontal tab
Restricted fields Hop-by-hop, proxy, forwarding, connection, host, infrastructure-controlled, and certain prefixed headers are restricted

Invalid, duplicated, restricted, or oversized headers produce a request error. Header names are case-insensitive, so Cookie and cookie count as the same name. Avoid adding transport-level fields such as Host or Connection; the service controls those.

Sign-in pages and credential safety

The API does not automate an interactive login flow. If you are authorized to access a page, obtain a short-lived session cookie or authorization token through your normal sign-in process, then pass it in headers. If the page can be embedded in a supported way, that may avoid rendering a signed-in page altogether.

  • Keep API keys and session credentials on your server. Treat an API key like a password and limit its scope to the operations your application needs.
  • Prefer short-lived, narrowly scoped session tokens over long-lived credentials.
  • Do not put secrets in create-and-render URLs. URLs can be recorded in browser history, access logs, analytics, and referrer data.
  • For signed create-and-render URLs, keep signing on the server and never expose the API key in client-side code. Every repeated headers query parameter must be included in the HMAC input in the exact order and encoding used in the URL.

Or skip the browser setup

If you need a screenshot API with cookies and custom headers, ScreenshotNeo accepts them as request options. This runnable cURL example captures a URL and writes a WebP image; see the ScreenshotNeo API documentation for its options.

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

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Add request headers or cookies using the documented API parameters for your use case.

Sign up free for 1,000 screenshots a month, with no card required.

Troubleshooting

Symptom Likely cause What to check
Request is rejected Malformed, duplicate, restricted, or oversized header Use a flat object or repeated form fields, ensure names are unique regardless of case, and check the documented limits.
The page redirects to sign-in Cookie or token is expired, invalid, or scoped to a different host Refresh the credential and verify its domain/path applicability for the requested URL.
Main page loads but an image or script is missing The resource is a subrequest and headers are not included on subrequests Enable include_headers_on_subrequests only when needed, and authorize the exact additional origin.
Credential works on the page origin but not a second host Cross-origin resources do not inherit custom headers by default Add the exact scheme, host, and port to additional_header_origins, then apply the subrequest option if relevant.
Cookie seems ignored Cookie syntax or scope does not match the target page Send a valid Cookie header string and check that the session is still valid for that domain and path.
Signed URL fails after adding a header The signature does not cover all repeated header parameters exactly Regenerate the HMAC server-side using each header parameter in its exact order and encoding.
Interactive sign-in never completes The API renders a request; it does not automate an interactive login flow Authenticate separately and provide an authorized short-lived cookie or token.

Performance, reliability, and cost considerations

Authenticated captures add dependencies: the credential must remain valid, the target must be reachable, and any protected assets on other origins must receive headers only when explicitly authorized. Keep header scope narrow and avoid enabling subrequest propagation without a concrete need. For repeat captures of the same page state, check the service’s cache and request behavior in its documentation; do not assume a cached result reflects a refreshed login state.

Budget around the API plan and your application’s capture volume. Avoid retries that blindly reuse expired credentials or resubmit permanently invalid headers; classify authentication and validation errors first. The cited documentation does not establish a performance benchmark or a fixed capture time, so test latency and failure handling with the pages and credentials your application actually uses.

FAQ

Can I set cookies for an HTML or CSS render?

The documented headers parameter applies to URL screenshots. It is not a mechanism for setting request headers on HTML/CSS or template renders.

Can I send headers to every third-party resource on the page?

Header forwarding is origin-scoped. Add specific authorized origins and enable subrequest inclusion only when needed; do not treat it as a global browser header override.

Can HTMLCSStoImage log in for me?

No. Obtain a valid session through your own authorized login flow and pass a short-lived credential with the URL request.

Does a colon in a form header value break parsing?

The form parser splits at the first colon, so later colons remain part of the value. URL-encode form values when submitting them.