[Go to site: main page, start]

Skip to content

Create Image — Template-to-Image Generation API

Generate an image from an image template with one synchronous call. Send JSON, get back a PNG, JPEG or WebP — either as a signed URL or the raw bytes.

POST https://api.templatefox.com/v1/image/create

Authentication: API key in x-api-key header. Credits: 1 credit per successful generation (refunded automatically if rendering fails).

Image generation works on image templates — a single fixed canvas (e.g. 1080×1080) designed in the editor. PDF templates return a 400; use create-pdf for documents.

You address elements by the layer name you gave them in the editor’s Layers panel, and change them through modifications:

FieldTypeDescription
template_idstringThe 12-character ID of your image template (copy from the images dashboard).
modificationsarrayElements to change, each addressed by its layer name. See Modifications.
curl -X POST https://api.templatefox.com/v1/image/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "template_id": "HMQywVpZxqAM",
  "modifications": [
    { "name": "title", "text": "Summer Sale -50%" },
    { "name": "product_image", "image_url": "https://example.com/photo.jpg" }
  ]
}'

Or use one of our official SDKs — TypeScript, Python, Go, PHP, Ruby, Java, C#.

FieldTypeRequiredDefaultDescription
template_idstring12-character template short ID.
modificationsarrayElements to change, addressed by layer name. See Modifications. Up to 100 items.
formatstring"png"Output format: "png" (lossless, supports transparency), "jpeg" (smaller, no transparency), or "webp" (modern compression).
widthintegertemplate widthOutput width in pixels; height follows the template’s aspect ratio. Min 100, max 4000. Defaults to the template’s native canvas width.
qualityinteger85Compression quality for jpeg and webp (1100). Ignored for png.
export_typestring"url""url" uploads the image to our CDN and returns a signed URL. "binary" returns the raw image bytes.
expirationinteger86400URL expiration in seconds. Min: 60, max: 604800 (7 days). Only applies when export_type="url".
filenamestring"document"Custom filename (without extension). Alphanumeric, _, -, . only. Max 100 chars.
store_s3booleanfalseUpload to your configured S3 bucket instead of our CDN. Requires an S3 integration.
s3_filepathstringPath prefix inside your S3 bucket. Overrides default_prefix. Max 500 chars.
s3_bucketstringOverride the bucket name from your S3 integration (3–63 chars, lowercase).
versionstringTemplate version tag (e.g. "prod") or numeric version (e.g. "3"). Omit to use the current draft. Max 50 chars.

The template defines the canvas aspect ratio (for example an Instagram square at 1080×1080 or an Open Graph card at 1200×630). width sets the output resolution in pixels; the height is derived from the template so the image is never distorted. Omit width to render at the template’s native pixel size, or pass a larger value (e.g. 2160) for a higher-resolution export.

Each item in modifications targets an element by the name you set in the editor’s Layers panel, then changes one or more of its properties:

PropertyTypeDescription
namestringLayer name to modify (required).
textstringReplace the layer’s text. Rendered as literal text — HTML and {{ }} are not interpreted.
image_urlstringSet the layer’s image. For an image layer this sets its source; for any other layer it sets a background-image. Must be an http(s) URL.
colorstringText color (any CSS color).
backgroundstringBackground color (any CSS color).
hiddenbooleanHide (true) or show (false) the layer.

A few behaviors worth knowing:

  • Naming: only layers you have named in the editor are addressable. Rename a layer in the Layers panel to give it a stable name.
  • Unknown names are skipped. If a name matches no layer, the render still succeeds and the skipped name is listed in the response warnings.
  • Duplicate names apply to all. If several layers share a name, the modification is applied to every one of them.

Returns JSON with a signed URL to the generated image.

{
"url": "https://cdn.templatefox.com/generated/abc123/social-card.png",
"filename": "social-card.png",
"credits_remaining": 99,
"expires_in": 86400
}
FieldTypeDescription
urlstringSigned URL to download the image (expires after expires_in seconds).
filenamestringFinal filename of the generated image.
credits_remainingnumberCredits left in your team’s balance after this call.
expires_innumberSeconds until the signed URL expires.
warningsarrayPresent only when a modification’s layer name matched no element. Lists the skipped names.

Returns the raw image with content type image/png, image/jpeg or image/webp (matching format). Useful when you want to stream the file directly to a user or store it yourself. expiration, filename, and S3 options are ignored.

Response headers:

Content-Type: image/png
Content-Disposition: attachment; filename="HMQywVpZxqAM.png"
X-Credits-Remaining: 99

When S3 upload is requested, the response describes where the file landed in your bucket instead of returning a URL:

{
"s3_bucket": "my-image-bucket",
"s3_key": "social/2026/01/social-card.png",
"filename": "social-card.png",
"credits_remaining": 99
}

Choose a format and width to match where the image will be used:

curl -X POST https://api.templatefox.com/v1/image/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "template_id": "HMQywVpZxqAM",
  "modifications": [{ "name": "title", "text": "Welcome aboard" }],
  "format": "webp",
  "width": 1200,
  "quality": 90
}'

Set export_type to "binary" to receive the raw image bytes directly — useful for streaming to the user or saving to disk without a CDN round-trip.

curl -X POST https://api.templatefox.com/v1/image/create \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
--output social-card.png \
-d '{
  "template_id": "HMQywVpZxqAM",
  "modifications": [{ "name": "title", "text": "Welcome aboard" }],
  "export_type": "binary"
}'
StatusErrorWhen
400BAD_REQUESTThe template is not an image template (use create-pdf), or has more than one page.
401UNAUTHORIZEDMissing or invalid API key.
402INSUFFICIENT_CREDITSYour team’s credit balance is 0.
403FORBIDDENThe template does not belong to your team.
404TEMPLATE_NOT_FOUNDtemplate_id does not exist.
429RATE_LIMIT_EXCEEDEDRate limit hit (see response headers).
500INTERNAL_ERRORRendering failed. Credit is automatically refunded.

See the full list in the API Reference overview.