|
| 1 | +--- |
| 2 | +layout: page |
| 3 | +title: Single-Request Image Generation |
| 4 | +permalink: /getting-started/create-and-render/ |
| 5 | +parent: Getting started |
| 6 | +nav_order: 6 |
| 7 | +--- |
| 8 | +# Single-Request Image Generation |
| 9 | +{: .no_toc } |
| 10 | +{: .fs-9 } |
| 11 | + |
| 12 | +Generate images from HTML/CSS in a single request with signed URLs. |
| 13 | +{: .fs-6 .fw-300 } |
| 14 | + |
| 15 | +<hr> |
| 16 | + |
| 17 | +Table of contents |
| 18 | +{: .text-delta } |
| 19 | +- TOC |
| 20 | +{:toc} |
| 21 | + |
| 22 | +<hr> |
| 23 | + |
| 24 | +{% include hint.md title="Recommendation" text="We recommend using the [standard API endpoint](/getting-started/using-the-api/) 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." %} |
| 25 | + |
| 26 | +## Key benefits |
| 27 | + |
| 28 | +This endpoint allows you to generate image URLs that directly render images when accessed: |
| 29 | + |
| 30 | +- **No POST request needed**: Generate image URLs client-side without making API calls |
| 31 | +- **Client-side friendly**: Use signed URLs to keep your API Key secure |
| 32 | +- **Simplified workflow**: Skip the image creation step and go straight to image rendering |
| 33 | + |
| 34 | +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. |
| 35 | + |
| 36 | +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. |
| 37 | + |
| 38 | +{% include hint.md title="Security note" text="Never expose your API Key in client-side code. The API ID and generated token are safe to use client-side." %} |
| 39 | + |
| 40 | +## Creating an image |
| 41 | + |
| 42 | +To generate an image with a signed URL, construct a URL with your API ID and token: |
| 43 | + |
| 44 | +<pre class="http-method fs-4"> |
| 45 | + <span>get</span> https://hcti.io<b>/v1/image/create-and-render/:api_id/:token/:format</b> |
| 46 | +</pre> |
| 47 | + |
| 48 | +### URL Components |
| 49 | + |
| 50 | +| Component | Description | |
| 51 | +|:-------------|:------------------| |
| 52 | +| **api_id** | Your public API ID from the dashboard | |
| 53 | +| **token** | HMAC SHA256 hash of the query string using your API Key (see below for how to generate) | |
| 54 | +| **format** | Optional file format: `png` (default), `jpg`, or `webp` | |
| 55 | + |
| 56 | +### Parameters |
| 57 | + |
| 58 | +The parameters are the same as the [standard API endpoint](/getting-started/using-the-api/#parameters), but they must be passed as query parameters in the URL. |
| 59 | + |
| 60 | +| Name | Type | Description | |
| 61 | +|:-------------|:------------------|:------| |
| 62 | +| **html**† | `String` | This is the HTML you want to render. You can send an HTML snippet \(`<div>Your content</div>`\) or an entire webpage. | |
| 63 | +| **css** | `String` | The CSS for your image. When using with `url` it will be injected into the page. | |
| 64 | +| **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. | |
| 65 | + |
| 66 | +{% include hint.md title="Required params" text="† Either `url` OR `html` is required, but not both. `css` is optional." %} |
| 67 | + |
| 68 | +<hr> |
| 69 | + |
| 70 | +### Additional parameters |
| 71 | + |
| 72 | +Optional parameters for greater control over your image. |
| 73 | + |
| 74 | +{% include additional_parameters.md %} |
| 75 | + |
| 76 | +<hr> |
| 77 | + |
| 78 | +### Understanding HMAC authentication |
| 79 | + |
| 80 | +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: |
| 81 | + |
| 82 | +1. The **message** is your query string (without the leading `?`), e.g., `html=<div>Hello</div>&css=div{color:red}` |
| 83 | +2. The **secret key** is your API Key |
| 84 | +3. The **hash function** used is SHA-256 |
| 85 | +4. The resulting **token** is used in the URL path to authenticate the request |
| 86 | + |
| 87 | +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. |
| 88 | + |
| 89 | +### Testing token generation online |
| 90 | + |
| 91 | +You can test token generation using online tools like [FreeFormatter's HMAC Generator](https://www.freeformatter.com/hmac-generator.html): |
| 92 | + |
| 93 | +1. Enter your query string (e.g., `html=<div>Hello</div>`) as the **String** |
| 94 | +2. Enter your API Key as the **Secret Key** |
| 95 | +3. The **Computed MAC** in lowercase hex format is your token |
| 96 | + |
| 97 | +For example: |
| 98 | +- Input String: `html=<div>Hello</div>` |
| 99 | +- Secret Key: `your-api-key-here` |
| 100 | +- Computed MAC: `a659c427bc8eb94c32a3ca9cf92a1ad873da2b36be436f3084b8b76eaa6e7b65` |
| 101 | + |
| 102 | +Your final URL would be: |
| 103 | +``` |
| 104 | +https://hcti.io/v1/image/create-and-render/your-api-id-here/a659c427bc8eb94c32a3ca9cf92a1ad873da2b36be436f3084b8b76eaa6e7b65/png?html=<div>Hello</div> |
| 105 | +``` |
| 106 | + |
| 107 | +### JavaScript example |
| 108 | + |
| 109 | +```javascript |
| 110 | +const crypto = require('crypto'); |
| 111 | + |
| 112 | +function generateToken(queryString, apiKey) { |
| 113 | + return crypto |
| 114 | + .createHmac('sha256', apiKey) |
| 115 | + .update(queryString) |
| 116 | + .digest('hex'); |
| 117 | +} |
| 118 | + |
| 119 | +// Example 1: Using HTML and CSS |
| 120 | +const apiId = 'your_api_id_here'; |
| 121 | +const apiKey = 'your_api_key_here'; |
| 122 | +const format = 'png'; |
| 123 | +const queryString = 'html=<div>Hello World</div>&css=div{color:red}'; |
| 124 | +const token = generateToken(queryString, apiKey); |
| 125 | + |
| 126 | +// Generate the URL |
| 127 | +const imageUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${token}/${format}?${queryString}`; |
| 128 | + |
| 129 | +// Example 2: Using a URL parameter |
| 130 | +const websiteUrl = 'https://example.com'; |
| 131 | +const encodedUrl = encodeURIComponent(websiteUrl); |
| 132 | +const urlQueryString = `url=${encodedUrl}`; |
| 133 | +const urlToken = generateToken(urlQueryString, apiKey); |
| 134 | + |
| 135 | +// Generate the URL for website screenshot |
| 136 | +const screenshotUrl = `https://hcti.io/v1/image/create-and-render/${apiId}/${urlToken}/${format}?${urlQueryString}`; |
| 137 | + |
| 138 | +// Now these URLs can be used directly in an <img> tag or as a link |
| 139 | +// <img src="imageUrl" alt="Generated image" /> |
| 140 | +``` |
| 141 | + |
| 142 | +### PHP example |
| 143 | + |
| 144 | +```php |
| 145 | +<?php |
| 146 | +// Example 1: Using HTML and CSS |
| 147 | +$apiId = 'your_api_id_here'; |
| 148 | +$apiKey = 'your_api_key_here'; |
| 149 | +$format = 'png'; |
| 150 | + |
| 151 | +// Create query string |
| 152 | +$html = '<div>Hello from PHP</div>'; |
| 153 | +$css = 'div{color:blue;font-family:Arial}'; |
| 154 | +$queryString = 'html=' . urlencode($html) . '&css=' . urlencode($css); |
| 155 | + |
| 156 | +// Generate token |
| 157 | +$token = hash_hmac('sha256', $queryString, $apiKey); |
| 158 | + |
| 159 | +// Generate the URL |
| 160 | +$imageUrl = "https://hcti.io/v1/image/create-and-render/$apiId/$token/$format?$queryString"; |
| 161 | +echo "Generated image URL: $imageUrl\n"; |
| 162 | + |
| 163 | +// Example 2: Using a URL parameter |
| 164 | +$websiteUrl = 'https://example.com'; |
| 165 | +$urlQueryString = 'url=' . urlencode($websiteUrl); |
| 166 | +$urlToken = hash_hmac('sha256', $urlQueryString, $apiKey); |
| 167 | + |
| 168 | +// Generate the URL for website screenshot |
| 169 | +$screenshotUrl = "https://hcti.io/v1/image/create-and-render/$apiId/$urlToken/$format?$urlQueryString"; |
| 170 | +echo "Screenshot URL: $screenshotUrl\n"; |
| 171 | + |
| 172 | +// Use the URLs directly in your HTML |
| 173 | +// echo '<img src="' . htmlspecialchars($imageUrl) . '" alt="Generated image">'; |
| 174 | +``` |
| 175 | + |
| 176 | +<hr> |
| 177 | + |
| 178 | +### Example response |
| 179 | + |
| 180 | +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). |
| 181 | + |
| 182 | +If there's an error, you'll receive a JSON response: |
| 183 | + |
| 184 | +``` |
| 185 | +STATUS: 400 BAD REQUEST |
| 186 | +``` |
| 187 | + |
| 188 | +```javascript |
| 189 | +{ |
| 190 | + "error": "Bad Request", |
| 191 | + "statusCode": 400, |
| 192 | + "message": "HTML is Required" |
| 193 | +} |
| 194 | +``` |
| 195 | + |
| 196 | +``` |
| 197 | +STATUS: 401 UNAUTHORIZED |
| 198 | +``` |
| 199 | + |
| 200 | +```javascript |
| 201 | +{ |
| 202 | + "error": "Unauthorized", |
| 203 | + "statusCode": 401, |
| 204 | + "message": "Invalid token" |
| 205 | +} |
| 206 | +``` |
| 207 | + |
| 208 | +{% include code_footer.md version=1 %} |
0 commit comments