Encited

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 Location header to the client.
  • 304 Passthrough — Static asset, non-HTML request, or real browser navigation. Location header contains origin URL.
  • 401 Unauthorized — Missing or invalid API key.
  • 402 Subscription required — Rendering via API requires an active plan.
  • 403 Forbiddendomain_not_owned or api_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.