Render API
GET /api/prerender/render#
Render a JavaScript page into static HTML. Returns rendered HTML (200) or a passthrough instruction (304 + Location) when prerendering does not apply.
Query Parameters#
| Parameter | Type | Description |
|---|---|---|
url (required) |
string | URL-encoded target page to render. Must be a valid URL. |
cache_invalidate |
string | Set to 1 to skip the cache and force a fresh render. The response is the newly rendered HTML (cache status miss) and the stored snapshot is replaced, so later requests serve the updated version. Pass it as a top-level parameter alongside url, not inside the encoded url value. |
Response Headers#
| Header | Values | Description |
|---|---|---|
x-lovablehtml-render-cache |
edge-hit, hit, or miss |
Which cache tier served the response (see below) |
x-lovablehtml-snapshot-key |
string | Identifier for the stored HTML snapshot (present on hit) |
cache-control |
public, max-age=N, s-maxage=N |
Cache TTL based on your domain's configured refresh interval |
etag |
W/"sha256" |
Weak etag derived from the HTML content hash |
Cache tiers
edge-hit— served from a short-lived edge tier close to the requester. Lowest latency. May serve stale content for up to 5 minutes after an invalidation.hit— served from the durable snapshot cache. Reflects the latest successful render for your domain's refresh interval.miss— no cache entry was usable; the page was rendered on demand.
A forced render is slower than a cached response and counts toward your render usage, so use it to refresh a specific page on demand rather than on every request. It renders even when on-demand rendering is turned off for the domain.
To refresh pages without fetching them, in bulk or after a deploy, use the Cache Invalidation API instead.
Response Body#
On 200, returns the fully-rendered HTML string with Content-Type: text/html; charset=utf-8.
On 304, the body is empty. Follow the Location header to the origin URL.
Response Codes#
- 200 Success — Returns rendered HTML with
Content-Type: text/html - 301 Redirect — A configured redirect rule matched. Forward the
Locationheader to the client. - 304 Passthrough — Static asset, non-HTML request, or real browser navigation.
Locationheader contains origin URL. - 401 Unauthorized — Missing or invalid API key.
- 402 Subscription required — Rendering via API requires an active plan.
- 403 Forbidden —
domain_not_ownedorapi_key_domain_scope_mismatch.
Example#
const response = await fetch(
'https://encited.com/api/prerender/render?url=' +
encodeURIComponent('https://your-app.com/page'),
{
redirect: 'manual',
headers: {
'x-lovablehtml-api-key': '<API_KEY>',
'Accept': 'text/html'
}
}
);
const html = await response.text();
// Check response headers
const cacheStatus = response.headers.get('x-lovablehtml-render-cache');
// → "edge-hit" or "hit" (cached) or "miss" (fresh render)
const snapshotKey = response.headers.get('x-lovablehtml-snapshot-key');
// Useful for debugging: the stored HTML object key (when available)
curl -X GET \
"https://encited.com/api/prerender/render?url=https%3A%2F%2Fyour-app.com%2Fpage" \
-H "x-lovablehtml-api-key: <API_KEY>" \
-H "Accept: text/html"
# Force a fresh render and replace the stored snapshot
curl -X GET \
"https://encited.com/api/prerender/render?url=https%3A%2F%2Fyour-app.com%2Fpage&cache_invalidate=1" \
-H "x-lovablehtml-api-key: <API_KEY>" \
-H "Accept: text/html"
import requests
import urllib.parse
url = urllib.parse.quote('https://your-app.com/page', safe='')
response = requests.get(
f'https://encited.com/api/prerender/render?url={url}',
headers={
'x-lovablehtml-api-key': '<API_KEY>',
'Accept': 'text/html'
},
allow_redirects=False,
)
html = response.text
cache_status = response.headers.get('x-lovablehtml-render-cache')
Static assets (CSS, JS, images, fonts) are never prerendered. Follow the Location header or fetch directly from origin.
