Skip to content

Render images with the API

Use this guide when another server-side system needs a PNG from a template. The image endpoint is credential-free when FRAMEKIT_AUTH_ENABLED is missing or false; set FRAMEKIT_AUTH_ENABLED=true and use a token when the deployment needs authenticated API access. For endpoint details, see the image render API reference. For public deployment, read Security and reverse proxies first.

1. Create a server-side token when auth is enabled

Section titled “1. Create a server-side token when auth is enabled”

Skip this step in open mode. When FRAMEKIT_AUTH_ENABLED=true, sign in to Studio, open Settings, and create an API token with a descriptive name. The full fk_ secret is shown only once. Store it in the calling service’s secret manager or environment, not in a browser bundle, URL, template, or log.

The token works while it is not revoked and its owner is active. Changing a password does not revoke tokens; revoking a token does.

The application must be running on the Node.js runtime with Chromium installed. A generated project can prepare the browser with:

Terminal window
pnpm framekit browser install

Use --with-deps on Linux when system browser dependencies are not already installed. Build before starting the production process:

Terminal window
pnpm framekit build
pnpm framekit start

The generated App Router API route must use createFrameKitApiHandler(templates) and export the supported HTTP methods from a Node.js route. See Integrate an existing Next.js project if the route is not present.

Replace example with a slug from the generated template registry. For an authenticated deployment, send the token in an Authorization header:

Terminal window
export FRAMEKIT_ORIGIN=https://framekit.example.com
export FRAMEKIT_TOKEN='fk_replace_with_the_full_secret'
curl --fail-with-body \
--request POST "$FRAMEKIT_ORIGIN/api/framekit/images/render" \
--header "Authorization: Bearer $FRAMEKIT_TOKEN" \
--header 'Content-Type: application/json' \
--data '{"template":"example"}' \
--output example.png

For open mode, omit the Authorization header and do not create a token. The server still validates the request, image inputs, browser navigation, render capacity, timeout, and cleanup defenses.

To override content, include a variant and a data object containing only declared field keys:

{
"template": "example",
"variant": "default",
"data": {
"title": "Launch"
}
}

The template’s default variant is used when variant is omitted. The endpoint validates the resolved data before opening the browser render.

The success response is 200 with Content-Type: image/png and Cache-Control: no-store. Save the response bytes as a PNG; the current endpoint does not return another format or an asynchronous job identifier.

For an error, read the JSON body and branch on error:

{
"error": "invalid_template_data",
"message": "Template data is invalid",
"fields": {
"title": {
"code": "required"
}
}
}

Treat render_capacity_exhausted as a bounded retry condition, correct invalid_template_data or unsupported_image at the caller, and fix api_not_configured in the deployment environment. The error reference lists every stable code and status.

If a declared image field receives an HTTPS URL, add only its exact hostname to FRAMEKIT_ALLOWED_IMAGE_HOSTS. FrameKit fetches the raster image from Node, validates its MIME type and signature, and prepares it before Chromium renders. HTTP, IP literals, credentials, explicit non-default ports, SVG, unsafe redirects, and hosts outside the allowlist are rejected. https://host:443 is normalized and accepted as HTTPS without a port.

Prefer root-relative project assets when the image is already part of the generated application. Neither public assets nor client bundles should contain the API token.