HTML-to-Image API for Restaurant Menu Thumbnails in India
Build consistent restaurant menu thumbnails from HTML and CSS. Learn the HCTI workflow, India-specific checks, production safeguards, and a ScreenshotNeo option for webpage captures.
An HTML-to-image API renders an HTML/CSS design into an image. For restaurant menu thumbnails, your application supplies the menu data and a template; the API renders the result. HCTI documents a create-image endpoint that accepts HTML or a public webpage URL, optional CSS, and rendering controls, and returns a generated image URL. It does not provide a documented restaurant-specific input format or automatic menu layout. HCTI API documentation.
This guide shows a practical integration pattern and what to verify before deploying it for Indian customers. The code examples use environment variables for credentials; replace the sample markup and dimensions with your own design and destination requirements.
1. Design the menu thumbnail
Start by deciding where the image will appear and what that destination expects: aspect ratio, dimensions, file type, background, and any file-size constraints. Create an HTML card for one menu item or a small group of items. Supply the content yourself, including the dish name, price, optional description, dietary labels, and image URL.
Build the template to tolerate real menu data. Long dish names should wrap or shrink within a defined limit; prices should remain legible; missing photos should fall back to a designed placeholder. Consider language and script choices, including the fonts needed for the languages you serve. These are design requirements to validate with your own data, not menu-specific capabilities claimed by HCTI.
<article class="menu-card">
<img class="dish-photo" src="https://example.com/images/thali.jpg" alt="">
<div class="menu-copy">
<p class="label">HOUSE SPECIAL</p>
<h1>Paneer tikka thali</h1>
<p class="description">Paneer, rice, dal, salad and bread</p>
<p class="price">₹320</p>
</div>
</article>
* { box-sizing: border-box; }
html, body { margin: 0; width: 800px; height: 450px; }
body { font-family: Arial, sans-serif; background: #f4efe6; color: #241c16; }
.menu-card { display: flex; width: 800px; height: 450px; padding: 24px; gap: 24px; }
.dish-photo { width: 360px; height: 402px; object-fit: cover; border-radius: 18px; }
.menu-copy { min-width: 0; display: flex; flex: 1; flex-direction: column; }
.label { font-size: 14px; font-weight: 700; letter-spacing: .12em; color: #8d432c; }
h1 { margin: 18px 0 10px; font-size: 42px; line-height: 1.08; overflow-wrap: anywhere; }
.description { font-size: 20px; line-height: 1.35; }
.price { margin-top: auto; font-size: 34px; font-weight: 700; }
The sample is illustrative HTML/CSS, not a tested HCTI template. Validate fonts, image loading, line wrapping, and the final cropped result for representative menu entries before using it at scale.
2. Create an image with HCTI
HCTI documents POST https://hcti.io/v1/image. Authenticate with HTTP Basic authentication: use the API ID as the username and API key as the password. Treat the key like a password, keep it on your server, and grant only the permissions required for the operation. The documented request accepts an HTML snippet or document, or a fully qualified public URL; CSS is optional. Its docs also list output format, viewport dimensions, device scale, Google Fonts, render delay, transparency, media type, and selector-based cropping controls.
cURL
export HCTI_USER_ID="YOUR_API_ID"
export HCTI_API_KEY="YOUR_API_KEY"
curl --fail-with-body --user "$HCTI_USER_ID:$HCTI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"html":"<div style=\"width:800px;height:450px;background:#f4efe6;padding:32px;font:32px Arial\">Paneer tikka thali — ₹320</div>","css":"body{margin:0}","viewport_width":800,"viewport_height":450,"device_scale":1,"format":"png"}' \
https://hcti.io/v1/image
The documented workflow returns a generated image URL in the API response. This command prints that response; parse its URL field in your application and download the image if your workflow needs a local file or object-storage upload. Confirm the precise parameter names and response schema against the current provider documentation before shipping.
Python
import os
import requests
user_id = os.environ["HCTI_USER_ID"]
api_key = os.environ["HCTI_API_KEY"]
payload = {
"html": "<div style='width:800px;height:450px;background:#f4efe6;padding:32px;font:32px Arial'>Paneer tikka thali — ₹320</div>",
"css": "body{margin:0}",
"viewport_width": 800,
"viewport_height": 450,
"device_scale": 1,
"format": "png",
}
response = requests.post(
"https://hcti.io/v1/image",
auth=(user_id, api_key),
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json()) # Read the generated image URL from the response.
Node.js
const userId = process.env.HCTI_USER_ID;
const apiKey = process.env.HCTI_API_KEY;
if (!userId || !apiKey) throw new Error('Set HCTI_USER_ID and HCTI_API_KEY');
const html = "<div style='width:800px;height:450px;background:#f4efe6;padding:32px;font:32px Arial'>Paneer tikka thali — ₹320</div>";
const auth = Buffer.from(`${userId}:${apiKey}`).toString('base64');
const response = await fetch('https://hcti.io/v1/image', {
method: 'POST',
headers: { 'Authorization': `Basic ${auth}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
html,
css: 'body{margin:0}',
viewport_width: 800,
viewport_height: 450,
device_scale: 1,
format: 'png'
})
});
if (!response.ok) throw new Error(`HCTI request failed: ${response.status} ${await response.text()}`);
console.log(await response.json()); // Read the generated image URL from the response.
3. Choose output and rendering controls
| Need | Control to investigate | Implementation note |
|---|---|---|
| Image format | PNG, JPG, WebP, or PDF | Choose against the consuming app’s accepted formats and your quality and size needs. |
| Consistent card size | Viewport width and height | Set the viewport to the designed card dimensions, then verify the resulting crop. |
| Sharper output | Device scale | Higher scale can affect quality and file size. The reviewed documentation provides the control, but no comparative benchmark. |
| Remote fonts | Google Fonts | Use fonts with the required glyph coverage and allow time for remote font loading. |
| Late-loading content | Render delay | Use a delay only when content needs time to load; measure the added latency in your own workflow. |
| Transparent card | Transparent background | Check the destination’s support for transparency and choose a compatible format. |
| Specific section of a page | Selector-based cropping | Useful when rendering a public page with a target element, rather than a self-contained card. |
| Print output | Use only when the consumer needs a document rather than a thumbnail image. |
HCTI’s docs overview also describes reusable templates with variable text, images, and data, and lists a batch templated-images update dated October 2, 2026. This makes template reuse worth evaluating when generating many menu variants. The update does not establish throughput, pricing, or suitability for a particular workload; verify those directly.
4. Build a production workflow
- Keep credentials server-side. Do not put the API ID and key in browser code, a mobile app bundle, or public repository. Read them from a secret store or protected environment variables.
- Validate menu input. Check required fields and constrain user-provided content. Escape values when interpolating them into HTML to prevent markup injection. Prefer generating markup from structured data over accepting arbitrary HTML from end users.
- Render representative cases. Include long and short names, missing descriptions, varied prices, special characters, each language/script, absent photos, and slow or unreachable image hosts.
- Handle the response explicitly. Check the HTTP status, parse the documented response, and handle a missing or unusable image URL. If downloading the generated image, validate the download response before storing it.
- Store and serve thoughtfully. Persist the generated asset in your own storage if you need predictable retention or delivery. Use deterministic keys or content hashes where appropriate so unchanged menu content need not be regenerated by your own application.
- Record operational details. Track request outcome, duration, format, dimensions, and a non-sensitive menu identifier. Never log credentials or private customer data unnecessarily.
5. India-specific checks before launch
The reviewed HCTI documentation explains how to call the rendering API but does not establish India-specific pricing, tax treatment, latency from Indian hosting regions, processing or retention location, support arrangements, or availability for Indian customers. Confirm each point with the provider before choosing a production plan.
- Ask whether your account and payment method are supported in India, and confirm current prices, taxes, billing currency, and invoice requirements.
- Measure end-to-end latency from the region where your application runs. Include HTML rendering, external font/photo fetches, response handling, and any later image download.
- Review what content is sent to the API, how long request data and generated images are retained, and where processing occurs.
- Confirm documented request limits, concurrency expectations, retries, and support response arrangements for your plan.
- Check that the destination platform permits your chosen dimensions, format, and image delivery method.
6. Reliability, performance, and cost
No performance benchmark or pricing terms for this particular workload were established by the reviewed documentation. Estimate cost from the provider’s current plan and your actual number of distinct renders, then test a representative batch from your deployment region. Include retries and re-renders in the estimate, and verify billing rules and taxes with the provider.
Rendering time can depend on template complexity and external resources such as photos and fonts. For more predictable rendering, minimize dependencies, use appropriately sized assets, avoid unnecessary scripts, and set a deliberate viewport. A longer render delay may accommodate slow content but also adds waiting time. Device scale can increase output size. These are engineering considerations to measure on your own workload, not provider benchmark claims.
Make retries bounded and selective: retry transient network failures or server errors with backoff, but do not repeatedly retry malformed input or authentication failures. If a request times out, avoid blindly issuing duplicate renders unless you can tolerate duplicate work; the reviewed material does not establish an idempotency mechanism. Keep a queue for bulk menu refreshes, cap concurrency according to the provider’s confirmed limits, and retain the last valid thumbnail until a replacement succeeds.
7. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| 401 or 403 response | Incorrect API ID/key, missing credentials, or insufficient permissions | Check the Basic-auth username and password, confirm the active key and its allowed operations, and keep secrets out of client code. |
| Request rejected | Malformed JSON, unsupported parameter, or invalid HTML payload | Read the response body, compare fields with the current API docs, and reduce the request to a minimal valid card. |
| Image is blank or incomplete | Content or remote assets were not ready when capture began, or markup did not produce visible content | Check the HTML and external asset accessibility; investigate the documented delay control and retest. |
| Photo or font missing | Remote URL is inaccessible to the renderer, URL is wrong, or font loading is incomplete | Use an accessible fully qualified asset URL, check response/access restrictions, and verify font support and render timing. |
| Text is clipped | Content exceeds the template’s space or viewport/crop is wrong | Test long names, revise wrapping or line limits, and inspect viewport and selector-crop settings. |
| Unexpected image dimensions | Viewport, device scale, or crop settings differ from the design assumptions | Set explicit dimensions and scale, then inspect the actual generated file and adjust the layout. |
| Slow requests | Complex HTML, external resources, or render delay | Measure with and without remote dependencies, reduce unnecessary content, and confirm service limits and expected latency with the provider. |
| Works locally but fails in production | Credentials or asset URLs differ, network access is restricted, or production input contains edge cases | Compare safe request metadata, validate production URLs, and reproduce with a representative payload without exposing secrets. |
8. Or skip the browser setup
If the input is already a public webpage and you need a screenshot of it, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. Its API captures a URL with one GET request; it is for webpage screenshots, rather than a menu-specific HTML template renderer. 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)
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}`);
For the target page, replace https://stripe.com with your public menu URL. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; 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. Sign up for 1,000 free screenshots a month.
9. FAQ
Does the API automatically understand restaurant menus?
The documented workflow renders supplied HTML/CSS or a public URL. You provide the menu content and layout.
Can I use it for a menu with multiple languages?
Potentially, but test your chosen fonts and actual scripts, glyphs, line lengths, and prices in the generated image before launch.
Is HCTI’s batch template update proof it will handle my volume?
No. The overview lists a batch templated-images update, but it does not establish throughput or suitability. Confirm limits and benchmark your own workload.
What should I compare when choosing a provider?
Compare template/data support, output controls, credential handling, measured latency and throughput, India billing and taxes, data retention and processing location, rate limits, and support. Several of those India-specific details require direct provider confirmation.


